[Mesa-dev] [PATCH v4 5/9] anv: Added support for dynamic sample locations on Gen8+
Eleni Maria Stea
estea at igalia.com
Thu Mar 14 19:52:03 UTC 2019
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
More information about the mesa-dev
mailing list