summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.h14
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_fp.cpp28
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp206
3 files changed, 144 insertions, 104 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index dc4e0c8c933..c62c1eb866f 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -488,6 +488,20 @@ public:
fs_reg lod, fs_reg lod2, int grad_components,
fs_reg sample_index, fs_reg mcs, fs_reg sampler,
fs_reg offset_value);
+ void emit_texture(ir_texture_opcode op,
+ const glsl_type *dest_type,
+ fs_reg coordinate, const struct glsl_type *coord_type,
+ fs_reg shadow_c,
+ fs_reg lod, fs_reg dpdy, int grad_components,
+ fs_reg sample_index,
+ fs_reg offset, unsigned offset_components,
+ fs_reg mcs,
+ int gather_component,
+ bool is_cube_array,
+ bool is_rect,
+ uint32_t sampler,
+ fs_reg sampler_reg,
+ int texunit);
fs_reg emit_mcs_fetch(fs_reg coordinate, int components, fs_reg sampler);
void emit_gen6_gather_wa(uint8_t wa, fs_reg dst);
fs_reg fix_math_operand(fs_reg src);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_fp.cpp b/src/mesa/drivers/dri/i965/brw_fs_fp.cpp
index 825d793dc4a..1ba24a9170e 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_fp.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_fp.cpp
@@ -476,28 +476,18 @@ fs_visitor::emit_fragment_program_code()
unreachable("not reached");
}
- int coord_components = coordinate_type->vector_elements;
-
if (fpi->TexShadow)
shadow_c = offset(coordinate, 2);
- coordinate = rescale_texcoord(coordinate, coordinate_type,
- fpi->TexSrcTarget == TEXTURE_RECT_INDEX,
- fpi->TexSrcUnit, fpi->TexSrcUnit);
-
- fs_inst *inst;
- if (brw->gen >= 7) {
- inst = emit_texture_gen7(ir->op, dst, coordinate, coord_components, shadow_c, lod, dpdy, 0, sample_index, fs_reg(0u), fs_reg(fpi->TexSrcUnit), texel_offset);
- } else if (brw->gen >= 5) {
- inst = emit_texture_gen5(ir->op, dst, coordinate, coord_components, shadow_c, lod, dpdy, 0, sample_index, fpi->TexSrcUnit, false);
- } else {
- inst = emit_texture_gen4(ir->op, dst, coordinate, coord_components, shadow_c, lod, dpdy, 0, fpi->TexSrcUnit);
- }
-
- inst->shadow_compare = fpi->TexShadow;
-
- /* Reuse the GLSL swizzle_result() handler. */
- swizzle_result(ir->op, 4, dst, fpi->TexSrcUnit);
+ emit_texture(ir->op, glsl_type::vec4_type, coordinate, coordinate_type,
+ shadow_c, lod, dpdy, 0, sample_index,
+ reg_undef, 0, /* offset, components */
+ reg_undef, /* mcs */
+ 0, /* gather component */
+ false, /* is cube array */
+ fpi->TexSrcTarget == TEXTURE_RECT_INDEX,
+ fpi->TexSrcUnit, fs_reg(fpi->TexSrcUnit),
+ fpi->TexSrcUnit);
dst = this->result;
break;
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 9008e167df1..8a11b04c0fa 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -1837,7 +1837,19 @@ fs_visitor::emit_mcs_fetch(fs_reg coordinate, int components, fs_reg sampler)
}
void
-fs_visitor::visit(ir_texture *ir)
+fs_visitor::emit_texture(ir_texture_opcode op,
+ const glsl_type *dest_type,
+ fs_reg coordinate, const struct glsl_type *coord_type,
+ fs_reg shadow_c,
+ fs_reg lod, fs_reg lod2, int grad_components,
+ fs_reg sample_index,
+ fs_reg offset_value, unsigned offset_components,
+ fs_reg mcs,
+ int gather_component,
+ bool is_cube_array,
+ bool is_rect,
+ uint32_t sampler,
+ fs_reg sampler_reg, int texunit)
{
const struct brw_sampler_prog_key_data *tex =
(stage == MESA_SHADER_FRAGMENT) ?
@@ -1845,6 +1857,98 @@ fs_visitor::visit(ir_texture *ir)
assert(tex);
fs_inst *inst = NULL;
+ if (op == ir_tg4) {
+ /* When tg4 is used with the degenerate ZERO/ONE swizzles, don't bother
+ * emitting anything other than setting up the constant result.
+ */
+ int swiz = GET_SWZ(tex->swizzles[sampler], gather_component);
+ if (swiz == SWIZZLE_ZERO || swiz == SWIZZLE_ONE) {
+
+ fs_reg res = fs_reg(this, glsl_type::vec4_type);
+ this->result = res;
+
+ for (int i=0; i<4; i++) {
+ emit(MOV(res, fs_reg(swiz == SWIZZLE_ZERO ? 0.0f : 1.0f)));
+ res = offset(res, 1);
+ }
+ return;
+ }
+ }
+
+ if (coordinate.file != BAD_FILE) {
+ /* FINISHME: Texture coordinate rescaling doesn't work with non-constant
+ * samplers. This should only be a problem with GL_CLAMP on Gen7.
+ */
+ coordinate = rescale_texcoord(coordinate, coord_type, is_rect,
+ sampler, texunit);
+ }
+
+ /* Writemasking doesn't eliminate channels on SIMD8 texture
+ * samples, so don't worry about them.
+ */
+ fs_reg dst(this, glsl_type::get_instance(dest_type->base_type, 4, 1));
+
+ int coord_components = coord_type ? coord_type->vector_elements : 0;
+
+ if (brw->gen >= 7) {
+ inst = emit_texture_gen7(op, dst, coordinate, coord_components,
+ shadow_c, lod, lod2, grad_components,
+ sample_index, mcs, sampler_reg,
+ offset_value);
+ } else if (brw->gen >= 5) {
+ inst = emit_texture_gen5(op, dst, coordinate, coord_components,
+ shadow_c, lod, lod2, grad_components,
+ sample_index, sampler,
+ offset_value.file != BAD_FILE);
+ } else {
+ inst = emit_texture_gen4(op, dst, coordinate, coord_components,
+ shadow_c, lod, lod2, grad_components,
+ sampler);
+ }
+
+ if (shadow_c.file != BAD_FILE)
+ inst->shadow_compare = true;
+
+ if (offset_value.file == IMM)
+ inst->texture_offset = offset_value.fixed_hw_reg.dw1.ud;
+
+ if (op == ir_tg4) {
+ inst->texture_offset |=
+ gather_channel(gather_component, sampler) << 16; /* M0.2:16-17 */
+
+ if (brw->gen == 6)
+ emit_gen6_gather_wa(tex->gen6_gather_wa[sampler], dst);
+ }
+
+ /* fixup #layers for cube map arrays */
+ if (op == ir_txs && is_cube_array) {
+ fs_reg depth = offset(dst, 2);
+ fs_reg fixed_depth = fs_reg(this, glsl_type::int_type);
+ emit_math(SHADER_OPCODE_INT_QUOTIENT, fixed_depth, depth, fs_reg(6));
+
+ fs_reg *fixed_payload = ralloc_array(mem_ctx, fs_reg, inst->regs_written);
+ int components = inst->regs_written / (dst.width / 8);
+ for (int i = 0; i < components; i++) {
+ if (i == 2) {
+ fixed_payload[i] = fixed_depth;
+ } else {
+ fixed_payload[i] = offset(dst, i);
+ }
+ }
+ emit(LOAD_PAYLOAD(dst, fixed_payload, components));
+ }
+
+ swizzle_result(op, dest_type->vector_elements, dst, sampler);
+}
+
+void
+fs_visitor::visit(ir_texture *ir)
+{
+ const struct brw_sampler_prog_key_data *tex =
+ (stage == MESA_SHADER_FRAGMENT) ?
+ &((brw_wm_prog_key*) this->key)->tex : NULL;
+ assert(tex);
+
uint32_t sampler =
_mesa_get_sampler_uniform_value(ir->sampler, shader_prog, prog);
@@ -1889,25 +1993,6 @@ fs_visitor::visit(ir_texture *ir)
*/
int texunit = prog->SamplerUnits[sampler];
- if (ir->op == ir_tg4) {
- /* When tg4 is used with the degenerate ZERO/ONE swizzles, don't bother
- * emitting anything other than setting up the constant result.
- */
- ir_constant *chan = ir->lod_info.component->as_constant();
- int swiz = GET_SWZ(tex->swizzles[sampler], chan->value.i[0]);
- if (swiz == SWIZZLE_ZERO || swiz == SWIZZLE_ONE) {
-
- fs_reg res = fs_reg(this, glsl_type::vec4_type);
- this->result = res;
-
- for (int i=0; i<4; i++) {
- emit(MOV(res, fs_reg(swiz == SWIZZLE_ZERO ? 0.0f : 1.0f)));
- res = offset(res, 1);
- }
- return;
- }
- }
-
/* Should be lowered by do_lower_texture_projection */
assert(!ir->projector);
@@ -1919,19 +2004,13 @@ fs_visitor::visit(ir_texture *ir)
* generating these values may involve SEND messages that need the MRFs.
*/
fs_reg coordinate;
+ const glsl_type *coord_type = NULL;
if (ir->coordinate) {
+ coord_type = ir->coordinate->type;
ir->coordinate->accept(this);
-
- coordinate = rescale_texcoord(this->result,
- ir->coordinate->type,
- ir->sampler->type->sampler_dimensionality ==
- GLSL_SAMPLER_DIM_RECT,
- sampler, texunit);
+ coordinate = this->result;
}
- int coord_components =
- ir->coordinate ? ir->coordinate->type->vector_elements : 0;
-
fs_reg shadow_comparitor;
if (ir->shadow_comparitor) {
ir->shadow_comparitor->accept(this);
@@ -1939,6 +2018,7 @@ fs_visitor::visit(ir_texture *ir)
}
fs_reg offset_value;
+ int offset_components = 0;
if (ir->offset) {
ir_constant *const_offset = ir->offset->as_constant();
if (const_offset) {
@@ -1953,6 +2033,7 @@ fs_visitor::visit(ir_texture *ir)
ir->offset->accept(this);
offset_value = this->result;
}
+ offset_components = ir->offset->type->vector_elements;
}
fs_reg lod, lod2, sample_index, mcs;
@@ -1996,66 +2077,21 @@ fs_visitor::visit(ir_texture *ir)
unreachable("Unrecognized texture opcode");
};
- /* Writemasking doesn't eliminate channels on SIMD8 texture
- * samples, so don't worry about them.
- */
- fs_reg dst = fs_reg(this, glsl_type::get_instance(ir->type->base_type, 4, 1));
-
- if (brw->gen >= 7) {
- inst = emit_texture_gen7(ir->op, dst, coordinate, coord_components,
- shadow_comparitor,
- lod, lod2, grad_components,
- sample_index, mcs, sampler_reg,
- offset_value);
- } else if (brw->gen >= 5) {
- inst = emit_texture_gen5(ir->op, dst, coordinate, coord_components,
- shadow_comparitor,
- lod, lod2, grad_components,
- sample_index, sampler,
- ir->offset != NULL);
- } else {
- inst = emit_texture_gen4(ir->op, dst, coordinate, coord_components,
- shadow_comparitor,
- lod, lod2, grad_components,
- sampler);
- }
-
- if (offset_value.file == IMM)
- inst->texture_offset = offset_value.fixed_hw_reg.dw1.ud;
-
+ int gather_component = 0;
if (ir->op == ir_tg4)
- inst->texture_offset |= gather_channel(ir->lod_info.component->as_constant()->value.i[0], sampler) << 16; // M0.2:16-17
+ gather_component = ir->lod_info.component->as_constant()->value.i[0];
- if (ir->shadow_comparitor)
- inst->shadow_compare = true;
-
- /* fixup #layers for cube map arrays */
- if (ir->op == ir_txs) {
- glsl_type const *type = ir->sampler->type;
- if (type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE &&
- type->sampler_array) {
- fs_reg depth = offset(dst, 2);
- fs_reg fixed_depth = fs_reg(this, glsl_type::int_type);
- emit_math(SHADER_OPCODE_INT_QUOTIENT, fixed_depth, depth, fs_reg(6));
-
- fs_reg *fixed_payload = ralloc_array(mem_ctx, fs_reg, inst->regs_written);
- int components = inst->regs_written / (dst.width / 8);
- for (int i = 0; i < components; i++) {
- if (i == 2) {
- fixed_payload[i] = fixed_depth;
- } else {
- fixed_payload[i] = offset(dst, i);
- }
- }
- emit(LOAD_PAYLOAD(dst, fixed_payload, components));
- }
- }
+ bool is_rect =
+ ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT;
- if (brw->gen == 6 && ir->op == ir_tg4) {
- emit_gen6_gather_wa(tex->gen6_gather_wa[sampler], dst);
- }
+ bool is_cube_array =
+ ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE &&
+ ir->sampler->type->sampler_array;
- swizzle_result(ir->op, ir->type->vector_elements, dst, sampler);
+ emit_texture(ir->op, ir->type, coordinate, coord_type, shadow_comparitor,
+ lod, lod2, grad_components, sample_index, offset_value,
+ offset_components, mcs, gather_component,
+ is_cube_array, is_rect, sampler, sampler_reg, texunit);
}
/**