anv: Stop recording sample locations per-sample-count

The only reason why we recorded them per-sample-count is because Intel
hardware is weird starting with Broadwell.  The API, requires that the
dynamic sample pattern be reset every time the sample count changes so
we only need to record the pattern for the current sample count.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17564>
This commit is contained in:
Jason Ekstrand 2022-07-12 16:30:46 -05:00 committed by Marge Bot
parent 36417bd05b
commit 18868f1c76
5 changed files with 67 additions and 85 deletions

View File

@ -110,17 +110,6 @@ void
anv_dynamic_state_init(struct anv_dynamic_state *state)
{
*state = default_dynamic_state;
#define INIT_LOCATIONS(idx) \
memcpy(state->sample_locations.locations_##idx, \
intel_sample_positions_##idx##x, \
sizeof(state->sample_locations.locations_##idx))
INIT_LOCATIONS(1);
INIT_LOCATIONS(2);
INIT_LOCATIONS(4);
INIT_LOCATIONS(8);
INIT_LOCATIONS(16);
#undef INIT_LOCATIONS
}
/**
@ -214,26 +203,17 @@ anv_dynamic_state_copy(struct anv_dynamic_state *dest,
ANV_CMP_COPY(logic_op, ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP);
if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS) {
#define ANV_CMP_COPY_LOCATIONS(idx) \
if (memcmp(dest->sample_locations.locations_##idx, \
src->sample_locations.locations_##idx, \
sizeof(src->sample_locations.locations_##idx))) { \
typed_memcpy(dest->sample_locations.locations_##idx, \
src->sample_locations.locations_##idx, \
ARRAY_SIZE(src->sample_locations.locations_##idx)); \
changed |= ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS; \
ANV_CMP_COPY(sample_locations.samples,
ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS);
if (memcmp(dest->sample_locations.locations,
src->sample_locations.locations,
src->sample_locations.samples *
sizeof(*src->sample_locations.locations))) {
typed_memcpy(dest->sample_locations.locations,
src->sample_locations.locations,
src->sample_locations.samples);
changed |= ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS;
}
switch (src->sample_locations.pipeline_samples) {
case 1: ANV_CMP_COPY_LOCATIONS(1); break;
case 2: ANV_CMP_COPY_LOCATIONS(2); break;
case 4: ANV_CMP_COPY_LOCATIONS(4); break;
case 8: ANV_CMP_COPY_LOCATIONS(8); break;
case 16: ANV_CMP_COPY_LOCATIONS(16); break;
default: unreachable("invalid sample count");
}
#undef ANV_CMP_COPY_LOCATIONS
}
ANV_CMP_COPY(color_writes, ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE);
@ -888,7 +868,13 @@ void anv_CmdSetSampleLocationsEXT(
struct anv_dynamic_state *dyn_state = &cmd_buffer->state.gfx.dynamic;
uint32_t samples = pSampleLocationsInfo->sampleLocationsPerPixel;
struct intel_sample_position *positions =
anv_dynamic_state_get_sample_locations(dyn_state, samples);
dyn_state->sample_locations.locations;
if (dyn_state->sample_locations.samples != samples) {
dyn_state->sample_locations.samples = samples;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS;
}
for (uint32_t i = 0; i < samples; i++) {
if (positions[i].x != pSampleLocationsInfo->pSampleLocations[i].x ||
positions[i].y != pSampleLocationsInfo->pSampleLocations[i].y) {

View File

@ -2285,34 +2285,23 @@ copy_non_dynamic_state(struct anv_graphics_pipeline *pipeline,
if (states & ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS) {
const VkPipelineSampleLocationsStateCreateInfoEXT *sl_info = ms_info ?
vk_find_struct_const(ms_info, PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT) : NULL;
uint32_t samples = MAX2(1, ms_info ? ms_info->rasterizationSamples : 1);
struct intel_sample_position *locations;
switch (samples) {
case 1: locations = dynamic->sample_locations.locations_1; break;
case 2: locations = dynamic->sample_locations.locations_2; break;
case 4: locations = dynamic->sample_locations.locations_4; break;
case 8: locations = dynamic->sample_locations.locations_8; break;
case 16: locations = dynamic->sample_locations.locations_16; break;
default: unreachable("invalid sample count");
}
if (sl_info && sl_info->sampleLocationsEnable) {
const VkSampleLocationEXT *positions =
sl_info->sampleLocationsInfo.pSampleLocations;
for (uint32_t i = 0; i < samples; i++) {
locations[i].x = positions[i].x;
locations[i].y = positions[i].y;
dynamic->sample_locations.locations[i].x = positions[i].x;
dynamic->sample_locations.locations[i].y = positions[i].y;
}
} else {
const struct intel_sample_position *positions =
intel_get_sample_positions(samples);
for (uint32_t i = 0; i < samples; i++) {
locations[i].x = positions[i].x;
locations[i].y = positions[i].y;
dynamic->sample_locations.locations[i].x = positions[i].x;
dynamic->sample_locations.locations[i].y = positions[i].y;
}
}
dynamic->sample_locations.pipeline_samples = samples;
dynamic->sample_locations.samples = samples;
}
if (states & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE) {

View File

@ -2700,13 +2700,8 @@ struct anv_dynamic_state {
} line_stipple;
struct {
struct intel_sample_position locations_1[1];
struct intel_sample_position locations_2[2];
struct intel_sample_position locations_4[4];
struct intel_sample_position locations_8[8];
struct intel_sample_position locations_16[16];
/* Only valid on the pipeline dynamic state */
unsigned pipeline_samples;
struct intel_sample_position locations[16];
unsigned samples;
} sample_locations;
struct {
@ -2739,20 +2734,6 @@ anv_cmd_dirty_mask_t anv_dynamic_state_copy(struct anv_dynamic_state *dest,
const struct anv_dynamic_state *src,
anv_cmd_dirty_mask_t copy_mask);
static inline struct intel_sample_position *
anv_dynamic_state_get_sample_locations(struct anv_dynamic_state *state,
unsigned samples)
{
switch (samples) {
case 1: return state->sample_locations.locations_1; break;
case 2: return state->sample_locations.locations_2; break;
case 4: return state->sample_locations.locations_4; break;
case 8: return state->sample_locations.locations_8; break;
case 16: return state->sample_locations.locations_16; break;
default: unreachable("invalid sample count");
}
}
struct anv_surface_state {
struct anv_state state;
/** Address of the surface referred to by this state

View File

@ -746,22 +746,48 @@ genX(emit_sample_pattern)(struct anv_batch *batch,
* 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.
*/
if (d) {
INTEL_SAMPLE_POS_1X_ARRAY(sp._1xSample, d->sample_locations.locations_1);
INTEL_SAMPLE_POS_2X_ARRAY(sp._2xSample, d->sample_locations.locations_2);
INTEL_SAMPLE_POS_4X_ARRAY(sp._4xSample, d->sample_locations.locations_4);
INTEL_SAMPLE_POS_8X_ARRAY(sp._8xSample, d->sample_locations.locations_8);
for (uint32_t i = 1; i <= (GFX_VER >= 9 ? 16 : 8); i *= 2) {
switch (i) {
case VK_SAMPLE_COUNT_1_BIT:
if (d && d->sample_locations.samples == i) {
INTEL_SAMPLE_POS_1X_ARRAY(sp._1xSample, d->sample_locations.locations);
} else {
INTEL_SAMPLE_POS_1X(sp._1xSample);
}
break;
case VK_SAMPLE_COUNT_2_BIT:
if (d && d->sample_locations.samples == i) {
INTEL_SAMPLE_POS_2X_ARRAY(sp._2xSample, d->sample_locations.locations);
} else {
INTEL_SAMPLE_POS_2X(sp._2xSample);
}
break;
case VK_SAMPLE_COUNT_4_BIT:
if (d && d->sample_locations.samples == i) {
INTEL_SAMPLE_POS_4X_ARRAY(sp._4xSample, d->sample_locations.locations);
} else {
INTEL_SAMPLE_POS_4X(sp._4xSample);
}
break;
case VK_SAMPLE_COUNT_8_BIT:
if (d && d->sample_locations.samples == i) {
INTEL_SAMPLE_POS_8X_ARRAY(sp._8xSample, d->sample_locations.locations);
} else {
INTEL_SAMPLE_POS_8X(sp._8xSample);
}
break;
#if GFX_VER >= 9
INTEL_SAMPLE_POS_16X_ARRAY(sp._16xSample, d->sample_locations.locations_16);
#endif
} else {
INTEL_SAMPLE_POS_1X(sp._1xSample);
INTEL_SAMPLE_POS_2X(sp._2xSample);
INTEL_SAMPLE_POS_4X(sp._4xSample);
INTEL_SAMPLE_POS_8X(sp._8xSample);
#if GFX_VER >= 9
INTEL_SAMPLE_POS_16X(sp._16xSample);
case VK_SAMPLE_COUNT_16_BIT:
if (d && d->sample_locations.samples == i) {
INTEL_SAMPLE_POS_16X_ARRAY(sp._16xSample, d->sample_locations.locations);
} else {
INTEL_SAMPLE_POS_16X(sp._16xSample);
}
break;
#endif
default:
unreachable("Invalid sample count");
}
}
}
}

View File

@ -257,10 +257,10 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS)) {
assert(d->sample_locations.samples == pipeline->rasterization_samples);
genX(emit_multisample)(&cmd_buffer->batch,
pipeline->rasterization_samples,
anv_dynamic_state_get_sample_locations(d,
pipeline->rasterization_samples));
d->sample_locations.samples,
d->sample_locations.locations);
}
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |