diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index 2cd579410f7..8ef04677601 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -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) { diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c index 8b766a00c63..cf9f17f2962 100644 --- a/src/intel/vulkan/anv_pipeline.c +++ b/src/intel/vulkan/anv_pipeline.c @@ -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) { diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index e65764b858e..477d5db7d95 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -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 diff --git a/src/intel/vulkan/genX_state.c b/src/intel/vulkan/genX_state.c index 85b7c48a62e..2a3c3732dcf 100644 --- a/src/intel/vulkan/genX_state.c +++ b/src/intel/vulkan/genX_state.c @@ -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"); + } } } } diff --git a/src/intel/vulkan/gfx7_cmd_buffer.c b/src/intel/vulkan/gfx7_cmd_buffer.c index b59b54407a8..eb7dfe70870 100644 --- a/src/intel/vulkan/gfx7_cmd_buffer.c +++ b/src/intel/vulkan/gfx7_cmd_buffer.c @@ -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 |