diff options
Diffstat (limited to 'mesalib/src/mesa/state_tracker')
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c | 51 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_texture.c | 30 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_gen_mipmap.c | 1 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 365 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h | 1 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_texture.c | 4 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_texture.h | 5 |
7 files changed, 246 insertions, 211 deletions
diff --git a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c index 331defb52..59c59e113 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -93,7 +93,6 @@ st_bufferobj_free(struct gl_context *ctx, struct gl_buffer_object *obj) */
static void
st_bufferobj_subdata(struct gl_context *ctx,
- GLenum target,
GLintptrARB offset,
GLsizeiptrARB size,
const GLvoid * data, struct gl_buffer_object *obj)
@@ -133,7 +132,6 @@ st_bufferobj_subdata(struct gl_context *ctx, */
static void
st_bufferobj_get_subdata(struct gl_context *ctx,
- GLenum target,
GLintptrARB offset,
GLsizeiptrARB size,
GLvoid * data, struct gl_buffer_object *obj)
@@ -238,52 +236,10 @@ static long st_bufferobj_zero_length = 0; /**
- * Called via glMapBufferARB().
- */
-static void *
-st_bufferobj_map(struct gl_context *ctx, GLenum target, GLenum access,
- struct gl_buffer_object *obj)
-{
- struct st_buffer_object *st_obj = st_buffer_object(obj);
- uint flags;
-
- switch (access) {
- case GL_WRITE_ONLY:
- flags = PIPE_TRANSFER_WRITE;
- break;
- case GL_READ_ONLY:
- flags = PIPE_TRANSFER_READ;
- break;
- case GL_READ_WRITE:
- default:
- flags = PIPE_TRANSFER_READ_WRITE;
- break;
- }
-
- /* Handle zero-size buffers here rather than in drivers */
- if (obj->Size == 0) {
- obj->Pointer = &st_bufferobj_zero_length;
- }
- else {
- obj->Pointer = pipe_buffer_map(st_context(ctx)->pipe,
- st_obj->buffer,
- flags,
- &st_obj->transfer);
- }
-
- if (obj->Pointer) {
- obj->Offset = 0;
- obj->Length = obj->Size;
- }
- return obj->Pointer;
-}
-
-
-/**
* Called via glMapBufferRange().
*/
static void *
-st_bufferobj_map_range(struct gl_context *ctx, GLenum target,
+st_bufferobj_map_range(struct gl_context *ctx,
GLintptr offset, GLsizeiptr length, GLbitfield access,
struct gl_buffer_object *obj)
{
@@ -353,7 +309,7 @@ st_bufferobj_map_range(struct gl_context *ctx, GLenum target, static void
-st_bufferobj_flush_mapped_range(struct gl_context *ctx, GLenum target,
+st_bufferobj_flush_mapped_range(struct gl_context *ctx,
GLintptr offset, GLsizeiptr length,
struct gl_buffer_object *obj)
{
@@ -378,7 +334,7 @@ st_bufferobj_flush_mapped_range(struct gl_context *ctx, GLenum target, * Called via glUnmapBufferARB().
*/
static GLboolean
-st_bufferobj_unmap(struct gl_context *ctx, GLenum target, struct gl_buffer_object *obj)
+st_bufferobj_unmap(struct gl_context *ctx, struct gl_buffer_object *obj)
{
struct pipe_context *pipe = st_context(ctx)->pipe;
struct st_buffer_object *st_obj = st_buffer_object(obj);
@@ -444,7 +400,6 @@ st_init_bufferobject_functions(struct dd_function_table *functions) functions->BufferData = st_bufferobj_data;
functions->BufferSubData = st_bufferobj_subdata;
functions->GetBufferSubData = st_bufferobj_get_subdata;
- functions->MapBuffer = st_bufferobj_map;
functions->MapBufferRange = st_bufferobj_map_range;
functions->FlushMappedBufferRange = st_bufferobj_flush_mapped_range;
functions->UnmapBuffer = st_bufferobj_unmap;
diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index 7f6ffee5e..82a1079a2 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -344,7 +344,7 @@ guess_and_alloc_texture(struct st_context *st, stImage->base.Width2,
stImage->base.Height2,
stImage->base.Depth2,
- stImage->level,
+ stImage->base.Level,
&width, &height, &depth)) {
/* we can't determine the image size at level=0 */
stObj->width0 = stObj->height0 = stObj->depth0 = 0;
@@ -367,7 +367,7 @@ guess_and_alloc_texture(struct st_context *st, stImage->base._BaseFormat == GL_DEPTH_COMPONENT ||
stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) &&
!stObj->base.GenerateMipmap &&
- stImage->level == 0) {
+ stImage->base.Level == 0) {
/* only alloc space for a single mipmap level */
lastLevel = 0;
}
@@ -506,8 +506,8 @@ st_TexImage(struct gl_context * ctx, assert(texImage->Depth == depth);
}
- stImage->face = _mesa_tex_target_to_face(target);
- stImage->level = level;
+ stImage->base.Face = _mesa_tex_target_to_face(target);
+ stImage->base.Level = level;
_mesa_set_fetch_functions(texImage, dims);
@@ -529,7 +529,7 @@ st_TexImage(struct gl_context * ctx, if (stObj->pt) {
if (level > (GLint) stObj->pt->last_level ||
!st_texture_match_image(stObj->pt, &stImage->base,
- stImage->face, stImage->level)) {
+ stImage->base.Face, stImage->base.Level)) {
DBG("release it\n");
pipe_resource_reference(&stObj->pt, NULL);
assert(!stObj->pt);
@@ -563,7 +563,7 @@ st_TexImage(struct gl_context * ctx, */
if (stObj->pt &&
st_texture_match_image(stObj->pt, &stImage->base,
- stImage->face, stImage->level)) {
+ stImage->base.Face, stImage->base.Level)) {
pipe_resource_reference(&stImage->pt, stObj->pt);
assert(stImage->pt);
@@ -1501,8 +1501,8 @@ st_copy_texsubimage(struct gl_context *ctx, pipe->resource_copy_region(pipe,
/* dest */
stImage->pt,
- stImage->level,
- destX, destY, destZ + stImage->face,
+ stImage->base.Level,
+ destX, destY, destZ + stImage->base.Face,
/* src */
strb->texture,
strb->surface->u.tex.level,
@@ -1524,9 +1524,9 @@ st_copy_texsubimage(struct gl_context *ctx, memset(&surf_tmpl, 0, sizeof(surf_tmpl));
surf_tmpl.format = util_format_linear(stImage->pt->format);
surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
- surf_tmpl.u.tex.level = stImage->level;
- surf_tmpl.u.tex.first_layer = stImage->face + destZ;
- surf_tmpl.u.tex.last_layer = stImage->face + destZ;
+ surf_tmpl.u.tex.level = stImage->base.Level;
+ surf_tmpl.u.tex.first_layer = stImage->base.Face + destZ;
+ surf_tmpl.u.tex.last_layer = stImage->base.Face + destZ;
dest_surface = pipe->create_surface(pipe, stImage->pt,
&surf_tmpl);
@@ -1629,7 +1629,7 @@ copy_image_data_to_texture(struct st_context *st, /* debug checks */
{
const struct gl_texture_image *dstImage =
- stObj->base.Image[stImage->face][dstLevel];
+ stObj->base.Image[stImage->base.Face][dstLevel];
assert(dstImage);
assert(dstImage->Width == stImage->base.Width);
assert(dstImage->Height == stImage->base.Height);
@@ -1641,15 +1641,15 @@ copy_image_data_to_texture(struct st_context *st, */
st_texture_image_copy(st->pipe,
stObj->pt, dstLevel, /* dest texture, level */
- stImage->pt, stImage->level, /* src texture, level */
- stImage->face);
+ stImage->pt, stImage->base.Level, /* src texture, level */
+ stImage->base.Face);
pipe_resource_reference(&stImage->pt, NULL);
}
else if (stImage->base.Data) {
st_texture_image_data(st,
stObj->pt,
- stImage->face,
+ stImage->base.Face,
dstLevel,
stImage->base.Data,
stImage->base.RowStride *
diff --git a/mesalib/src/mesa/state_tracker/st_gen_mipmap.c b/mesalib/src/mesa/state_tracker/st_gen_mipmap.c index b0911294a..82ca4af7f 100644 --- a/mesalib/src/mesa/state_tracker/st_gen_mipmap.c +++ b/mesalib/src/mesa/state_tracker/st_gen_mipmap.c @@ -453,7 +453,6 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target, srcImage->TexFormat); stImage = st_texture_image(dstImage); - stImage->level = dstLevel; pipe_resource_reference(&stImage->pt, pt); } diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index aef23e7d2..22660830a 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -295,6 +295,7 @@ public: bool indirect_addr_consts; int glsl_version; + bool native_integers; variable_storage *find_variable_storage(ir_variable *var); @@ -372,11 +373,11 @@ public: /** * Emit the correct dot-product instruction for the type of arguments */ - void emit_dp(ir_instruction *ir, - st_dst_reg dst, - st_src_reg src0, - st_src_reg src1, - unsigned elements); + glsl_to_tgsi_instruction *emit_dp(ir_instruction *ir, + st_dst_reg dst, + st_src_reg src0, + st_src_reg src1, + unsigned elements); void emit_scalar(ir_instruction *ir, unsigned op, st_dst_reg dst, st_src_reg src0); @@ -389,9 +390,11 @@ public: void emit_scs(ir_instruction *ir, unsigned op, st_dst_reg dst, const st_src_reg &src); - GLboolean try_emit_mad(ir_expression *ir, - int mul_operand); - GLboolean try_emit_sat(ir_expression *ir); + bool try_emit_mad(ir_expression *ir, + int mul_operand); + bool try_emit_mad_for_and_not(ir_expression *ir, + int mul_operand); + bool try_emit_sat(ir_expression *ir); void emit_swz(ir_expression *ir); @@ -600,7 +603,7 @@ glsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op, if (src0.type == GLSL_TYPE_FLOAT || src1.type == GLSL_TYPE_FLOAT) type = GLSL_TYPE_FLOAT; - else if (glsl_version >= 130) + else if (native_integers) type = src0.type; #define case4(c, f, i, u) \ @@ -641,7 +644,7 @@ glsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op, return op; } -void +glsl_to_tgsi_instruction * glsl_to_tgsi_visitor::emit_dp(ir_instruction *ir, st_dst_reg dst, st_src_reg src0, st_src_reg src1, unsigned elements) @@ -650,7 +653,7 @@ glsl_to_tgsi_visitor::emit_dp(ir_instruction *ir, TGSI_OPCODE_DP2, TGSI_OPCODE_DP3, TGSI_OPCODE_DP4 }; - emit(ir, dot_opcodes[elements - 2], dst, src0, src1); + return emit(ir, dot_opcodes[elements - 2], dst, src0, src1); } /** @@ -863,7 +866,7 @@ glsl_to_tgsi_visitor::add_constant(gl_register_file file, } } -struct st_src_reg +st_src_reg glsl_to_tgsi_visitor::st_src_reg_for_float(float val) { st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_FLOAT); @@ -875,13 +878,13 @@ glsl_to_tgsi_visitor::st_src_reg_for_float(float val) return src; } -struct st_src_reg +st_src_reg glsl_to_tgsi_visitor::st_src_reg_for_int(int val) { st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_INT); union gl_constant_value uval; - assert(glsl_version >= 130); + assert(native_integers); uval.i = val; src.index = add_constant(src.file, &uval, 1, GL_INT, &src.swizzle); @@ -889,10 +892,10 @@ glsl_to_tgsi_visitor::st_src_reg_for_int(int val) return src; } -struct st_src_reg +st_src_reg glsl_to_tgsi_visitor::st_src_reg_for_type(int type, int val) { - if (glsl_version >= 130) + if (native_integers) return type == GLSL_TYPE_FLOAT ? st_src_reg_for_float(val) : st_src_reg_for_int(val); else @@ -950,7 +953,7 @@ glsl_to_tgsi_visitor::get_temp(const glsl_type *type) { st_src_reg src; - src.type = glsl_version >= 130 ? type->base_type : GLSL_TYPE_FLOAT; + src.type = native_integers ? type->base_type : GLSL_TYPE_FLOAT; src.file = PROGRAM_TEMPORARY; src.index = next_temp; src.reladdr = NULL; @@ -1032,7 +1035,7 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir) } } - struct variable_storage *storage; + variable_storage *storage; st_dst_reg dst; if (i == ir->num_state_slots) { /* We'll set the index later. */ @@ -1053,7 +1056,7 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir) this->next_temp += type_size(ir->type); dst = st_dst_reg(st_src_reg(PROGRAM_TEMPORARY, storage->index, - glsl_version >= 130 ? ir->type->base_type : GLSL_TYPE_FLOAT)); + native_integers ? ir->type->base_type : GLSL_TYPE_FLOAT)); } @@ -1069,7 +1072,7 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir) } } else { st_src_reg src(PROGRAM_STATE_VAR, index, - glsl_version >= 130 ? ir->type->base_type : GLSL_TYPE_FLOAT); + native_integers ? ir->type->base_type : GLSL_TYPE_FLOAT); src.swizzle = slots[i].swizzle; emit(ir, TGSI_OPCODE_MOV, dst, src); /* even a float takes up a whole vec4 reg in a struct/array. */ @@ -1183,7 +1186,7 @@ glsl_to_tgsi_visitor::visit(ir_function *ir) } } -GLboolean +bool glsl_to_tgsi_visitor::try_emit_mad(ir_expression *ir, int mul_operand) { int nonmul_operand = 1 - mul_operand; @@ -1209,7 +1212,47 @@ glsl_to_tgsi_visitor::try_emit_mad(ir_expression *ir, int mul_operand) return true; } -GLboolean +/** + * Emit MAD(a, -b, a) instead of AND(a, NOT(b)) + * + * The logic values are 1.0 for true and 0.0 for false. Logical-and is + * implemented using multiplication, and logical-or is implemented using + * addition. Logical-not can be implemented as (true - x), or (1.0 - x). + * As result, the logical expression (a & !b) can be rewritten as: + * + * - a * !b + * - a * (1 - b) + * - (a * 1) - (a * b) + * - a + -(a * b) + * - a + (a * -b) + * + * This final expression can be implemented as a single MAD(a, -b, a) + * instruction. + */ +bool +glsl_to_tgsi_visitor::try_emit_mad_for_and_not(ir_expression *ir, int try_operand) +{ + const int other_operand = 1 - try_operand; + st_src_reg a, b; + + ir_expression *expr = ir->operands[try_operand]->as_expression(); + if (!expr || expr->operation != ir_unop_logic_not) + return false; + + ir->operands[other_operand]->accept(this); + a = this->result; + expr->operands[0]->accept(this); + b = this->result; + + b.negate = ~b.negate; + + this->result = get_temp(ir->type); + emit(ir, TGSI_OPCODE_MAD, st_dst_reg(this->result), a, b, a); + + return true; +} + +bool glsl_to_tgsi_visitor::try_emit_sat(ir_expression *ir) { /* Saturates were only introduced to vertex programs in @@ -1290,6 +1333,16 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) if (try_emit_mad(ir, 0)) return; } + + /* Quick peephole: Emit OPCODE_MAD(-a, -b, a) instead of AND(a, NOT(b)) + */ + if (ir->operation == ir_binop_logic_and) { + if (try_emit_mad_for_and_not(ir, 1)) + return; + if (try_emit_mad_for_and_not(ir, 0)) + return; + } + if (try_emit_sat(ir)) return; @@ -1335,7 +1388,17 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) switch (ir->operation) { case ir_unop_logic_not: - emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], st_src_reg_for_type(result_dst.type, 0)); + if (result_dst.type != GLSL_TYPE_FLOAT) + emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], st_src_reg_for_type(result_dst.type, 0)); + else { + /* Previously 'SEQ dst, src, 0.0' was used for this. However, many + * older GPUs implement SEQ using multiple instructions (i915 uses two + * SGE instructions and a MUL instruction). Since our logic values are + * 0.0 and 1.0, 1-x also implements !x. + */ + op[0].negate = ~op[0].negate; + emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], st_src_reg_for_float(1.0)); + } break; case ir_unop_neg: assert(result_dst.type == GLSL_TYPE_FLOAT || result_dst.type == GLSL_TYPE_INT); @@ -1444,13 +1507,31 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) /* "==" operator producing a scalar boolean. */ if (ir->operands[0]->type->is_vector() || ir->operands[1]->type->is_vector()) { - st_src_reg temp = get_temp(glsl_version >= 130 ? + st_src_reg temp = get_temp(native_integers ? glsl_type::get_instance(ir->operands[0]->type->base_type, 4, 1) : glsl_type::vec4_type); assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]); + + /* After the dot-product, the value will be an integer on the + * range [0,4]. Zero becomes 1.0, and positive values become zero. + */ emit_dp(ir, result_dst, temp, temp, vector_elements); - emit(ir, TGSI_OPCODE_SEQ, result_dst, result_src, st_src_reg_for_float(0.0)); + + if (result_dst.type == GLSL_TYPE_FLOAT) { + /* Negating the result of the dot-product gives values on the range + * [-4, 0]. Zero becomes 1.0, and negative values become zero. + * This is achieved using SGE. + */ + st_src_reg sge_src = result_src; + sge_src.negate = ~sge_src.negate; + emit(ir, TGSI_OPCODE_SGE, result_dst, sge_src, st_src_reg_for_float(0.0)); + } else { + /* The TGSI negate flag doesn't work for integers, so use SEQ 0 + * instead. + */ + emit(ir, TGSI_OPCODE_SEQ, result_dst, result_src, st_src_reg_for_int(0)); + } } else { emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]); } @@ -1459,34 +1540,102 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) /* "!=" operator producing a scalar boolean. */ if (ir->operands[0]->type->is_vector() || ir->operands[1]->type->is_vector()) { - st_src_reg temp = get_temp(glsl_version >= 130 ? + st_src_reg temp = get_temp(native_integers ? glsl_type::get_instance(ir->operands[0]->type->base_type, 4, 1) : glsl_type::vec4_type); assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]); - emit_dp(ir, result_dst, temp, temp, vector_elements); - emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_float(0.0)); + + /* After the dot-product, the value will be an integer on the + * range [0,4]. Zero stays zero, and positive values become 1.0. + */ + glsl_to_tgsi_instruction *const dp = + emit_dp(ir, result_dst, temp, temp, vector_elements); + if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB && + result_dst.type == GLSL_TYPE_FLOAT) { + /* The clamping to [0,1] can be done for free in the fragment + * shader with a saturate. + */ + dp->saturate = true; + } else if (result_dst.type == GLSL_TYPE_FLOAT) { + /* Negating the result of the dot-product gives values on the range + * [-4, 0]. Zero stays zero, and negative values become 1.0. This + * achieved using SLT. + */ + st_src_reg slt_src = result_src; + slt_src.negate = ~slt_src.negate; + emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0)); + } else { + emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_int(0)); + } } else { emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]); } break; - case ir_unop_any: + case ir_unop_any: { assert(ir->operands[0]->type->is_vector()); - emit_dp(ir, result_dst, op[0], op[0], - ir->operands[0]->type->vector_elements); - emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_float(0.0)); + + /* After the dot-product, the value will be an integer on the + * range [0,4]. Zero stays zero, and positive values become 1.0. + */ + glsl_to_tgsi_instruction *const dp = + emit_dp(ir, result_dst, op[0], op[0], + ir->operands[0]->type->vector_elements); + if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB && + result_dst.type == GLSL_TYPE_FLOAT) { + /* The clamping to [0,1] can be done for free in the fragment + * shader with a saturate. + */ + dp->saturate = true; + } else if (result_dst.type == GLSL_TYPE_FLOAT) { + /* Negating the result of the dot-product gives values on the range + * [-4, 0]. Zero stays zero, and negative values become 1.0. This + * is achieved using SLT. + */ + st_src_reg slt_src = result_src; + slt_src.negate = ~slt_src.negate; + emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0)); + } + else { + /* Use SNE 0 if integers are being used as boolean values. */ + emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_int(0)); + } break; + } case ir_binop_logic_xor: emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]); break; - case ir_binop_logic_or: - /* This could be a saturated add and skip the SNE. */ - emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]); - emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_float(0.0)); + case ir_binop_logic_or: { + /* After the addition, the value will be an integer on the + * range [0,2]. Zero stays zero, and positive values become 1.0. + */ + glsl_to_tgsi_instruction *add = + emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]); + if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB && + result_dst.type == GLSL_TYPE_FLOAT) { + /* The clamping to [0,1] can be done for free in the fragment + * shader with a saturate if floats are being used as boolean values. + */ + add->saturate = true; + } else if (result_dst.type == GLSL_TYPE_FLOAT) { + /* Negating the result of the addition gives values on the range + * [-2, 0]. Zero stays zero, and negative values become 1.0. This + * is achieved using SLT. + */ + st_src_reg slt_src = result_src; + slt_src.negate = ~slt_src.negate; + emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0)); + } else { + /* Use an SNE on the result of the addition. Zero stays zero, + * 1 stays 1, and 2 becomes 1. + */ + emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_int(0)); + } break; + } case ir_binop_logic_and: /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */ @@ -1514,7 +1663,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) break; case ir_unop_i2f: case ir_unop_b2f: - if (glsl_version >= 130) { + if (native_integers) { emit(ir, TGSI_OPCODE_I2F, result_dst, op[0]); break; } @@ -1526,7 +1675,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) result_src = op[0]; break; case ir_unop_f2i: - if (glsl_version >= 130) + if (native_integers) emit(ir, TGSI_OPCODE_F2I, result_dst, op[0]); else emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]); @@ -1567,7 +1716,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) break; } case ir_unop_u2f: - if (glsl_version >= 130) { + if (native_integers) { emit(ir, TGSI_OPCODE_U2F, result_dst, op[0]); break; } @@ -1719,7 +1868,7 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir) } this->result = st_src_reg(entry->file, entry->index, var->type); - if (glsl_version <= 120) + if (!native_integers) this->result.type = GLSL_TYPE_FLOAT; } @@ -2109,27 +2258,27 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir) } break; case GLSL_TYPE_UINT: - gl_type = glsl_version >= 130 ? GL_UNSIGNED_INT : GL_FLOAT; + gl_type = native_integers ? GL_UNSIGNED_INT : GL_FLOAT; for (i = 0; i < ir->type->vector_elements; i++) { - if (glsl_version >= 130) + if (native_integers) values[i].u = ir->value.u[i]; else values[i].f = ir->value.u[i]; } break; case GLSL_TYPE_INT: - gl_type = glsl_version >= 130 ? GL_INT : GL_FLOAT; + gl_type = native_integers ? GL_INT : GL_FLOAT; for (i = 0; i < ir->type->vector_elements; i++) { - if (glsl_version >= 130) + if (native_integers) values[i].i = ir->value.i[i]; else values[i].f = ir->value.i[i]; } break; case GLSL_TYPE_BOOL: - gl_type = glsl_version >= 130 ? GL_BOOL : GL_FLOAT; + gl_type = native_integers ? GL_BOOL : GL_FLOAT; for (i = 0; i < ir->type->vector_elements; i++) { - if (glsl_version >= 130) + if (native_integers) values[i].b = ir->value.b[i]; else values[i].f = ir->value.b[i]; @@ -2277,16 +2426,18 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) glsl_to_tgsi_instruction *inst = NULL; unsigned opcode = TGSI_OPCODE_NOP; - ir->coordinate->accept(this); + if (ir->coordinate) { + ir->coordinate->accept(this); - /* Put our coords in a temp. We'll need to modify them for shadow, - * projection, or LOD, so the only case we'd use it as is is if - * we're doing plain old texturing. The optimization passes on - * glsl_to_tgsi_visitor should handle cleaning up our mess in that case. - */ - coord = get_temp(glsl_type::vec4_type); - coord_dst = st_dst_reg(coord); - emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result); + /* Put our coords in a temp. We'll need to modify them for shadow, + * projection, or LOD, so the only case we'd use it as is is if + * we're doing plain old texturing. The optimization passes on + * glsl_to_tgsi_visitor should handle cleaning up our mess in that case. + */ + coord = get_temp(glsl_type::vec4_type); + coord_dst = st_dst_reg(coord); + emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result); + } if (ir->projector) { ir->projector->accept(this); @@ -2320,8 +2471,15 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) ir->lod_info.grad.dPdy->accept(this); dy = this->result; break; - case ir_txf: /* TODO: use TGSI_OPCODE_TXF here */ - assert(!"GLSL 1.30 features unsupported"); + case ir_txs: + opcode = TGSI_OPCODE_TXQ; + ir->lod_info.lod->accept(this); + lod_info = this->result; + break; + case ir_txf: + opcode = TGSI_OPCODE_TXF; + ir->lod_info.lod->accept(this); + lod_info = this->result; break; } @@ -2385,7 +2543,8 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) coord_dst.writemask = WRITEMASK_XYZW; } - if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXB) { + if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXB || + opcode == TGSI_OPCODE_TXF) { /* TGSI stores LOD or LOD bias in the last channel of the coords. */ coord_dst.writemask = WRITEMASK_W; emit(ir, TGSI_OPCODE_MOV, coord_dst, lod_info); @@ -2394,6 +2553,8 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) if (opcode == TGSI_OPCODE_TXD) inst = emit(ir, opcode, result_dst, coord, dx, dy); + else if (opcode == TGSI_OPCODE_TXQ) + inst = emit(ir, opcode, result_dst, lod_info); else inst = emit(ir, opcode, result_dst, coord); @@ -2802,36 +2963,6 @@ set_uniform_initializer(struct gl_context *ctx, void *mem_ctx, } } -static void -set_uniform_initializers(struct gl_context *ctx, - struct gl_shader_program *shader_program) -{ - void *mem_ctx = NULL; - - for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { - struct gl_shader *shader = shader_program->_LinkedShaders[i]; - - if (shader == NULL) - continue; - - foreach_iter(exec_list_iterator, iter, *shader->ir) { - ir_instruction *ir = (ir_instruction *)iter.get(); - ir_variable *var = ir->as_variable(); - - if (!var || var->mode != ir_var_uniform || !var->constant_value) - continue; - - if (!mem_ctx) - mem_ctx = ralloc_context(NULL); - - set_uniform_initializer(ctx, mem_ctx, shader_program, var->name, - var->type, var->constant_value); - } - } - - ralloc_free(mem_ctx); -} - /* * Scan/rewrite program to remove reads of custom (output) registers. * The passed type has to be either PROGRAM_OUTPUT or PROGRAM_VARYING @@ -3443,7 +3574,7 @@ glsl_to_tgsi_visitor::eliminate_dead_code_advanced(void) /* Continuing the block, clear any channels from the write array that * are read by this instruction. */ - for (int i = 0; i < 4; i++) { + for (unsigned i = 0; i < Elements(inst->src); i++) { if (inst->src[i].file == PROGRAM_TEMPORARY && inst->src[i].reladdr){ /* Any temporary might be read, so no dead code elimination * across this instruction. @@ -3611,6 +3742,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp, v->ctx = original->ctx; v->prog = prog; v->glsl_version = original->glsl_version; + v->native_integers = original->native_integers; v->options = original->options; v->next_temp = original->next_temp; v->num_address_regs = original->num_address_regs; @@ -3739,6 +3871,7 @@ get_bitmap_visitor(struct st_fragment_program *fp, v->ctx = original->ctx; v->prog = prog; v->glsl_version = original->glsl_version; + v->native_integers = original->native_integers; v->options = original->options; v->next_temp = original->next_temp; v->num_address_regs = original->num_address_regs; @@ -4085,7 +4218,7 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg) static void compile_tgsi_instruction(struct st_translate *t, - const struct glsl_to_tgsi_instruction *inst) + const glsl_to_tgsi_instruction *inst) { struct ureg_program *ureg = t->ureg; GLuint i; @@ -4124,6 +4257,8 @@ compile_tgsi_instruction(struct st_translate *t, case TGSI_OPCODE_TXD: case TGSI_OPCODE_TXL: case TGSI_OPCODE_TXP: + case TGSI_OPCODE_TXQ: + case TGSI_OPCODE_TXF: src[num_src++] = t->samplers[inst->sampler]; ureg_tex_insn(ureg, inst->op, @@ -4674,6 +4809,7 @@ get_mesa_program(struct gl_context *ctx, v->shader_program = shader_program; v->options = options; v->glsl_version = ctx->Const.GLSLVersion; + v->native_integers = ctx->Const.NativeIntegers; add_uniforms_to_parameters_list(shader_program, shader, prog); @@ -4924,53 +5060,4 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) return GL_TRUE; } - -/** - * Link a GLSL shader program. Called via glLinkProgram(). - */ -void -st_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) -{ - unsigned int i; - - _mesa_clear_shader_program_data(ctx, prog); - - prog->LinkStatus = GL_TRUE; - - for (i = 0; i < prog->NumShaders; i++) { - if (!prog->Shaders[i]->CompileStatus) { - fail_link(prog, "linking with uncompiled shader"); - prog->LinkStatus = GL_FALSE; - } - } - - prog->Varying = _mesa_new_parameter_list(); - _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL); - _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL); - _mesa_reference_geomprog(ctx, &prog->GeometryProgram, NULL); - - if (prog->LinkStatus) { - link_shaders(ctx, prog); - } - - if (prog->LinkStatus) { - if (!ctx->Driver.LinkShader(ctx, prog)) { - prog->LinkStatus = GL_FALSE; - } - } - - set_uniform_initializers(ctx, prog); - - if (ctx->Shader.Flags & GLSL_DUMP) { - if (!prog->LinkStatus) { - printf("GLSL shader program %d failed to link\n", prog->Name); - } - - if (prog->InfoLog && prog->InfoLog[0] != 0) { - printf("GLSL shader program %d info log:\n", prog->Name); - printf("%s\n", prog->InfoLog); - } - } -} - } /* extern "C" */ diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h index d87747178..fafe52e31 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h @@ -64,7 +64,6 @@ struct gl_shader *st_new_shader(struct gl_context *ctx, GLuint name, GLuint type struct gl_shader_program * st_new_shader_program(struct gl_context *ctx, GLuint name); -void st_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog); GLboolean st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog); #ifdef __cplusplus diff --git a/mesalib/src/mesa/state_tracker/st_texture.c b/mesalib/src/mesa/state_tracker/st_texture.c index 0e857fddc..232c286c1 100644 --- a/mesalib/src/mesa/state_tracker/st_texture.c +++ b/mesalib/src/mesa/state_tracker/st_texture.c @@ -221,8 +221,8 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage, DBG("%s \n", __FUNCTION__); - stImage->transfer = pipe_get_transfer(st->pipe, pt, stImage->level, - stImage->face + zoffset, + stImage->transfer = pipe_get_transfer(st->pipe, pt, stImage->base.Level, + stImage->base.Face + zoffset, usage, x, y, w, h); if (stImage->transfer) diff --git a/mesalib/src/mesa/state_tracker/st_texture.h b/mesalib/src/mesa/state_tracker/st_texture.h index a84050f3b..fb1071fc3 100644 --- a/mesalib/src/mesa/state_tracker/st_texture.h +++ b/mesalib/src/mesa/state_tracker/st_texture.h @@ -45,11 +45,6 @@ struct st_texture_image {
struct gl_texture_image base;
- /* These aren't stored in gl_texture_image
- */
- GLuint level;
- GLuint face;
-
/* If stImage->pt != NULL, image data is stored here.
* Else if stImage->base.Data != NULL, image is stored there.
* Else there is no image data.
|