From: Eleni Maria Stea <es...@igalia.com> This commit adds a "locations" parameter to emit_multisample and emit_sample_pattern which, if provided, will override the default sample locations. --- src/intel/common/gen_sample_positions.h | 57 +++++++++++++ src/intel/vulkan/anv_genX.h | 6 +- src/intel/vulkan/genX_pipeline.c | 2 +- src/intel/vulkan/genX_state.c | 109 +++++++++++++++++++----- 4 files changed, 148 insertions(+), 26 deletions(-)
diff --git a/src/intel/common/gen_sample_positions.h b/src/intel/common/gen_sample_positions.h index da48dcb5ed0..850661931cf 100644 --- a/src/intel/common/gen_sample_positions.h +++ b/src/intel/common/gen_sample_positions.h @@ -160,4 +160,61 @@ prefix##14YOffset = 0.9375; \ prefix##15XOffset = 0.0625; \ prefix##15YOffset = 0.0000; +/* Examples: + * in case of GEN_GEN < 8: + * GEN_SAMPLE_POS_ELEM(ms.Sample, info->pSampleLocations, 0); expands to: + * ms.Sample0XOffset = info->pSampleLocations[0].pos.x; + * ms.Sample0YOffset = info->pSampleLocations[0].y; + * + * in case of GEN_GEN >= 8: + * GEN_SAMPLE_POS_ELEM(sp._16xSample, info->pSampleLocations, 0); expands to: + * sp._16xSample0XOffset = info->pSampleLocations[0].x; + * sp._16xSample0YOffset = info->pSampleLocations[0].y; + */ + +#define GEN_SAMPLE_POS_ELEM(prefix, arr, sample_idx) \ +prefix##sample_idx##XOffset = arr[sample_idx].x; \ +prefix##sample_idx##YOffset = arr[sample_idx].y; + +#define GEN_SAMPLE_POS_1X_ARRAY(prefix, arr)\ +GEN_SAMPLE_POS_ELEM(prefix, arr, 0); + +#define GEN_SAMPLE_POS_2X_ARRAY(prefix, arr) \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 0); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 1); + +#define GEN_SAMPLE_POS_4X_ARRAY(prefix, arr) \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 0); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 1); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 2); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 3); + +#define GEN_SAMPLE_POS_8X_ARRAY(prefix, arr) \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 0); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 1); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 2); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 3); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 4); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 5); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 6); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 7); + +#define GEN_SAMPLE_POS_16X_ARRAY(prefix, arr) \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 0); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 1); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 2); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 3); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 4); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 5); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 6); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 7); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 8); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 9); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 10); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 11); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 12); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 13); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 14); \ +GEN_SAMPLE_POS_ELEM(prefix, arr, 15); + #endif /* GEN_SAMPLE_POSITIONS_H */ diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h index 55226179124..608954d1a2c 100644 --- a/src/intel/vulkan/anv_genX.h +++ b/src/intel/vulkan/anv_genX.h @@ -74,9 +74,11 @@ genX(emit_urb_setup)(struct anv_device *device, struct anv_batch *batch, VkShaderStageFlags active_stages, const unsigned entry_size[4]); -void genX(emit_multisample)(struct anv_batch *batch, uint32_t samples); +void genX(emit_multisample)(struct anv_batch *batch, uint32_t samples, + const VkSampleLocationEXT *locations); -void genX(emit_sample_pattern)(struct anv_batch *batch); +void genX(emit_sample_pattern)(struct anv_batch *batch, uint32_t samples, + const VkSampleLocationEXT *locations); void genX(cmd_buffer_so_memcpy)(struct anv_cmd_buffer *cmd_buffer, struct anv_address dst, struct anv_address src, diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c index 7eb05333dad..430b095c5b1 100644 --- a/src/intel/vulkan/genX_pipeline.c +++ b/src/intel/vulkan/genX_pipeline.c @@ -553,7 +553,7 @@ emit_ms_state(struct anv_pipeline *pipeline, { uint32_t samples = info ? info->rasterizationSamples : 1; - genX(emit_multisample)(&pipeline->batch, samples); + genX(emit_multisample)(&pipeline->batch, samples, NULL); anv_batch_emit(&pipeline->batch, GENX(3DSTATE_SAMPLE_MASK), sm) { /* From the Vulkan 1.0 spec: diff --git a/src/intel/vulkan/genX_state.c b/src/intel/vulkan/genX_state.c index cc066e68f2c..4054f9c6024 100644 --- a/src/intel/vulkan/genX_state.c +++ b/src/intel/vulkan/genX_state.c @@ -139,7 +139,7 @@ genX(init_device_state)(struct anv_device *device) #if GEN_GEN >= 8 anv_batch_emit(&batch, GENX(3DSTATE_WM_CHROMAKEY), ck); - genX(emit_sample_pattern)(&batch); + genX(emit_sample_pattern)(&batch, 0, NULL); /* The BDW+ docs describe how to use the 3DSTATE_WM_HZ_OP instruction in the * section titled, "Optimized Depth Buffer Clear and/or Stencil Buffer @@ -218,7 +218,8 @@ genX(init_device_state)(struct anv_device *device) } void -genX(emit_multisample)(struct anv_batch *batch, uint32_t samples) +genX(emit_multisample)(struct anv_batch *batch, uint32_t samples, + const VkSampleLocationEXT *locations) { anv_batch_emit(batch, GENX(3DSTATE_MULTISAMPLE), ms) { ms.NumberofMultisamples = __builtin_ffs(samples) - 1; @@ -233,21 +234,40 @@ genX(emit_multisample)(struct anv_batch *batch, uint32_t samples) 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; + if (locations) { + switch (samples) { + case 1: + GEN_SAMPLE_POS_1X_ARRAY(ms.Sample, locations); + break; + case 2: + GEN_SAMPLE_POS_2X_ARRAY(ms.Sample, locations); + break; + case 4: + GEN_SAMPLE_POS_4X_ARRAY(ms.Sample, locations); + break; + case 8: + GEN_SAMPLE_POS_8X_ARRAY(ms.Sample, locations); + break; + default: + break; + } + } 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 } @@ -255,7 +275,8 @@ genX(emit_multisample)(struct anv_batch *batch, uint32_t samples) #if GEN_GEN >= 8 void -genX(emit_sample_pattern)(struct anv_batch *batch) +genX(emit_sample_pattern)(struct anv_batch *batch, uint32_t samples, + const VkSampleLocationEXT *locations) { #if GEN_GEN == 10 gen10_emit_wa_cs_stall_flush(batch); @@ -265,13 +286,55 @@ genX(emit_sample_pattern)(struct anv_batch *batch) * VkPhysicalDeviceFeatures::standardSampleLocations. */ anv_batch_emit(batch, GENX(3DSTATE_SAMPLE_PATTERN), sp) { - GEN_SAMPLE_POS_1X(sp._1xSample); - GEN_SAMPLE_POS_2X(sp._2xSample); - GEN_SAMPLE_POS_4X(sp._4xSample); - GEN_SAMPLE_POS_8X(sp._8xSample); + if (locations) { + /* The Skylake PRM Vol. 2a "3DSTATE_SAMPLE_PATTERN" says: + * + * "When programming the sample offsets (for NUMSAMPLES_4 or _8 + * and MSRASTMODE_xxx_PATTERN), the order of the samples 0 to 3 + * (or 7 for 8X, or 15 for 16X) must have monotonically increasing + * distance from the pixel center. This is required to get the + * correct centroid computation in the device." + * + * However, the Vulkan spec seems to require that the the samples + * occur in the order provided through the API. The standard sample + * patterns have the above property that they have monotonically + * increasing distances from the center but client-provided ones do + * not. As long as this only affects centroid calculations as the + * docs say, we should be ok because OpenGL and Vulkan only require + * that the centroid be some lit sample and that it's the same for + * all samples in a pixel; they have no requirement that it be the + * one closest to center. + */ + switch (samples) { + case 1: + GEN_SAMPLE_POS_1X_ARRAY(sp._1xSample, locations); + break; + case 2: + GEN_SAMPLE_POS_2X_ARRAY(sp._2xSample, locations); + break; + case 4: + GEN_SAMPLE_POS_4X_ARRAY(sp._4xSample, locations); + break; + case 8: + GEN_SAMPLE_POS_8X_ARRAY(sp._8xSample, locations); + break; +#if GEN_GEN >= 9 + case 16: + GEN_SAMPLE_POS_16X_ARRAY(sp._16xSample, locations); + break; +#endif + default: + break; + } + } else { + GEN_SAMPLE_POS_1X(sp._1xSample); + GEN_SAMPLE_POS_2X(sp._2xSample); + GEN_SAMPLE_POS_4X(sp._4xSample); + GEN_SAMPLE_POS_8X(sp._8xSample); #if GEN_GEN >= 9 - GEN_SAMPLE_POS_16X(sp._16xSample); + GEN_SAMPLE_POS_16X(sp._16xSample); #endif + } } #if GEN_GEN == 10 -- 2.20.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev