diff --git a/.pick_status.json b/.pick_status.json index c17d4e9bac0..2c4c9ff2191 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -994,7 +994,7 @@ "description": "brw: handle GLSL/GLSL tessellation parameters", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "a91e0e0d616f857144c8cadfaed734ac5be8e729", "notes": null diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c index 135fadf7b09..64205872b49 100644 --- a/src/gallium/drivers/iris/iris_program.c +++ b/src/gallium/drivers/iris/iris_program.c @@ -223,9 +223,9 @@ iris_apply_brw_tes_prog_data(struct iris_compiled_shader *shader, iris_apply_brw_vue_prog_data(&brw->base, &iris->base); - iris->partitioning = brw->partitioning; - iris->output_topology = brw->output_topology; - iris->domain = brw->domain; + iris->partitioning = brw_tess_info_partitioning(brw->tess_info); + iris->output_topology = brw_tess_info_output_topology(brw->tess_info); + iris->domain = brw_tess_info_domain(brw->tess_info); iris->include_primitive_id = brw->include_primitive_id; } diff --git a/src/intel/compiler/brw/brw_compile_tcs.cpp b/src/intel/compiler/brw/brw_compile_tcs.cpp index 6db72faf381..da991e9c8dc 100644 --- a/src/intel/compiler/brw/brw_compile_tcs.cpp +++ b/src/intel/compiler/brw/brw_compile_tcs.cpp @@ -196,6 +196,9 @@ brw_compile_tcs(const struct brw_compiler *compiler, brw_prog_data_init(&prog_data->base.base, ¶ms->base); + brw_fill_tess_info_from_shader_info(&prog_data->tess_info, + &nir->info); + nir->info.outputs_written = key->outputs_written; nir->info.patch_outputs_written = key->patch_outputs_written; diff --git a/src/intel/compiler/brw/brw_compile_tes.cpp b/src/intel/compiler/brw/brw_compile_tes.cpp index 56c79e5cddf..2f8b9d93be3 100644 --- a/src/intel/compiler/brw/brw_compile_tes.cpp +++ b/src/intel/compiler/brw/brw_compile_tes.cpp @@ -59,6 +59,22 @@ run_tes(brw_shader &s) return !s.failed; } +extern "C" void +brw_fill_tess_info_from_shader_info(struct brw_tess_info *brw_info, + const shader_info *shader_info) +{ + STATIC_ASSERT(INTEL_TESS_PARTITIONING_INTEGER == TESS_SPACING_EQUAL - 1); + STATIC_ASSERT(INTEL_TESS_PARTITIONING_ODD_FRACTIONAL == + TESS_SPACING_FRACTIONAL_ODD - 1); + STATIC_ASSERT(INTEL_TESS_PARTITIONING_EVEN_FRACTIONAL == + TESS_SPACING_FRACTIONAL_EVEN - 1); + + brw_info->primitive_mode = shader_info->tess._primitive_mode; + brw_info->spacing = shader_info->tess.spacing; + brw_info->ccw = shader_info->tess.ccw; + brw_info->point_mode = shader_info->tess.point_mode; +} + const unsigned * brw_compile_tes(const struct brw_compiler *compiler, brw_compile_tes_params *params) @@ -121,39 +137,8 @@ brw_compile_tes(const struct brw_compiler *compiler, prog_data->base.urb_read_length = 0; - STATIC_ASSERT(INTEL_TESS_PARTITIONING_INTEGER == TESS_SPACING_EQUAL - 1); - STATIC_ASSERT(INTEL_TESS_PARTITIONING_ODD_FRACTIONAL == - TESS_SPACING_FRACTIONAL_ODD - 1); - STATIC_ASSERT(INTEL_TESS_PARTITIONING_EVEN_FRACTIONAL == - TESS_SPACING_FRACTIONAL_EVEN - 1); - - prog_data->partitioning = - (enum intel_tess_partitioning) (nir->info.tess.spacing - 1); - - switch (nir->info.tess._primitive_mode) { - case TESS_PRIMITIVE_QUADS: - prog_data->domain = INTEL_TESS_DOMAIN_QUAD; - break; - case TESS_PRIMITIVE_TRIANGLES: - prog_data->domain = INTEL_TESS_DOMAIN_TRI; - break; - case TESS_PRIMITIVE_ISOLINES: - prog_data->domain = INTEL_TESS_DOMAIN_ISOLINE; - break; - default: - UNREACHABLE("invalid domain shader primitive mode"); - } - - if (nir->info.tess.point_mode) { - prog_data->output_topology = INTEL_TESS_OUTPUT_TOPOLOGY_POINT; - } else if (nir->info.tess._primitive_mode == TESS_PRIMITIVE_ISOLINES) { - prog_data->output_topology = INTEL_TESS_OUTPUT_TOPOLOGY_LINE; - } else { - /* Hardware winding order is backwards from OpenGL */ - prog_data->output_topology = - nir->info.tess.ccw ? INTEL_TESS_OUTPUT_TOPOLOGY_TRI_CW - : INTEL_TESS_OUTPUT_TOPOLOGY_TRI_CCW; - } + brw_fill_tess_info_from_shader_info(&prog_data->tess_info, + &nir->info); if (unlikely(debug_enabled)) { fprintf(stderr, "TES Input "); diff --git a/src/intel/compiler/brw/brw_compiler.h b/src/intel/compiler/brw/brw_compiler.h index 1fa8f2ef099..76b7afd3be0 100644 --- a/src/intel/compiler/brw/brw_compiler.h +++ b/src/intel/compiler/brw/brw_compiler.h @@ -1158,10 +1158,20 @@ struct brw_vs_prog_data { uint32_t vf_component_packing[4]; }; +struct brw_tess_info { + enum tess_primitive_mode primitive_mode:8; + uint8_t spacing:2; + bool ccw:1; + bool point_mode:1; + uint32_t pad:20; +}; + struct brw_tcs_prog_data { struct brw_vue_prog_data base; + struct brw_tess_info tess_info; + /** Number of input vertices, 0 means dynamic */ unsigned input_vertices; @@ -1187,14 +1197,12 @@ struct brw_tcs_prog_data unsigned tess_config_param; }; - struct brw_tes_prog_data { struct brw_vue_prog_data base; - enum intel_tess_partitioning partitioning; - enum intel_tess_output_topology output_topology; - enum intel_tess_domain domain; + struct brw_tess_info tess_info; + bool include_primitive_id; /** @@ -1367,6 +1375,64 @@ DEFINE_PROG_DATA_DOWNCAST(mesh, prog_data->stage == MESA_SHADER_MESH) #undef DEFINE_PROG_DATA_DOWNCAST +static inline struct brw_tess_info +brw_merge_tess_info(struct brw_tess_info tcs_info, + struct brw_tess_info tes_info) +{ + /* Just merge by OR'ing the raw bits */ + uint32_t x, y; + + assert(sizeof(x) == sizeof(tcs_info)); + + memcpy(&x, &tcs_info, sizeof(x)); + memcpy(&y, &tes_info, sizeof(y)); + + x |= y; + + struct brw_tess_info out; + memcpy(&out, &x, sizeof(out)); + return out; +} + +static inline enum intel_tess_partitioning +brw_tess_info_partitioning(struct brw_tess_info info) +{ + return (enum intel_tess_partitioning)(info.spacing - 1); +} + +static inline enum intel_tess_domain +brw_tess_info_domain(struct brw_tess_info info) +{ + switch (info.primitive_mode) { + case TESS_PRIMITIVE_QUADS: + return INTEL_TESS_DOMAIN_QUAD; + break; + case TESS_PRIMITIVE_TRIANGLES: + return INTEL_TESS_DOMAIN_TRI; + break; + case TESS_PRIMITIVE_ISOLINES: + return INTEL_TESS_DOMAIN_ISOLINE; + break; + default: + UNREACHABLE("invalid primitive mode"); + } +} + +static inline enum intel_tess_output_topology +brw_tess_info_output_topology(struct brw_tess_info info) +{ + if (info.point_mode) { + return INTEL_TESS_OUTPUT_TOPOLOGY_POINT; + } else if (info.primitive_mode == TESS_PRIMITIVE_ISOLINES) { + return INTEL_TESS_OUTPUT_TOPOLOGY_LINE; + } else { + /* Hardware winding order is backwards from OpenGL */ + return info.ccw ? + INTEL_TESS_OUTPUT_TOPOLOGY_TRI_CW : + INTEL_TESS_OUTPUT_TOPOLOGY_TRI_CCW; + } +} + /** @} */ struct brw_compiler * diff --git a/src/intel/compiler/brw/brw_nir.h b/src/intel/compiler/brw/brw_nir.h index d9195f1c062..a37b87510bf 100644 --- a/src/intel/compiler/brw/brw_nir.h +++ b/src/intel/compiler/brw/brw_nir.h @@ -36,6 +36,10 @@ extern "C" { extern const struct nir_shader_compiler_options brw_scalar_nir_options; +void +brw_fill_tess_info_from_shader_info(struct brw_tess_info *brw_info, + const shader_info *shader_info); + int type_size_vec4(const struct glsl_type *type, bool bindless); int type_size_dvec4(const struct glsl_type *type, bool bindless); diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index d7e19540b54..68b85842f34 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2161,8 +2161,15 @@ struct anv_gfx_dynamic_state { uint32_t SampleMask; } sm; + /* 3DSTATE_DS */ + struct { + bool ComputeWCoordinateEnable; + } ds; + /* 3DSTATE_TE */ struct { + uint32_t TEDomain; + uint32_t Partitioning; uint32_t OutputTopology; uint32_t TessellationDistributionMode; } te; diff --git a/src/intel/vulkan/genX_gfx_state.c b/src/intel/vulkan/genX_gfx_state.c index ddf09c0eaeb..5c4c125b2ed 100644 --- a/src/intel/vulkan/genX_gfx_state.c +++ b/src/intel/vulkan/genX_gfx_state.c @@ -490,7 +490,12 @@ anv_raster_polygon_mode(const struct anv_cmd_graphics_state *gfx, } UNREACHABLE("Unsupported GS output topology"); } else if (gfx->shaders[MESA_SHADER_TESS_EVAL] != NULL) { - switch (get_gfx_tes_prog_data(gfx)->output_topology) { + struct brw_tess_info tess_info = + brw_merge_tess_info( + get_gfx_tcs_prog_data(gfx)->tess_info, + get_gfx_tes_prog_data(gfx)->tess_info); + + switch (brw_tess_info_output_topology(tess_info)) { case INTEL_TESS_OUTPUT_TOPOLOGY_POINT: return VK_POLYGON_MODE_POINT; @@ -500,8 +505,10 @@ anv_raster_polygon_mode(const struct anv_cmd_graphics_state *gfx, case INTEL_TESS_OUTPUT_TOPOLOGY_TRI_CW: case INTEL_TESS_OUTPUT_TOPOLOGY_TRI_CCW: return polygon_mode; + + default: + UNREACHABLE("Unsupported TCS output topology"); } - UNREACHABLE("Unsupported TCS output topology"); } else { switch (primitive_topology) { case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: @@ -1317,6 +1324,22 @@ update_cps(struct anv_gfx_dynamic_state *hw_state, } #endif +ALWAYS_INLINE static void +update_ds(struct anv_gfx_dynamic_state *hw_state, + const struct anv_cmd_graphics_state *gfx) +{ + const struct brw_tes_prog_data *tes_prog_data = get_gfx_tes_prog_data(gfx); + + if (tes_prog_data) { + struct brw_tess_info tess_info = + brw_merge_tess_info(get_gfx_tcs_prog_data(gfx)->tess_info, + tes_prog_data->tess_info); + + SET(DS, ds.ComputeWCoordinateEnable, + brw_tess_info_domain(tess_info) == INTEL_TESS_DOMAIN_TRI); + } +} + ALWAYS_INLINE static void update_te(struct anv_gfx_dynamic_state *hw_state, const struct anv_device *device, @@ -1326,16 +1349,28 @@ update_te(struct anv_gfx_dynamic_state *hw_state, const struct brw_tes_prog_data *tes_prog_data = get_gfx_tes_prog_data(gfx); if (tes_prog_data) { + struct brw_tess_info tess_info = + brw_merge_tess_info(get_gfx_tcs_prog_data(gfx)->tess_info, + tes_prog_data->tess_info); + + SET(TE, te.TEDomain, brw_tess_info_domain(tess_info)); + SET(TE, te.Partitioning, brw_tess_info_partitioning(tess_info)); if (dyn->ts.domain_origin == VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT) { - SET(TE, te.OutputTopology, tes_prog_data->output_topology); + SET(TE, te.OutputTopology, brw_tess_info_output_topology(tess_info)); } else { - /* When the origin is upper-left, we have to flip the winding order */ - if (tes_prog_data->output_topology == OUTPUT_TRI_CCW) { + /* When the origin is upper-left, we have to flip the winding order */ + enum intel_tess_output_topology output_topology = + brw_tess_info_output_topology(tess_info); + switch (output_topology) { + case OUTPUT_TRI_CCW: SET(TE, te.OutputTopology, OUTPUT_TRI_CW); - } else if (tes_prog_data->output_topology == OUTPUT_TRI_CW) { + break; + case OUTPUT_TRI_CW: SET(TE, te.OutputTopology, OUTPUT_TRI_CCW); - } else { - SET(TE, te.OutputTopology, tes_prog_data->output_topology); + break; + default: + SET(TE, te.OutputTopology, output_topology); + break; } } @@ -2335,11 +2370,14 @@ cmd_buffer_flush_gfx_runtime_state(struct anv_gfx_dynamic_state *hw_state, update_cps(hw_state, device, dyn); #endif /* GFX_VER >= 11 */ + if (gfx->dirty & (ANV_CMD_DIRTY_HS | ANV_CMD_DIRTY_DS)) + update_ds(hw_state, gfx); + if ( #if GFX_VERx10 >= 125 (gfx->dirty & ANV_CMD_DIRTY_PRERASTER_SHADERS) || #else - (gfx->dirty & ANV_CMD_DIRTY_DS) || + (gfx->dirty & (ANV_CMD_DIRTY_HS | ANV_CMD_DIRTY_DS)) || #endif BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_TS_DOMAIN_ORIGIN)) update_te(hw_state, device, dyn, gfx); @@ -2506,10 +2544,14 @@ cmd_buffer_flush_gfx_runtime_state(struct anv_gfx_dynamic_state *hw_state, ((gfx->dirty & (ANV_CMD_DIRTY_HS | ANV_CMD_DIRTY_DS)) || BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS))) { assert(tcs_prog_data != NULL && tes_prog_data != NULL); + struct brw_tess_info tess_info = + brw_merge_tess_info(tcs_prog_data->tess_info, + tes_prog_data->tess_info); + SET(TESS_CONFIG, tess_config, intel_tess_config(dyn->ts.patch_control_points, tcs_prog_data->instances, - tes_prog_data->domain, + brw_tess_info_domain(tess_info), tcs_prog_data->base.vue_map.num_per_patch_slots, tcs_prog_data->base.vue_map.num_per_vertex_slots, tcs_prog_data->base.vue_map.builtins_slot_offset)); @@ -2975,6 +3017,8 @@ cmd_buffer_repack_gfx_state(struct anv_gfx_dynamic_state *hw_state, if (anv_gfx_has_stage(gfx, MESA_SHADER_TESS_EVAL)) { anv_gfx_pack_merge(te, GENX(3DSTATE_TE), MESA_SHADER_TESS_EVAL, ds.te, te) { + SET(te, te, TEDomain); + SET(te, te, Partitioning); SET(te, te, OutputTopology); #if GFX_VERx10 >= 125 SET(te, te, TessellationDistributionMode); @@ -3230,8 +3274,12 @@ cmd_buffer_repack_gfx_state(struct anv_gfx_dynamic_state *hw_state, if (IS_DIRTY(HS)) anv_gfx_copy_protected(hs, GENX(3DSTATE_HS), MESA_SHADER_TESS_CTRL, hs.hs); - if (IS_DIRTY(DS)) - anv_gfx_copy_protected(ds, GENX(3DSTATE_DS), MESA_SHADER_TESS_EVAL, ds.ds); + if (IS_DIRTY(DS)) { + anv_gfx_pack_merge_protected(ds, GENX(3DSTATE_DS), + MESA_SHADER_TESS_EVAL, ds.ds, ds) { + SET(ds, ds, ComputeWCoordinateEnable); + } + } if (IS_DIRTY(GS)) { anv_gfx_pack_merge_protected(gs, GENX(3DSTATE_GS), diff --git a/src/intel/vulkan/genX_shader.c b/src/intel/vulkan/genX_shader.c index 4b9b427646a..77591fe5bbd 100644 --- a/src/intel/vulkan/genX_shader.c +++ b/src/intel/vulkan/genX_shader.c @@ -695,8 +695,6 @@ emit_ds_shader(struct anv_batch *batch, anv_shader_emit(batch, shader, ds.te, GENX(3DSTATE_TE), te) { te.TEEnable = true; - te.Partitioning = tes_prog_data->partitioning; - te.TEDomain = tes_prog_data->domain; te.MaximumTessellationFactorOdd = 63.0; te.MaximumTessellationFactorNotOdd = 64.0; #if GFX_VERx10 >= 125 @@ -731,9 +729,6 @@ emit_ds_shader(struct anv_batch *batch, ds.BindingTableEntryCount = shader->bind_map.surface_count; ds.MaximumNumberofThreads = devinfo->max_tes_threads - 1; - ds.ComputeWCoordinateEnable = - tes_prog_data->domain == INTEL_TESS_DOMAIN_TRI; - ds.PatchURBEntryReadLength = tes_prog_data->base.urb_read_length; ds.PatchURBEntryReadOffset = 0; ds.DispatchGRFStartRegisterForURBData =