Added support for setting the locations when the pipeline has been created with the dynamic state bit enabled according to the Vulkan Specification section [26.5. Custom Sample Locations] for the function:
'vkCmdSetSampleLocationsEXT' The reason that we preferred to store the boolean valid inside the dynamic state struct for locations instead of using a dirty bit (ANV_CMD_DIRTY_SAMPLE_LOCATIONS for example) is that other functions can modify the value of the dirty bits causing unexpected behavior. v2: Removed all the anv* structs used with sample locations to store the locations in order for dynamic case. (see also the patch for the non-dynamic case. (Jason Ekstrand) --- src/intel/vulkan/anv_cmd_buffer.c | 19 ++++++++++++++ src/intel/vulkan/anv_genX.h | 4 +++ src/intel/vulkan/anv_private.h | 6 +++++ src/intel/vulkan/genX_cmd_buffer.c | 24 ++++++++++++++++++ src/intel/vulkan/genX_pipeline.c | 40 +----------------------------- src/intel/vulkan/genX_state.c | 36 +++++++++++++++++++++++++++ 6 files changed, 90 insertions(+), 39 deletions(-) diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index 1b34644a434..866cd03b05e 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -558,6 +558,25 @@ void anv_CmdSetStencilReference( cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE; } +void +anv_CmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer, + const VkSampleLocationsInfoEXT *pSampleLocationsInfo) +{ + ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); + + struct anv_dynamic_state *dyn_state = &cmd_buffer->state.gfx.dynamic; + uint32_t num_samples = pSampleLocationsInfo->sampleLocationsPerPixel; + + assert(pSampleLocationsInfo); + dyn_state->sample_locations.num_samples = num_samples; + + memcpy(dyn_state->sample_locations.positions, + pSampleLocationsInfo->pSampleLocations, + num_samples * sizeof *pSampleLocationsInfo->pSampleLocations); + + dyn_state->sample_locations.valid = true; +} + static void anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer, VkPipelineBindPoint bind_point, diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h index fb7419b6347..5c618a6666b 100644 --- a/src/intel/vulkan/anv_genX.h +++ b/src/intel/vulkan/anv_genX.h @@ -89,6 +89,10 @@ void genX(cmd_buffer_mi_memset)(struct anv_cmd_buffer *cmd_buffer, void genX(blorp_exec)(struct blorp_batch *batch, const struct blorp_params *params); +void genX(emit_multisample)(struct anv_batch *batch, + uint32_t samples, + uint32_t log2_samples); + void genX(emit_sample_locations)(struct anv_batch *batch, const VkSampleLocationEXT *sl, uint32_t num_samples, diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index a39195733cd..1e1d2feaa50 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2124,6 +2124,12 @@ struct anv_dynamic_state { uint32_t front; uint32_t back; } stencil_reference; + + struct { + VkSampleLocationEXT positions[MAX_SAMPLE_LOCATIONS]; + uint32_t num_samples; + bool valid; + } sample_locations; }; extern const struct anv_dynamic_state default_dynamic_state; diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 7687507e6b7..5d7c9b51a84 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -30,6 +30,7 @@ #include "util/fast_idiv_by_const.h" #include "common/gen_l3_config.h" +#include "common/gen_sample_positions.h" #include "genxml/gen_macros.h" #include "genxml/genX_pack.h" @@ -2638,6 +2639,24 @@ cmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer, cmd_buffer->state.push_constants_dirty &= ~flushed; } +static void +cmd_buffer_emit_sample_locations(struct anv_cmd_buffer *cmd_buffer) +{ +#if GEN_GEN >= 8 + struct anv_dynamic_state *dyn_state = &cmd_buffer->state.gfx.dynamic; + uint32_t samples = dyn_state->sample_locations.num_samples; + uint32_t log2_samples; + + assert(samples > 0); + log2_samples = __builtin_ffs(samples) - 1; + + genX(emit_multisample)(&cmd_buffer->batch, samples, log2_samples); + genX(emit_sample_locations)(&cmd_buffer->batch, + dyn_state->sample_locations.positions, + samples, true); +#endif +} + void genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer) { @@ -2796,6 +2815,11 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer) ANV_CMD_DIRTY_RENDER_TARGETS)) gen7_cmd_buffer_emit_scissor(cmd_buffer); + if (cmd_buffer->state.gfx.dynamic.sample_locations.valid) { + cmd_buffer_emit_sample_locations(cmd_buffer); + cmd_buffer->state.gfx.dynamic.sample_locations.valid = false; + } + genX(cmd_buffer_flush_dynamic_state)(cmd_buffer); genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer); diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c index 07b45db1988..ada022620d1 100644 --- a/src/intel/vulkan/genX_pipeline.c +++ b/src/intel/vulkan/genX_pipeline.c @@ -571,44 +571,6 @@ emit_sample_mask(struct anv_pipeline *pipeline, } } -static void -emit_multisample(struct anv_pipeline *pipeline, - uint32_t samples, - uint32_t log2_samples) -{ - anv_batch_emit(&pipeline->batch, GENX(3DSTATE_MULTISAMPLE), ms) { - ms.NumberofMultisamples = log2_samples; - - ms.PixelLocation = CENTER; -#if GEN_GEN >= 8 - /* The PRM says that this bit is valid only for DX9: - * - * SW can choose to set this bit only for DX9 API. DX10/OGL API's - * should not have any effect by setting or not setting this bit. - */ - ms.PixelPositionOffsetEnable = false; -#else - - switch (samples) { - case 1: - GEN_SAMPLE_POS_1X(ms.Sample); - break; - case 2: - GEN_SAMPLE_POS_2X(ms.Sample); - break; - case 4: - GEN_SAMPLE_POS_4X(ms.Sample); - break; - case 8: - GEN_SAMPLE_POS_8X(ms.Sample); - break; - default: - break; - } -#endif - } -} - static void emit_ms_state(struct anv_pipeline *pipeline, const VkPipelineMultisampleStateCreateInfo *info, @@ -656,7 +618,7 @@ emit_ms_state(struct anv_pipeline *pipeline, log2_samples = __builtin_ffs(samples) - 1; } - emit_multisample(pipeline, samples, log2_samples); + genX(emit_multisample(&pipeline->batch, samples, log2_samples)); #if GEN_GEN >= 8 genX(emit_sample_locations)(&pipeline->batch, sl->pSampleLocations, diff --git a/src/intel/vulkan/genX_state.c b/src/intel/vulkan/genX_state.c index 3f628710b31..4fdb74111a5 100644 --- a/src/intel/vulkan/genX_state.c +++ b/src/intel/vulkan/genX_state.c @@ -436,6 +436,42 @@ VkResult genX(CreateSampler)( return VK_SUCCESS; } +void +genX(emit_multisample)(struct anv_batch *batch, + uint32_t samples, + uint32_t log2_samples) +{ + anv_batch_emit(batch, GENX(3DSTATE_MULTISAMPLE), ms) { + ms.NumberofMultisamples = log2_samples; + ms.PixelLocation = CENTER; +#if GEN_GEN >= 8 + /* The PRM says that this bit is valid only for DX9: + * + * SW can choose to set this bit only for DX9 API. DX10/OGL API's + * should not have any effect by setting or not setting this bit. + */ + ms.PixelPositionOffsetEnable = false; +#else + switch (samples) { + case 1: + GEN_SAMPLE_POS_1X(ms.Sample); + break; + case 2: + GEN_SAMPLE_POS_2X(ms.Sample); + break; + case 4: + GEN_SAMPLE_POS_4X(ms.Sample); + break; + case 8: + GEN_SAMPLE_POS_8X(ms.Sample); + break; + default: + break; + } +#endif + } +} + void genX(emit_sample_locations)(struct anv_batch *batch, const VkSampleLocationEXT *sl, -- 2.20.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev