diff options
author | Kenneth Graunke <[email protected]> | 2016-11-24 01:50:10 -0800 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2017-01-06 15:55:48 -0800 |
commit | e6ae19944d977dc91bc45adff679337182c20683 (patch) | |
tree | 554723310c16a8d291e32cd3d29e72e80d16ff0c /src/mesa/drivers/dri | |
parent | 31d9de58abbe25229956355b622b9699dffd2f7f (diff) |
i965: Rework gl_TessLevel*[] handling to use NIR compact arrays.
Treating everything as scalar arrays allows us to drop a bunch of
special case input/output munging all throughout the backend.
Instead, we just need to remap the TessLevel components to the
appropriate patch URB header locations in remap_patch_urb_offsets().
We also switch to treating the TES input versions of these as ordinary
shader inputs rather than system values, as remap_patch_urb_offsets()
just makes everything work out without special handling.
This regresses one Piglit test:
arb_tessellation_shader-large-uniforms/GL_TESS_CONTROL_SHADER-array-at-limit
The compiler starts promoting the constant arrays assigned to gl_TessLevel*
to uniform arrays. Since the shader also has a uniform array that uses
the maximum number of uniform components, this puts it over the uniform
component limit enforced by the linker. This is arguably a bug in the
constant array promotion code (it should avoid pushing us over limits),
but is unlikely to penalize any real application.
Signed-off-by: Kenneth Graunke <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_context.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 164 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_nir.c | 74 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_nir.h | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_nir_tcs_workarounds.c | 8 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_shader.cpp | 61 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_shader.h | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_tcs.c | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_tes.c | 17 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp | 117 |
10 files changed, 92 insertions, 364 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index f939463539c..84d34c0f6a0 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -673,7 +673,7 @@ brw_initialize_context_constants(struct brw_context *brw) if (brw->gen >= 5 || brw->is_g4x) ctx->Const.MaxClipPlanes = 8; - ctx->Const.LowerTessLevel = true; + ctx->Const.GLSLTessLevelsAsInputs = true; ctx->Const.LowerTCSPatchVerticesIn = brw->gen >= 8; ctx->Const.LowerTESPatchVerticesIn = true; ctx->Const.PrimitiveRestartForPatches = true; diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp index 2ed843bd03d..8f745dff440 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp @@ -2520,78 +2520,7 @@ fs_visitor::nir_emit_tcs_intrinsic(const fs_builder &bld, bld.MOV(patch_handle, retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UD)); - if (imm_offset == 0) { - /* This is a read of gl_TessLevelInner[], which lives in the - * Patch URB header. The layout depends on the domain. - */ - dst.type = BRW_REGISTER_TYPE_F; - switch (tcs_key->tes_primitive_mode) { - case GL_QUADS: { - /* DWords 3-2 (reversed) */ - fs_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_F, 4); - - inst = bld.emit(SHADER_OPCODE_URB_READ_SIMD8, tmp, patch_handle); - inst->offset = 0; - inst->mlen = 1; - inst->size_written = 4 * REG_SIZE; - - /* dst.xy = tmp.wz */ - bld.MOV(dst, offset(tmp, bld, 3)); - bld.MOV(offset(dst, bld, 1), offset(tmp, bld, 2)); - break; - } - case GL_TRIANGLES: - /* DWord 4; hardcode offset = 1 and size_written = REG_SIZE */ - inst = bld.emit(SHADER_OPCODE_URB_READ_SIMD8, dst, patch_handle); - inst->offset = 1; - inst->mlen = 1; - inst->size_written = REG_SIZE; - break; - case GL_ISOLINES: - /* All channels are undefined. */ - break; - default: - unreachable("Bogus tessellation domain"); - } - } else if (imm_offset == 1) { - /* This is a read of gl_TessLevelOuter[], which lives in the - * Patch URB header. The layout depends on the domain. - */ - dst.type = BRW_REGISTER_TYPE_F; - - fs_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_F, 4); - inst = bld.emit(SHADER_OPCODE_URB_READ_SIMD8, tmp, patch_handle); - inst->offset = 1; - inst->mlen = 1; - inst->size_written = 4 * REG_SIZE; - - /* Reswizzle: WZYX */ - fs_reg srcs[4] = { - offset(tmp, bld, 3), - offset(tmp, bld, 2), - offset(tmp, bld, 1), - offset(tmp, bld, 0), - }; - - unsigned num_components; - switch (tcs_key->tes_primitive_mode) { - case GL_QUADS: - num_components = 4; - break; - case GL_TRIANGLES: - num_components = 3; - break; - case GL_ISOLINES: - /* Isolines are not reversed; swizzle .zw -> .xy */ - srcs[0] = offset(tmp, bld, 2); - srcs[1] = offset(tmp, bld, 3); - num_components = 2; - break; - default: - unreachable("Bogus tessellation domain"); - } - bld.LOAD_PAYLOAD(dst, srcs, num_components, 0); - } else { + { if (first_component != 0) { unsigned read_components = instr->num_components + first_component; @@ -2656,55 +2585,6 @@ fs_visitor::nir_emit_tcs_intrinsic(const fs_builder &bld, if (indirect_offset.file != BAD_FILE) { srcs[header_regs++] = indirect_offset; - } else if (!is_passthrough_shader) { - if (imm_offset == 0) { - value.type = BRW_REGISTER_TYPE_F; - - mask &= (1 << tesslevel_inner_components(tcs_key->tes_primitive_mode)) - 1; - - /* This is a write to gl_TessLevelInner[], which lives in the - * Patch URB header. The layout depends on the domain. - */ - switch (tcs_key->tes_primitive_mode) { - case GL_QUADS: - /* gl_TessLevelInner[].xy lives at DWords 3-2 (reversed). - * We use an XXYX swizzle to reverse put .xy in the .wz - * channels, and use a .zw writemask. - */ - mask = writemask_for_backwards_vector(mask); - swiz = BRW_SWIZZLE4(0, 0, 1, 0); - break; - case GL_TRIANGLES: - /* gl_TessLevelInner[].x lives at DWord 4, so we set the - * writemask to X and bump the URB offset by 1. - */ - imm_offset = 1; - break; - case GL_ISOLINES: - /* Skip; gl_TessLevelInner[] doesn't exist for isolines. */ - return; - default: - unreachable("Bogus tessellation domain"); - } - } else if (imm_offset == 1) { - /* This is a write to gl_TessLevelOuter[] which lives in the - * Patch URB Header at DWords 4-7. However, it's reversed, so - * instead of .xyzw we have .wzyx. - */ - value.type = BRW_REGISTER_TYPE_F; - - mask &= (1 << tesslevel_outer_components(tcs_key->tes_primitive_mode)) - 1; - - if (tcs_key->tes_primitive_mode == GL_ISOLINES) { - /* Isolines .xy should be stored in .zw, in order. */ - swiz = BRW_SWIZZLE4(0, 0, 0, 1); - mask <<= 2; - } else { - /* Other domains are reversed; store .wzyx instead of .xyzw */ - swiz = BRW_SWIZZLE_WZYX; - mask = writemask_for_backwards_vector(mask); - } - } } if (mask == 0) @@ -2851,48 +2731,6 @@ fs_visitor::nir_emit_tes_intrinsic(const fs_builder &bld, } break; - case nir_intrinsic_load_tess_level_outer: - /* When the TES reads gl_TessLevelOuter, we ensure that the patch header - * appears as a push-model input. So, we can simply use the ATTR file - * rather than issuing URB read messages. The data is stored in the - * high DWords in reverse order - DWord 7 contains .x, DWord 6 contains - * .y, and so on. - */ - switch (tes_prog_data->domain) { - case BRW_TESS_DOMAIN_QUAD: - for (unsigned i = 0; i < 4; i++) - bld.MOV(offset(dest, bld, i), component(fs_reg(ATTR, 0), 7 - i)); - break; - case BRW_TESS_DOMAIN_TRI: - for (unsigned i = 0; i < 3; i++) - bld.MOV(offset(dest, bld, i), component(fs_reg(ATTR, 0), 7 - i)); - break; - case BRW_TESS_DOMAIN_ISOLINE: - for (unsigned i = 0; i < 2; i++) - bld.MOV(offset(dest, bld, i), component(fs_reg(ATTR, 0), 6 + i)); - break; - } - break; - - case nir_intrinsic_load_tess_level_inner: - /* When the TES reads gl_TessLevelInner, we ensure that the patch header - * appears as a push-model input. So, we can simply use the ATTR file - * rather than issuing URB read messages. - */ - switch (tes_prog_data->domain) { - case BRW_TESS_DOMAIN_QUAD: - bld.MOV(dest, component(fs_reg(ATTR, 0), 3)); - bld.MOV(offset(dest, bld, 1), component(fs_reg(ATTR, 0), 2)); - break; - case BRW_TESS_DOMAIN_TRI: - bld.MOV(dest, component(fs_reg(ATTR, 0), 4)); - break; - case BRW_TESS_DOMAIN_ISOLINE: - /* ignore - value is undefined */ - break; - } - break; - case nir_intrinsic_load_input: case nir_intrinsic_load_per_vertex_input: { fs_reg indirect_offset = get_indirect_offset(instr); diff --git a/src/mesa/drivers/dri/i965/brw_nir.c b/src/mesa/drivers/dri/i965/brw_nir.c index 6f37e97a86f..46eeb1723b4 100644 --- a/src/mesa/drivers/dri/i965/brw_nir.c +++ b/src/mesa/drivers/dri/i965/brw_nir.c @@ -141,9 +141,68 @@ remap_inputs_with_vue_map(nir_block *block, const struct brw_vue_map *vue_map) } static bool +remap_tess_levels(nir_builder *b, nir_intrinsic_instr *intr, + GLenum primitive_mode) +{ + const int location = nir_intrinsic_base(intr); + const unsigned component = nir_intrinsic_component(intr); + bool out_of_bounds; + + if (location == VARYING_SLOT_TESS_LEVEL_INNER) { + switch (primitive_mode) { + case GL_QUADS: + /* gl_TessLevelInner[0..1] lives at DWords 3-2 (reversed). */ + nir_intrinsic_set_base(intr, 0); + nir_intrinsic_set_component(intr, 3 - component); + out_of_bounds = false; + break; + case GL_TRIANGLES: + /* gl_TessLevelInner[0] lives at DWord 4. */ + nir_intrinsic_set_base(intr, 1); + out_of_bounds = component > 0; + break; + case GL_ISOLINES: + out_of_bounds = true; + break; + default: + unreachable("Bogus tessellation domain"); + } + } else if (location == VARYING_SLOT_TESS_LEVEL_OUTER) { + if (primitive_mode == GL_ISOLINES) { + /* gl_TessLevelOuter[0..1] lives at DWords 6-7 (in order). */ + nir_intrinsic_set_base(intr, 1); + nir_intrinsic_set_component(intr, 2 + nir_intrinsic_component(intr)); + out_of_bounds = component > 1; + } else { + /* Triangles use DWords 7-5 (reversed); Quads use 7-4 (reversed) */ + nir_intrinsic_set_base(intr, 1); + nir_intrinsic_set_component(intr, 3 - nir_intrinsic_component(intr)); + out_of_bounds = component == 3 && primitive_mode == GL_TRIANGLES; + } + } else { + return false; + } + + if (out_of_bounds) { + if (nir_intrinsic_infos[intr->intrinsic].has_dest) { + b->cursor = nir_before_instr(&intr->instr); + nir_ssa_def *undef = nir_ssa_undef(b, 1, 32); + nir_ssa_def_rewrite_uses(&intr->dest.ssa, nir_src_for_ssa(undef)); + } + nir_instr_remove(&intr->instr); + } + + return true; +} + +static bool remap_patch_urb_offsets(nir_block *block, nir_builder *b, - const struct brw_vue_map *vue_map) + const struct brw_vue_map *vue_map, + GLenum tes_primitive_mode) { + const bool is_passthrough_tcs = b->shader->info->name && + strcmp(b->shader->info->name, "passthrough") == 0; + nir_foreach_instr_safe(instr, block) { if (instr->type != nir_instr_type_intrinsic) continue; @@ -154,6 +213,11 @@ remap_patch_urb_offsets(nir_block *block, nir_builder *b, if ((stage == MESA_SHADER_TESS_CTRL && is_output(intrin)) || (stage == MESA_SHADER_TESS_EVAL && is_input(intrin))) { + + if (!is_passthrough_tcs && + remap_tess_levels(b, intrin, tes_primitive_mode)) + continue; + int vue_slot = vue_map->varying_to_slot[intrin->const_index[0]]; assert(vue_slot != -1); intrin->const_index[0] = vue_slot; @@ -273,7 +337,8 @@ brw_nir_lower_tes_inputs(nir_shader *nir, const struct brw_vue_map *vue_map) nir_builder b; nir_builder_init(&b, function->impl); nir_foreach_block(block, function->impl) { - remap_patch_urb_offsets(block, &b, vue_map); + remap_patch_urb_offsets(block, &b, vue_map, + nir->info->tes.primitive_mode); } } } @@ -341,7 +406,8 @@ brw_nir_lower_vue_outputs(nir_shader *nir, } void -brw_nir_lower_tcs_outputs(nir_shader *nir, const struct brw_vue_map *vue_map) +brw_nir_lower_tcs_outputs(nir_shader *nir, const struct brw_vue_map *vue_map, + GLenum tes_primitive_mode) { nir_foreach_variable(var, &nir->outputs) { var->data.driver_location = var->data.location; @@ -359,7 +425,7 @@ brw_nir_lower_tcs_outputs(nir_shader *nir, const struct brw_vue_map *vue_map) nir_builder b; nir_builder_init(&b, function->impl); nir_foreach_block(block, function->impl) { - remap_patch_urb_offsets(block, &b, vue_map); + remap_patch_urb_offsets(block, &b, vue_map, tes_primitive_mode); } } } diff --git a/src/mesa/drivers/dri/i965/brw_nir.h b/src/mesa/drivers/dri/i965/brw_nir.h index a7189c12165..f713d47b40e 100644 --- a/src/mesa/drivers/dri/i965/brw_nir.h +++ b/src/mesa/drivers/dri/i965/brw_nir.h @@ -109,7 +109,8 @@ void brw_nir_lower_fs_inputs(nir_shader *nir, struct brw_vue_map *vue_map, const struct gen_device_info *devinfo, const struct brw_wm_prog_key *key); void brw_nir_lower_vue_outputs(nir_shader *nir, bool is_scalar); -void brw_nir_lower_tcs_outputs(nir_shader *nir, const struct brw_vue_map *vue); +void brw_nir_lower_tcs_outputs(nir_shader *nir, const struct brw_vue_map *vue, + GLenum tes_primitive_mode); void brw_nir_lower_fs_outputs(nir_shader *nir); void brw_nir_lower_cs_shared(nir_shader *nir); diff --git a/src/mesa/drivers/dri/i965/brw_nir_tcs_workarounds.c b/src/mesa/drivers/dri/i965/brw_nir_tcs_workarounds.c index 154be3b1125..a85f493c704 100644 --- a/src/mesa/drivers/dri/i965/brw_nir_tcs_workarounds.c +++ b/src/mesa/drivers/dri/i965/brw_nir_tcs_workarounds.c @@ -73,7 +73,7 @@ */ static inline nir_ssa_def * -load_output(nir_builder *b, int num_components, int offset) +load_output(nir_builder *b, int num_components, int offset, int component) { nir_intrinsic_instr *load = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_output); @@ -81,6 +81,7 @@ load_output(nir_builder *b, int num_components, int offset) load->num_components = num_components; load->src[0] = nir_src_for_ssa(nir_imm_int(b, 0)); nir_intrinsic_set_base(load, offset); + nir_intrinsic_set_component(load, component); nir_builder_instr_insert(b, &load->instr); @@ -92,8 +93,8 @@ emit_quads_workaround(nir_builder *b, nir_block *block) { b->cursor = nir_after_block_before_jump(block); - nir_ssa_def *inner = load_output(b, 2, 0); - nir_ssa_def *outer = load_output(b, 4, 1); + nir_ssa_def *inner = load_output(b, 2, 0, 2); + nir_ssa_def *outer = load_output(b, 4, 1, 0); nir_ssa_def *any_greater_than_1 = nir_ior(b, nir_bany(b, nir_flt(b, nir_imm_float(b, 1.0f), outer)), @@ -113,6 +114,7 @@ emit_quads_workaround(nir_builder *b, nir_block *block) nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_output); store->num_components = 2; nir_intrinsic_set_write_mask(store, WRITEMASK_XY); + nir_intrinsic_set_component(store, 2); store->src[0] = nir_src_for_ssa(inner); store->src[1] = nir_src_for_ssa(nir_imm_int(b, 0)); nir_builder_instr_insert(b, &store->instr); diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp index af8a4e501f7..6c4f5f8de5e 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.cpp +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp @@ -648,53 +648,6 @@ get_atomic_counter_op(nir_intrinsic_op op) } } -unsigned -tesslevel_outer_components(GLenum tes_primitive_mode) -{ - switch (tes_primitive_mode) { - case GL_QUADS: - return 4; - case GL_TRIANGLES: - return 3; - case GL_ISOLINES: - return 2; - default: - unreachable("Bogus tessellation domain"); - } - return 0; -} - -unsigned -tesslevel_inner_components(GLenum tes_primitive_mode) -{ - switch (tes_primitive_mode) { - case GL_QUADS: - return 2; - case GL_TRIANGLES: - return 1; - case GL_ISOLINES: - return 0; - default: - unreachable("Bogus tessellation domain"); - } - return 0; -} - -/** - * Given a normal .xyzw writemask, convert it to a writemask for a vector - * that's stored backwards, i.e. .wzyx. - */ -unsigned -writemask_for_backwards_vector(unsigned mask) -{ - unsigned new_mask = 0; - - for (int i = 0; i < 4; i++) - new_mask |= ((mask >> i) & 1) << (3 - i); - - return new_mask; -} - backend_shader::backend_shader(const struct brw_compiler *compiler, void *log_data, void *mem_ctx, @@ -712,8 +665,6 @@ backend_shader::backend_shader(const struct brw_compiler *compiler, debug_enabled = INTEL_DEBUG & intel_debug_flag_for_shader_stage(stage); stage_name = _mesa_shader_stage_to_string(stage); stage_abbrev = _mesa_shader_stage_to_abbrev(stage); - is_passthrough_shader = - nir->info->name && strcmp(nir->info->name, "passthrough") == 0; } bool @@ -1394,17 +1345,7 @@ brw_compile_tes(const struct brw_compiler *compiler, /* URB entry sizes are stored as a multiple of 64 bytes. */ prog_data->base.urb_entry_size = ALIGN(output_size_bytes, 64) / 64; - - bool need_patch_header = nir->info->system_values_read & - (BITFIELD64_BIT(SYSTEM_VALUE_TESS_LEVEL_OUTER) | - BITFIELD64_BIT(SYSTEM_VALUE_TESS_LEVEL_INNER)); - - /* The TES will pull most inputs using URB read messages. - * - * However, we push the patch header for TessLevel factors when required, - * as it's a tiny amount of extra data. - */ - prog_data->base.urb_read_length = need_patch_header ? 1 : 0; + prog_data->base.urb_read_length = 0; if (unlikely(INTEL_DEBUG & DEBUG_TES)) { fprintf(stderr, "TES Input "); diff --git a/src/mesa/drivers/dri/i965/brw_shader.h b/src/mesa/drivers/dri/i965/brw_shader.h index 9366d91c74a..60f498f0ebb 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.h +++ b/src/mesa/drivers/dri/i965/brw_shader.h @@ -217,7 +217,6 @@ public: bool debug_enabled; const char *stage_name; const char *stage_abbrev; - bool is_passthrough_shader; brw::simple_allocator alloc; @@ -291,10 +290,6 @@ bool brw_cs_precompile(struct gl_context *ctx, struct gl_program *prog); GLboolean brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog); struct gl_linked_shader *brw_new_shader(gl_shader_stage stage); -unsigned tesslevel_outer_components(GLenum tes_primitive_mode); -unsigned tesslevel_inner_components(GLenum tes_primitive_mode); -unsigned writemask_for_backwards_vector(unsigned mask); - unsigned get_atomic_counter_op(nir_intrinsic_op op); #ifdef __cplusplus diff --git a/src/mesa/drivers/dri/i965/brw_tcs.c b/src/mesa/drivers/dri/i965/brw_tcs.c index 70571774a1e..b6251d52f60 100644 --- a/src/mesa/drivers/dri/i965/brw_tcs.c +++ b/src/mesa/drivers/dri/i965/brw_tcs.c @@ -51,7 +51,8 @@ create_passthrough_tcs(void *mem_ctx, const struct brw_compiler *compiler, nir_ssa_def *invoc_id = nir_load_system_value(&b, nir_intrinsic_load_invocation_id, 0); - nir->info->inputs_read = key->outputs_written; + nir->info->inputs_read = key->outputs_written & + ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER); nir->info->outputs_written = key->outputs_written; nir->info->tcs.vertices_out = key->input_vertices; nir->info->name = ralloc_strdup(nir, "passthrough"); @@ -81,7 +82,7 @@ create_passthrough_tcs(void *mem_ctx, const struct brw_compiler *compiler, } /* Copy inputs to outputs. */ - uint64_t varyings = key->outputs_written; + uint64_t varyings = nir->info->inputs_read; while (varyings != 0) { const int varying = ffsll(varyings) - 1; diff --git a/src/mesa/drivers/dri/i965/brw_tes.c b/src/mesa/drivers/dri/i965/brw_tes.c index 124df66ef9b..06862df8346 100644 --- a/src/mesa/drivers/dri/i965/brw_tes.c +++ b/src/mesa/drivers/dri/i965/brw_tes.c @@ -235,16 +235,12 @@ brw_tes_populate_key(struct brw_context *brw, */ if (tcp) { struct gl_program *tcp_prog = &tcp->program; - per_vertex_slots |= tcp_prog->info.outputs_written; + per_vertex_slots |= tcp_prog->info.outputs_written & + ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER); per_patch_slots |= tcp_prog->info.patch_outputs_written; } - /* Ignore gl_TessLevelInner/Outer - we treat them as system values, - * not inputs, and they're always present in the URB entry regardless - * of whether or not we read them. - */ - key->inputs_read = per_vertex_slots & - ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER); + key->inputs_read = per_vertex_slots; key->patch_inputs_read = per_patch_slots; /* _NEW_TEXTURE */ @@ -299,14 +295,11 @@ brw_tes_precompile(struct gl_context *ctx, if (shader_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]) { struct gl_program *tcp = shader_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program; - key.inputs_read |= tcp->nir->info->outputs_written; + key.inputs_read |= tcp->nir->info->outputs_written & + ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER); key.patch_inputs_read |= tcp->nir->info->patch_outputs_written; } - /* Ignore gl_TessLevelInner/Outer - they're system values. */ - key.inputs_read &= ~(VARYING_BIT_TESS_LEVEL_INNER | - VARYING_BIT_TESS_LEVEL_OUTER); - brw_setup_tex_for_precompile(brw, &key.tex, prog); success = brw_codegen_tes_prog(brw, btep, &key); diff --git a/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp b/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp index bfa22458f0e..9ef3dc04665 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp @@ -319,62 +319,8 @@ vec4_tcs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr) dst_reg dst = get_nir_dest(instr->dest, BRW_REGISTER_TYPE_D); dst.writemask = brw_writemask_for_size(instr->num_components); - if (imm_offset == 0 && indirect_offset.file == BAD_FILE) { - dst.type = BRW_REGISTER_TYPE_F; - - /* This is a read of gl_TessLevelInner[], which lives in the - * Patch URB header. The layout depends on the domain. - */ - switch (key->tes_primitive_mode) { - case GL_QUADS: { - /* DWords 3-2 (reversed); use offset 0 and WZYX swizzle. */ - dst_reg tmp(this, glsl_type::vec4_type); - emit_output_urb_read(tmp, 0, 0, src_reg()); - emit(MOV(writemask(dst, WRITEMASK_XY), - swizzle(src_reg(tmp), BRW_SWIZZLE_WZYX))); - break; - } - case GL_TRIANGLES: - /* DWord 4; use offset 1 but normal swizzle/writemask. */ - emit_output_urb_read(writemask(dst, WRITEMASK_X), 1, 0, - src_reg()); - break; - case GL_ISOLINES: - /* All channels are undefined. */ - return; - default: - unreachable("Bogus tessellation domain"); - } - } else if (imm_offset == 1 && indirect_offset.file == BAD_FILE) { - dst.type = BRW_REGISTER_TYPE_F; - unsigned swiz = BRW_SWIZZLE_WZYX; - - /* This is a read of gl_TessLevelOuter[], which lives in the - * high 4 DWords of the Patch URB header, in reverse order. - */ - switch (key->tes_primitive_mode) { - case GL_QUADS: - dst.writemask = WRITEMASK_XYZW; - break; - case GL_TRIANGLES: - dst.writemask = WRITEMASK_XYZ; - break; - case GL_ISOLINES: - /* Isolines are not reversed; swizzle .zw -> .xy */ - swiz = BRW_SWIZZLE_ZWZW; - dst.writemask = WRITEMASK_XY; - return; - default: - unreachable("Bogus tessellation domain"); - } - - dst_reg tmp(this, glsl_type::vec4_type); - emit_output_urb_read(tmp, 1, 0, src_reg()); - emit(MOV(dst, swizzle(src_reg(tmp), swiz))); - } else { - emit_output_urb_read(dst, imm_offset, nir_intrinsic_component(instr), - indirect_offset); - } + emit_output_urb_read(dst, imm_offset, nir_intrinsic_component(instr), + indirect_offset); break; } case nir_intrinsic_store_output: @@ -386,62 +332,6 @@ vec4_tcs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr) src_reg indirect_offset = get_indirect_offset(instr); unsigned imm_offset = instr->const_index[0]; - /* The passthrough shader writes the whole patch header as two vec4s; - * skip all the gl_TessLevelInner/Outer swizzling. - */ - if (indirect_offset.file == BAD_FILE && !is_passthrough_shader) { - if (imm_offset == 0) { - value.type = BRW_REGISTER_TYPE_F; - - mask &= - (1 << tesslevel_inner_components(key->tes_primitive_mode)) - 1; - - /* This is a write to gl_TessLevelInner[], which lives in the - * Patch URB header. The layout depends on the domain. - */ - switch (key->tes_primitive_mode) { - case GL_QUADS: - /* gl_TessLevelInner[].xy lives at DWords 3-2 (reversed). - * We use an XXYX swizzle to reverse put .xy in the .wz - * channels, and use a .zw writemask. - */ - swiz = BRW_SWIZZLE4(0, 0, 1, 0); - mask = writemask_for_backwards_vector(mask); - break; - case GL_TRIANGLES: - /* gl_TessLevelInner[].x lives at DWord 4, so we set the - * writemask to X and bump the URB offset by 1. - */ - imm_offset = 1; - break; - case GL_ISOLINES: - /* Skip; gl_TessLevelInner[] doesn't exist for isolines. */ - return; - default: - unreachable("Bogus tessellation domain"); - } - } else if (imm_offset == 1) { - value.type = BRW_REGISTER_TYPE_F; - - mask &= - (1 << tesslevel_outer_components(key->tes_primitive_mode)) - 1; - - /* This is a write to gl_TessLevelOuter[] which lives in the - * Patch URB Header at DWords 4-7. However, it's reversed, so - * instead of .xyzw we have .wzyx. - */ - if (key->tes_primitive_mode == GL_ISOLINES) { - /* Isolines .xy should be stored in .zw, in order. */ - swiz = BRW_SWIZZLE4(0, 0, 0, 1); - mask <<= 2; - } else { - /* Other domains are reversed; store .wzyx instead of .xyzw. */ - swiz = BRW_SWIZZLE_WZYX; - mask = writemask_for_backwards_vector(mask); - } - } - } - unsigned first_component = nir_intrinsic_component(instr); if (first_component) { if (nir_src_bit_size(instr->src[0]) == 64) @@ -522,7 +412,8 @@ brw_compile_tcs(const struct brw_compiler *compiler, nir = brw_nir_apply_sampler_key(nir, compiler, &key->tex, is_scalar); brw_nir_lower_vue_inputs(nir, is_scalar, &input_vue_map); - brw_nir_lower_tcs_outputs(nir, &vue_prog_data->vue_map); + brw_nir_lower_tcs_outputs(nir, &vue_prog_data->vue_map, + key->tes_primitive_mode); if (key->quads_workaround) brw_nir_apply_tcs_quads_workaround(nir); |