Module: Mesa Branch: main Commit: 55c8f5e288ea18683f0438c115fb9561b72a9a87 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=55c8f5e288ea18683f0438c115fb9561b72a9a87
Author: George Ouzounoudis <[email protected]> Date: Thu Aug 24 22:54:37 2023 +0300 nvk: Support extended dynamic state for tessellation domain origin The tessellation domain origin, type, prims and spacing are all pushed together in SET_TESSELLATION_PARAMETERS. So to support domain origin as dynamic we need to push all these together when the state is dynamically changed or when a new tessellation shader is bound. This is also needed for EXT_shader_object. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24872> --- src/nouveau/vulkan/nvk_cmd_draw.c | 34 +++++++++++++++++++++++++++++- src/nouveau/vulkan/nvk_graphics_pipeline.c | 34 ++++-------------------------- src/nouveau/vulkan/nvk_physical_device.c | 2 +- src/nouveau/vulkan/nvk_shader.h | 6 ++++++ 4 files changed, 44 insertions(+), 32 deletions(-) diff --git a/src/nouveau/vulkan/nvk_cmd_draw.c b/src/nouveau/vulkan/nvk_cmd_draw.c index 1188f79b2cd..22b2b760d2f 100644 --- a/src/nouveau/vulkan/nvk_cmd_draw.c +++ b/src/nouveau/vulkan/nvk_cmd_draw.c @@ -930,6 +930,15 @@ nvk_cmd_bind_graphics_pipeline(struct nvk_cmd_buffer *cmd, cmd->state.gfx.pipeline = pipeline; vk_cmd_set_dynamic_graphics_state(&cmd->vk, &pipeline->dynamic); + /* When a pipeline with tess shaders is bound we need to re-upload the + * tessellation parameters at flush_ts_state, as the domain origin can be + * dynamic. + */ + if (nvk_shader_is_enabled(&pipeline->base.shaders[MESA_SHADER_TESS_EVAL])) { + BITSET_SET(cmd->vk.dynamic_graphics_state.dirty, + MESA_VK_DYNAMIC_TS_DOMAIN_ORIGIN); + } + struct nv_push *p = nvk_cmd_buffer_push(cmd, pipeline->push_dw_count); nv_push_raw(p, pipeline->push_data, pipeline->push_dw_count); } @@ -999,11 +1008,34 @@ nvk_flush_ts_state(struct nvk_cmd_buffer *cmd) { const struct vk_dynamic_graphics_state *dyn = &cmd->vk.dynamic_graphics_state; + struct nv_push *p = nvk_cmd_buffer_push(cmd, 4); if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS)) { - struct nv_push *p = nvk_cmd_buffer_push(cmd, 2); P_IMMD(p, NV9097, SET_PATCH, dyn->ts.patch_control_points); } + + if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_TS_DOMAIN_ORIGIN)) { + const struct nvk_graphics_pipeline *pipeline= cmd->state.gfx.pipeline; + const struct nvk_shader *shader = + &pipeline->base.shaders[MESA_SHADER_TESS_EVAL]; + + if (nvk_shader_is_enabled(shader)) { + enum nak_ts_prims prims = shader->info.ts.prims; + /* When the origin is lower-left, we have to flip the winding order */ + if (dyn->ts.domain_origin == VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT) { + if (prims == NAK_TS_PRIMS_TRIANGLES_CW) + prims = NAK_TS_PRIMS_TRIANGLES_CCW; + else if (prims == NAK_TS_PRIMS_TRIANGLES_CCW) + prims = NAK_TS_PRIMS_TRIANGLES_CW; + } + P_MTHD(p, NV9097, SET_TESSELLATION_PARAMETERS); + P_NV9097_SET_TESSELLATION_PARAMETERS(p, { + shader->info.ts.domain, + shader->info.ts.spacing, + prims + }); + } + } } static void diff --git a/src/nouveau/vulkan/nvk_graphics_pipeline.c b/src/nouveau/vulkan/nvk_graphics_pipeline.c index dfb0d0ad4b9..8485818fcd3 100644 --- a/src/nouveau/vulkan/nvk_graphics_pipeline.c +++ b/src/nouveau/vulkan/nvk_graphics_pipeline.c @@ -113,27 +113,6 @@ static const uint32_t mesa_to_nv9097_shader_type[] = { [MESA_SHADER_FRAGMENT] = NV9097_SET_PIPELINE_SHADER_TYPE_PIXEL, }; -static void -emit_tessellation_paramaters(struct nv_push *p, - const struct nvk_shader *shader, - const struct vk_tessellation_state *state) -{ - enum nak_ts_prims prims = shader->info.ts.prims; - /* When the origin is lower-left, we have to flip the winding order */ - if (state->domain_origin == VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT) { - if (prims == NAK_TS_PRIMS_TRIANGLES_CW) - prims = NAK_TS_PRIMS_TRIANGLES_CCW; - else if (prims == NAK_TS_PRIMS_TRIANGLES_CCW) - prims = NAK_TS_PRIMS_TRIANGLES_CW; - } - P_MTHD(p, NV9097, SET_TESSELLATION_PARAMETERS); - P_NV9097_SET_TESSELLATION_PARAMETERS(p, { - shader->info.ts.domain, - shader->info.ts.spacing, - prims - }); -} - static void merge_tess_info(struct shader_info *tes_info, struct shader_info *tcs_info) { @@ -267,11 +246,11 @@ nvk_graphics_pipeline_create(struct nvk_device *dev, uint32_t idx = mesa_to_nv9097_shader_type[stage]; P_IMMD(p, NV9097, SET_PIPELINE_SHADER(idx), { - .enable = shader->upload_size > 0, + .enable = nvk_shader_is_enabled(shader), .type = mesa_to_nv9097_shader_type[stage], }); - if (shader->upload_size == 0) + if (!nvk_shader_is_enabled(shader)) continue; if (stage != MESA_SHADER_FRAGMENT) @@ -294,6 +273,8 @@ nvk_graphics_pipeline_create(struct nvk_device *dev, switch (stage) { case MESA_SHADER_VERTEX: case MESA_SHADER_GEOMETRY: + case MESA_SHADER_TESS_CTRL: + case MESA_SHADER_TESS_EVAL: break; case MESA_SHADER_FRAGMENT: @@ -329,13 +310,6 @@ nvk_graphics_pipeline_create(struct nvk_device *dev, shader->info.fs.uses_sample_shading; break; - case MESA_SHADER_TESS_CTRL: - break; - - case MESA_SHADER_TESS_EVAL: - emit_tessellation_paramaters(p, shader, state.ts); - break; - default: unreachable("Unsupported shader stage"); } diff --git a/src/nouveau/vulkan/nvk_physical_device.c b/src/nouveau/vulkan/nvk_physical_device.c index aead8a93c72..8e9bab843a0 100644 --- a/src/nouveau/vulkan/nvk_physical_device.c +++ b/src/nouveau/vulkan/nvk_physical_device.c @@ -389,7 +389,7 @@ nvk_get_device_features(const struct nv_device_info *info, .extendedDynamicState2PatchControlPoints = true, /* VK_EXT_extended_dynamic_state3 */ - .extendedDynamicState3TessellationDomainOrigin = false, + .extendedDynamicState3TessellationDomainOrigin = true, .extendedDynamicState3DepthClampEnable = true, .extendedDynamicState3PolygonMode = true, .extendedDynamicState3RasterizationSamples = false, diff --git a/src/nouveau/vulkan/nvk_shader.h b/src/nouveau/vulkan/nvk_shader.h index 0644b4e4e7a..dea5cdf0bd6 100644 --- a/src/nouveau/vulkan/nvk_shader.h +++ b/src/nouveau/vulkan/nvk_shader.h @@ -64,6 +64,12 @@ nvk_shader_address(const struct nvk_shader *shader) return shader->upload_addr + shader->upload_padding; } +static inline bool +nvk_shader_is_enabled(const struct nvk_shader *shader) +{ + return shader->upload_size > 0; +} + VkShaderStageFlags nvk_nak_stages(const struct nv_device_info *info); uint64_t
