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. --- src/intel/vulkan/anv_cmd_buffer.c | 19 ++++++++++++ src/intel/vulkan/anv_genX.h | 6 +++- src/intel/vulkan/anv_private.h | 6 ++++ src/intel/vulkan/genX_cmd_buffer.c | 27 ++++++++++++++++++ src/intel/vulkan/genX_pipeline.c | 46 ++++-------------------------- src/intel/vulkan/genX_state.c | 41 +++++++++++++++++++++++--- 6 files changed, 99 insertions(+), 46 deletions(-) diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index 1b34644a434..101c1375430 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -28,6 +28,7 @@ #include <fcntl.h> #include "anv_private.h" +#include "anv_sample_locations.h" #include "vk_format_info.h" #include "vk_util.h" @@ -558,6 +559,24 @@ 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); + assert(pSampleLocationsInfo); + + struct anv_dynamic_state *dyn_state = &cmd_buffer->state.gfx.dynamic; + dyn_state->sample_locations.num_samples = + pSampleLocationsInfo->sampleLocationsPerPixel; + + anv_calc_sample_locations(dyn_state->sample_locations.anv_samples, + dyn_state->sample_locations.num_samples, + pSampleLocationsInfo); + + cmd_buffer->state.gfx.dynamic.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 52415c04a45..f84fe457152 100644 --- a/src/intel/vulkan/anv_genX.h +++ b/src/intel/vulkan/anv_genX.h @@ -89,7 +89,11 @@ 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 struct anv_sample *anv_samples, uint32_t num_samples, - const VkSampleLocationsInfoEXT *sl, bool custom_locations); diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 981956e5706..a2e1756cd99 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2135,6 +2135,12 @@ struct anv_dynamic_state { uint32_t front; uint32_t back; } stencil_reference; + + struct { + struct anv_sample anv_samples[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..9229df84caa 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -25,11 +25,13 @@ #include <stdbool.h> #include "anv_private.h" +#include "anv_sample_locations.h" #include "vk_format_info.h" #include "vk_util.h" #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 +2640,26 @@ 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 + const struct anv_sample *anv_samples; + uint32_t log2_samples; + uint32_t samples; + + samples = cmd_buffer->state.gfx.dynamic.sample_locations.num_samples; + assert(samples > 0); + + log2_samples = __builtin_ffs(samples) - 1; + anv_samples = cmd_buffer->state.gfx.dynamic.sample_locations.anv_samples; + + genX(emit_multisample)(&cmd_buffer->batch, samples, log2_samples); + genX(emit_sample_locations)(&cmd_buffer->batch, anv_samples, samples, + true); +#endif +} + void genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer) { @@ -2796,6 +2818,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 feb431e10cd..fa42e622077 100644 --- a/src/intel/vulkan/genX_pipeline.c +++ b/src/intel/vulkan/genX_pipeline.c @@ -572,52 +572,15 @@ 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, const VkPipelineDynamicStateCreateInfo *dinfo) { #if GEN_GEN >= 8 - bool custom_locations = false; + struct anv_sample anv_samples[MAX_SAMPLE_LOCATIONS]; VkSampleLocationsInfoEXT *sl; + bool custom_locations = false; #endif uint32_t samples = 1; @@ -649,6 +612,7 @@ emit_ms_state(struct anv_pipeline *pipeline, samples = sl->sampleLocationsPerPixel; custom_locations = true; + anv_calc_sample_locations(anv_samples, samples, sl); } } } @@ -657,10 +621,10 @@ 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, samples, sl, + genX(emit_sample_locations)(&pipeline->batch, anv_samples, samples, custom_locations); #endif } diff --git a/src/intel/vulkan/genX_state.c b/src/intel/vulkan/genX_state.c index c14e502a68d..44cfc925ed5 100644 --- a/src/intel/vulkan/genX_state.c +++ b/src/intel/vulkan/genX_state.c @@ -437,22 +437,55 @@ 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 struct anv_sample *anv_samples, uint32_t num_samples, - const VkSampleLocationsInfoEXT *sl, bool custom_locations) { #if GEN_GEN >= 8 - struct anv_sample anv_samples[MAX_SAMPLE_LOCATIONS]; #if GEN_GEN == 10 gen10_emit_wa_cs_stall_flush(batch); #endif if (custom_locations) { - anv_calc_sample_locations(anv_samples, num_samples, sl); - anv_batch_emit(batch, GENX(3DSTATE_SAMPLE_PATTERN), sp) { switch (num_samples) { case 1: -- 2.20.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev