anv: Switch to using common dynamic state tracking

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-14 15:09:46 -05:00 committed by Marge Bot
parent cc89232f2e
commit 7d25c04236
11 changed files with 367 additions and 1361 deletions

View File

@ -41,193 +41,6 @@
* is concerned, most of anv_cmd_buffer is magic.
*/
/* TODO: These are taken from GLES. We should check the Vulkan spec */
const struct anv_dynamic_state default_dynamic_state = {
.viewport = {
.count = 0,
},
.scissor = {
.count = 0,
},
.line_width = 1.0f,
.depth_bias = {
.bias = 0.0f,
.clamp = 0.0f,
.slope = 0.0f,
},
.blend_constants = { 0.0f, 0.0f, 0.0f, 0.0f },
.depth_bounds = {
.min = 0.0f,
.max = 1.0f,
},
.stencil_compare_mask = {
.front = ~0u,
.back = ~0u,
},
.stencil_write_mask = {
.front = ~0u,
.back = ~0u,
},
.stencil_reference = {
.front = 0u,
.back = 0u,
},
.stencil_op = {
.front = {
.fail_op = 0,
.pass_op = 0,
.depth_fail_op = 0,
.compare_op = 0,
},
.back = {
.fail_op = 0,
.pass_op = 0,
.depth_fail_op = 0,
.compare_op = 0,
},
},
.line_stipple = {
.factor = 0u,
.pattern = 0u,
},
.cull_mode = 0,
.front_face = 0,
.primitive_topology = 0,
.depth_test_enable = 0,
.depth_write_enable = 0,
.depth_compare_op = 0,
.depth_bounds_test_enable = 0,
.stencil_test_enable = 0,
.dyn_vbo_stride = 0,
.color_writes = 0xff,
.raster_discard = 0,
.depth_bias_enable = 0,
.primitive_restart_enable = 0,
.logic_op = 0,
};
void
anv_dynamic_state_init(struct anv_dynamic_state *state)
{
*state = default_dynamic_state;
}
/**
* Copy the dynamic state from src to dest based on the copy_mask.
*
* Avoid copying states that have not changed, except for VIEWPORT, SCISSOR and
* BLEND_CONSTANTS (always copy them if they are in the copy_mask).
*
* Returns a mask of the states which changed.
*/
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)
{
anv_cmd_dirty_mask_t changed = 0;
if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT) {
dest->viewport.count = src->viewport.count;
typed_memcpy(dest->viewport.viewports, src->viewport.viewports,
src->viewport.count);
changed |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
}
if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_SCISSOR) {
dest->scissor.count = src->scissor.count;
typed_memcpy(dest->scissor.scissors, src->scissor.scissors,
src->scissor.count);
changed |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
}
if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS) {
typed_memcpy(dest->blend_constants, src->blend_constants, 4);
changed |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
}
#define ANV_CMP_COPY(field, flag) \
if (copy_mask & flag) { \
if (dest->field != src->field) { \
dest->field = src->field; \
changed |= flag; \
} \
}
ANV_CMP_COPY(line_width, ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH);
ANV_CMP_COPY(depth_bias.bias, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);
ANV_CMP_COPY(depth_bias.clamp, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);
ANV_CMP_COPY(depth_bias.slope, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);
ANV_CMP_COPY(depth_bounds.min, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS);
ANV_CMP_COPY(depth_bounds.max, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS);
ANV_CMP_COPY(stencil_compare_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK);
ANV_CMP_COPY(stencil_compare_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK);
ANV_CMP_COPY(stencil_write_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK);
ANV_CMP_COPY(stencil_write_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK);
ANV_CMP_COPY(stencil_reference.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE);
ANV_CMP_COPY(stencil_reference.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE);
ANV_CMP_COPY(line_stipple.factor, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE);
ANV_CMP_COPY(line_stipple.pattern, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE);
ANV_CMP_COPY(cull_mode, ANV_CMD_DIRTY_DYNAMIC_CULL_MODE);
ANV_CMP_COPY(front_face, ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE);
ANV_CMP_COPY(primitive_topology, ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY);
ANV_CMP_COPY(depth_test_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE);
ANV_CMP_COPY(depth_write_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE);
ANV_CMP_COPY(depth_compare_op, ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP);
ANV_CMP_COPY(depth_bounds_test_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE);
ANV_CMP_COPY(stencil_test_enable, ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE);
if (copy_mask & VK_DYNAMIC_STATE_STENCIL_OP) {
ANV_CMP_COPY(stencil_op.front.fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
ANV_CMP_COPY(stencil_op.front.pass_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
ANV_CMP_COPY(stencil_op.front.depth_fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
ANV_CMP_COPY(stencil_op.front.compare_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
ANV_CMP_COPY(stencil_op.back.fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
ANV_CMP_COPY(stencil_op.back.pass_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
ANV_CMP_COPY(stencil_op.back.depth_fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
ANV_CMP_COPY(stencil_op.back.compare_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
}
ANV_CMP_COPY(dyn_vbo_stride, ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE);
ANV_CMP_COPY(raster_discard, ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE);
ANV_CMP_COPY(depth_bias_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE);
ANV_CMP_COPY(primitive_restart_enable, ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE);
ANV_CMP_COPY(logic_op, ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP);
if (copy_mask & 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;
}
}
ANV_CMP_COPY(color_writes, ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE);
ANV_CMP_COPY(fragment_shading_rate.rate.width, ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE);
ANV_CMP_COPY(fragment_shading_rate.rate.height, ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE);
ANV_CMP_COPY(fragment_shading_rate.ops[0], ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE);
ANV_CMP_COPY(fragment_shading_rate.ops[1], ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE);
#undef ANV_CMP_COPY
return changed;
}
static void
anv_cmd_state_init(struct anv_cmd_buffer *cmd_buffer)
{
@ -236,9 +49,8 @@ anv_cmd_state_init(struct anv_cmd_buffer *cmd_buffer)
memset(state, 0, sizeof(*state));
state->current_pipeline = UINT32_MAX;
anv_dynamic_state_init(&state->gfx.dynamic);
state->gfx.restart_index = UINT32_MAX;
state->gfx.dirty = ANV_CMD_DIRTY_DYNAMIC_ALL;
state->gfx.dirty = 0;
}
static void
@ -291,6 +103,9 @@ static VkResult anv_create_cmd_buffer(
goto fail_alloc;
cmd_buffer->vk.destroy = anv_cmd_buffer_destroy;
cmd_buffer->vk.dynamic_graphics_state.ms.sample_locations =
&cmd_buffer->state.gfx.sample_locations;
cmd_buffer->batch.status = VK_SUCCESS;
cmd_buffer->device = device;
@ -598,10 +413,8 @@ void anv_CmdBindPipeline(
}
/* Apply the non dynamic state from the pipeline */
cmd_buffer->state.gfx.dirty |=
anv_dynamic_state_copy(&cmd_buffer->state.gfx.dynamic,
&gfx_pipeline->non_dynamic_state,
gfx_pipeline->non_dynamic_state_mask);
vk_cmd_set_dynamic_graphics_state(&cmd_buffer->vk,
&gfx_pipeline->dynamic_state);
state = &cmd_buffer->state.gfx.base;
stages = gfx_pipeline->active_stages;
@ -635,374 +448,6 @@ void anv_CmdBindPipeline(
anv_cmd_buffer_set_ray_query_buffer(cmd_buffer, state, pipeline, stages);
}
void anv_CmdSetRasterizerDiscardEnable(
VkCommandBuffer commandBuffer,
VkBool32 rasterizerDiscardEnable)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.raster_discard = rasterizerDiscardEnable;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE;
}
void anv_CmdSetDepthBiasEnable(
VkCommandBuffer commandBuffer,
VkBool32 depthBiasEnable)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.depth_bias_enable = depthBiasEnable;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE;
}
void anv_CmdSetPrimitiveRestartEnable(
VkCommandBuffer commandBuffer,
VkBool32 primitiveRestartEnable)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.primitive_restart_enable = primitiveRestartEnable;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
}
void anv_CmdSetLogicOpEXT(
VkCommandBuffer commandBuffer,
VkLogicOp logicOp)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.logic_op = logicOp;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP;
}
void anv_CmdSetPatchControlPointsEXT(
VkCommandBuffer commandBuffer,
uint32_t patchControlPoints)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_FEATURE_NOT_PRESENT);
}
void anv_CmdSetViewport(
VkCommandBuffer commandBuffer,
uint32_t firstViewport,
uint32_t viewportCount,
const VkViewport* pViewports)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
const uint32_t total_count = firstViewport + viewportCount;
if (cmd_buffer->state.gfx.dynamic.viewport.count < total_count)
cmd_buffer->state.gfx.dynamic.viewport.count = total_count;
memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports + firstViewport,
pViewports, viewportCount * sizeof(*pViewports));
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
}
void anv_CmdSetViewportWithCount(
VkCommandBuffer commandBuffer,
uint32_t viewportCount,
const VkViewport* pViewports)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.viewport.count = viewportCount;
memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports,
pViewports, viewportCount * sizeof(*pViewports));
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
}
void anv_CmdSetScissor(
VkCommandBuffer commandBuffer,
uint32_t firstScissor,
uint32_t scissorCount,
const VkRect2D* pScissors)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
const uint32_t total_count = firstScissor + scissorCount;
if (cmd_buffer->state.gfx.dynamic.scissor.count < total_count)
cmd_buffer->state.gfx.dynamic.scissor.count = total_count;
memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors + firstScissor,
pScissors, scissorCount * sizeof(*pScissors));
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
}
void anv_CmdSetScissorWithCount(
VkCommandBuffer commandBuffer,
uint32_t scissorCount,
const VkRect2D* pScissors)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.scissor.count = scissorCount;
memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors,
pScissors, scissorCount * sizeof(*pScissors));
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
}
void anv_CmdSetPrimitiveTopology(
VkCommandBuffer commandBuffer,
VkPrimitiveTopology primitiveTopology)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.primitive_topology = primitiveTopology;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY;
}
void anv_CmdSetLineWidth(
VkCommandBuffer commandBuffer,
float lineWidth)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.line_width = lineWidth;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH;
}
void anv_CmdSetDepthBias(
VkCommandBuffer commandBuffer,
float depthBiasConstantFactor,
float depthBiasClamp,
float depthBiasSlopeFactor)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.depth_bias.bias = depthBiasConstantFactor;
cmd_buffer->state.gfx.dynamic.depth_bias.clamp = depthBiasClamp;
cmd_buffer->state.gfx.dynamic.depth_bias.slope = depthBiasSlopeFactor;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
}
void anv_CmdSetBlendConstants(
VkCommandBuffer commandBuffer,
const float blendConstants[4])
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
memcpy(cmd_buffer->state.gfx.dynamic.blend_constants,
blendConstants, sizeof(float) * 4);
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
}
void anv_CmdSetDepthBounds(
VkCommandBuffer commandBuffer,
float minDepthBounds,
float maxDepthBounds)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.depth_bounds.min = minDepthBounds;
cmd_buffer->state.gfx.dynamic.depth_bounds.max = maxDepthBounds;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS;
}
void anv_CmdSetStencilCompareMask(
VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t compareMask)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
cmd_buffer->state.gfx.dynamic.stencil_compare_mask.front = compareMask;
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
cmd_buffer->state.gfx.dynamic.stencil_compare_mask.back = compareMask;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK;
}
void anv_CmdSetStencilWriteMask(
VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t writeMask)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
cmd_buffer->state.gfx.dynamic.stencil_write_mask.front = writeMask;
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
cmd_buffer->state.gfx.dynamic.stencil_write_mask.back = writeMask;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK;
}
void anv_CmdSetStencilReference(
VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t reference)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
cmd_buffer->state.gfx.dynamic.stencil_reference.front = reference;
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
cmd_buffer->state.gfx.dynamic.stencil_reference.back = reference;
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 samples = pSampleLocationsInfo->sampleLocationsPerPixel;
struct intel_sample_position *positions =
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) {
positions[i].x = pSampleLocationsInfo->pSampleLocations[i].x;
positions[i].y = pSampleLocationsInfo->pSampleLocations[i].y;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS;
}
}
}
void anv_CmdSetLineStippleEXT(
VkCommandBuffer commandBuffer,
uint32_t lineStippleFactor,
uint16_t lineStipplePattern)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.line_stipple.factor = lineStippleFactor;
cmd_buffer->state.gfx.dynamic.line_stipple.pattern = lineStipplePattern;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE;
}
void anv_CmdSetCullMode(
VkCommandBuffer commandBuffer,
VkCullModeFlags cullMode)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.cull_mode = cullMode;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_CULL_MODE;
}
void anv_CmdSetFrontFace(
VkCommandBuffer commandBuffer,
VkFrontFace frontFace)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.front_face = frontFace;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
}
void anv_CmdSetDepthTestEnable(
VkCommandBuffer commandBuffer,
VkBool32 depthTestEnable)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.depth_test_enable = depthTestEnable;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE;
}
void anv_CmdSetDepthWriteEnable(
VkCommandBuffer commandBuffer,
VkBool32 depthWriteEnable)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.depth_write_enable = depthWriteEnable;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE;
}
void anv_CmdSetDepthCompareOp(
VkCommandBuffer commandBuffer,
VkCompareOp depthCompareOp)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.depth_compare_op = depthCompareOp;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP;
}
void anv_CmdSetDepthBoundsTestEnable(
VkCommandBuffer commandBuffer,
VkBool32 depthBoundsTestEnable)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.depth_bounds_test_enable = depthBoundsTestEnable;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE;
}
void anv_CmdSetStencilTestEnable(
VkCommandBuffer commandBuffer,
VkBool32 stencilTestEnable)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.gfx.dynamic.stencil_test_enable = stencilTestEnable;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE;
}
void anv_CmdSetStencilOp(
VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
VkStencilOp failOp,
VkStencilOp passOp,
VkStencilOp depthFailOp,
VkCompareOp compareOp)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {
cmd_buffer->state.gfx.dynamic.stencil_op.front.fail_op = failOp;
cmd_buffer->state.gfx.dynamic.stencil_op.front.pass_op = passOp;
cmd_buffer->state.gfx.dynamic.stencil_op.front.depth_fail_op = depthFailOp;
cmd_buffer->state.gfx.dynamic.stencil_op.front.compare_op = compareOp;
}
if (faceMask & VK_STENCIL_FACE_BACK_BIT) {
cmd_buffer->state.gfx.dynamic.stencil_op.back.fail_op = failOp;
cmd_buffer->state.gfx.dynamic.stencil_op.back.pass_op = passOp;
cmd_buffer->state.gfx.dynamic.stencil_op.back.depth_fail_op = depthFailOp;
cmd_buffer->state.gfx.dynamic.stencil_op.back.compare_op = compareOp;
}
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP;
}
static void
anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
VkPipelineBindPoint bind_point,
@ -1167,9 +612,6 @@ void anv_CmdBindVertexBuffers2(
/* We have to defer setting up vertex buffer since we need the buffer
* stride from the pipeline. */
if (pStrides)
cmd_buffer->state.gfx.dynamic.dyn_vbo_stride = true;
assert(firstBinding + bindingCount <= MAX_VBS);
for (uint32_t i = 0; i < bindingCount; i++) {
ANV_FROM_HANDLE(anv_buffer, buffer, pBuffers[i]);
@ -1184,11 +626,15 @@ void anv_CmdBindVertexBuffers2(
.offset = pOffsets[i],
.size = vk_buffer_range(&buffer->vk, pOffsets[i],
pSizes ? pSizes[i] : VK_WHOLE_SIZE),
.stride = pStrides ? pStrides[i] : 0,
};
}
cmd_buffer->state.gfx.vb_dirty |= 1 << (firstBinding + i);
}
if (pStrides != NULL) {
vk_cmd_set_vertex_binding_strides(&cmd_buffer->vk, firstBinding,
bindingCount, pStrides);
}
}
void anv_CmdBindTransformFeedbackBuffersEXT(
@ -1610,50 +1056,6 @@ void anv_CmdSetDeviceMask(
/* No-op */
}
void anv_CmdSetColorWriteEnableEXT(
VkCommandBuffer commandBuffer,
uint32_t attachmentCount,
const VkBool32* pColorWriteEnables)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
assert(attachmentCount <= MAX_RTS);
/* Keep the existing values outside the color attachments count of the
* current pipeline.
*/
uint8_t color_writes = cmd_buffer->state.gfx.dynamic.color_writes;
for (uint32_t i = 0; i < attachmentCount; i++) {
if (pColorWriteEnables[i])
color_writes |= BITFIELD_BIT(i);
else
color_writes &= ~BITFIELD_BIT(i);
}
if (cmd_buffer->state.gfx.dynamic.color_writes != color_writes) {
cmd_buffer->state.gfx.dynamic.color_writes = color_writes;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE;
}
}
void anv_CmdSetFragmentShadingRateKHR(
VkCommandBuffer commandBuffer,
const VkExtent2D* pFragmentSize,
const VkFragmentShadingRateCombinerOpKHR combinerOps[2])
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
if (cmd_buffer->state.gfx.dynamic.fragment_shading_rate.rate.width != pFragmentSize->width ||
cmd_buffer->state.gfx.dynamic.fragment_shading_rate.rate.height != pFragmentSize->height ||
cmd_buffer->state.gfx.dynamic.fragment_shading_rate.ops[0] != combinerOps[0] ||
cmd_buffer->state.gfx.dynamic.fragment_shading_rate.ops[1] != combinerOps[1]) {
cmd_buffer->state.gfx.dynamic.fragment_shading_rate.rate = *pFragmentSize;
memcpy(cmd_buffer->state.gfx.dynamic.fragment_shading_rate.ops, combinerOps,
sizeof(cmd_buffer->state.gfx.dynamic.fragment_shading_rate.ops));
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE;
}
}
void anv_CmdSetRayTracingPipelineStackSizeKHR(
VkCommandBuffer commandBuffer,
uint32_t pipelineStackSize)

View File

@ -133,14 +133,14 @@ genX(emit_urb_setup)(struct anv_device *device, struct anv_batch *batch,
enum intel_urb_deref_block_size *deref_block_size);
void genX(emit_multisample)(struct anv_batch *batch, uint32_t samples,
const struct intel_sample_position *positions);
const struct vk_sample_locations_state *sl);
void genX(emit_sample_pattern)(struct anv_batch *batch,
const struct anv_dynamic_state *dynamic_state);
const struct vk_sample_locations_state *sl);
void genX(emit_shading_rate)(struct anv_batch *batch,
const struct anv_graphics_pipeline *pipeline,
struct anv_dynamic_state *dynamic_state);
const struct vk_fragment_shading_rate_state *fsr);
void genX(cmd_buffer_so_memcpy)(struct anv_cmd_buffer *cmd_buffer,
struct anv_address dst, struct anv_address src,

View File

@ -360,6 +360,7 @@ populate_gs_prog_key(const struct anv_device *device,
static bool
pipeline_has_coarse_pixel(const struct anv_graphics_pipeline *pipeline,
const BITSET_WORD *dynamic,
const struct vk_multisample_state *ms,
const struct vk_fragment_shading_rate_state *fsr)
{
@ -396,14 +397,10 @@ pipeline_has_coarse_pixel(const struct anv_graphics_pipeline *pipeline,
if (ms != NULL && ms->sample_shading_enable)
return false;
/* Not dynamic & not specified for the pipeline. */
if ((pipeline->dynamic_states & ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE) == 0 && fsr == NULL)
return false;
/* Not dynamic & pipeline has a 1x1 fragment shading rate with no
* possibility for element of the pipeline to change the value.
*/
if ((pipeline->dynamic_states & ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE) == 0 &&
if (!BITSET_TEST(dynamic, MESA_VK_DYNAMIC_FSR) &&
fsr->fragment_size.width <= 1 &&
fsr->fragment_size.height <= 1 &&
fsr->combiner_ops[0] == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR &&
@ -436,6 +433,7 @@ populate_mesh_prog_key(const struct anv_device *device,
static void
populate_wm_prog_key(const struct anv_graphics_pipeline *pipeline,
bool robust_buffer_acccess,
const BITSET_WORD *dynamic,
const struct vk_multisample_state *ms,
const struct vk_fragment_shading_rate_state *fsr,
const struct vk_render_pass_state *rp,
@ -489,7 +487,7 @@ populate_wm_prog_key(const struct anv_graphics_pipeline *pipeline,
key->coarse_pixel =
!key->persample_interp &&
device->vk.enabled_extensions.KHR_fragment_shading_rate &&
pipeline_has_coarse_pixel(pipeline, ms, fsr);
pipeline_has_coarse_pixel(pipeline, dynamic, ms, fsr);
}
static void
@ -1356,7 +1354,7 @@ anv_graphics_pipeline_init_keys(struct anv_graphics_pipeline *pipeline,
case MESA_SHADER_FRAGMENT: {
populate_wm_prog_key(pipeline,
pipeline->base.device->robust_buffer_access,
state->ms, state->fsr, state->rp,
state->dynamic, state->ms, state->fsr, state->rp,
&stages[s].key.wm);
break;
}
@ -2031,195 +2029,6 @@ VkResult anv_CreateComputePipelines(
return result;
}
/**
* Copy pipeline state not marked as dynamic.
* Dynamic state is pipeline state which hasn't been provided at pipeline
* creation time, but is dynamically provided afterwards using various
* vkCmdSet* functions.
*
* The set of state considered "non_dynamic" is determined by the pieces of
* state that have their corresponding VkDynamicState enums omitted from
* VkPipelineDynamicStateCreateInfo::pDynamicStates.
*
* @param[out] pipeline Destination non_dynamic state.
* @param[in] pCreateInfo Source of non_dynamic state to be copied.
*/
static void
copy_non_dynamic_state(struct anv_graphics_pipeline *pipeline,
const struct vk_graphics_pipeline_state *state)
{
anv_cmd_dirty_mask_t states = ANV_CMD_DIRTY_DYNAMIC_ALL;
anv_dynamic_state_init(&pipeline->non_dynamic_state);
states &= ~pipeline->dynamic_states;
struct anv_dynamic_state *dynamic = &pipeline->non_dynamic_state;
/* Section 9.2 of the Vulkan 1.0.15 spec says:
*
* pViewportState is [...] NULL if the pipeline
* has rasterization disabled.
*/
if (state->vp) {
pipeline->negative_one_to_one = state->vp->negative_one_to_one;
dynamic->viewport.count = state->vp->viewport_count;
if (states & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT) {
typed_memcpy(dynamic->viewport.viewports,
state->vp->viewports, state->vp->viewport_count);
}
dynamic->scissor.count = state->vp->scissor_count;
if (states & ANV_CMD_DIRTY_DYNAMIC_SCISSOR) {
typed_memcpy(dynamic->scissor.scissors,
state->vp->scissors, state->vp->scissor_count);
}
}
if (states & ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH)
dynamic->line_width = state->rs->line.width;
if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS) {
dynamic->depth_bias.bias = state->rs->depth_bias.constant;
dynamic->depth_bias.clamp = state->rs->depth_bias.clamp;
dynamic->depth_bias.slope = state->rs->depth_bias.slope;
}
if (states & ANV_CMD_DIRTY_DYNAMIC_CULL_MODE)
dynamic->cull_mode = state->rs->cull_mode;
if (states & ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE)
dynamic->front_face = state->rs->front_face;
if ((states & ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY) &&
(pipeline->active_stages & VK_SHADER_STAGE_VERTEX_BIT))
dynamic->primitive_topology = state->ia->primitive_topology;
if (states & ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE)
dynamic->raster_discard = state->rs->rasterizer_discard_enable;
if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE)
dynamic->depth_bias_enable = state->rs->depth_bias.enable;
if ((states & ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE) &&
(pipeline->active_stages & VK_SHADER_STAGE_VERTEX_BIT))
dynamic->primitive_restart_enable = state->ia->primitive_restart_enable;
if (state->cb != NULL && (states & ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS))
typed_memcpy(dynamic->blend_constants, state->cb->blend_constants, 4);
if (state->ds != NULL) {
if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS) {
dynamic->depth_bounds.min = state->ds->depth.bounds_test.min;
dynamic->depth_bounds.max = state->ds->depth.bounds_test.max;
}
if (states & ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK) {
dynamic->stencil_compare_mask.front =
state->ds->stencil.front.compare_mask;
dynamic->stencil_compare_mask.back =
state->ds->stencil.back.compare_mask;
}
if (states & ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK) {
dynamic->stencil_write_mask.front =
state->ds->stencil.front.write_mask;
dynamic->stencil_write_mask.back =
state->ds->stencil.back.write_mask;
}
if (states & ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE) {
dynamic->stencil_reference.front =
state->ds->stencil.front.reference;
dynamic->stencil_reference.back =
state->ds->stencil.back.reference;
}
if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE)
dynamic->depth_test_enable = state->ds->depth.test_enable;
if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE)
dynamic->depth_write_enable = state->ds->depth.write_enable;
if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP)
dynamic->depth_compare_op = state->ds->depth.compare_op;
if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE) {
dynamic->depth_bounds_test_enable =
state->ds->depth.bounds_test.enable;
}
if (states & ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE)
dynamic->stencil_test_enable = state->ds->stencil.test_enable;
if (states & ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP) {
dynamic->stencil_op.front.fail_op = state->ds->stencil.front.op.fail;
dynamic->stencil_op.front.pass_op = state->ds->stencil.front.op.pass;
dynamic->stencil_op.front.depth_fail_op = state->ds->stencil.front.op.depth_fail;
dynamic->stencil_op.front.compare_op = state->ds->stencil.front.op.compare;
dynamic->stencil_op.back.fail_op = state->ds->stencil.back.op.fail;
dynamic->stencil_op.back.pass_op = state->ds->stencil.back.op.pass;
dynamic->stencil_op.back.depth_fail_op = state->ds->stencil.back.op.depth_fail;
dynamic->stencil_op.back.compare_op = state->ds->stencil.back.op.compare;
}
}
if (state->rs != NULL) {
if (states & ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE) {
dynamic->line_stipple.factor = state->rs->line.stipple.factor;
dynamic->line_stipple.pattern = state->rs->line.stipple.pattern;
}
}
if (states & ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS) {
if (state->ms != NULL) {
uint32_t samples = state->ms->rasterization_samples;
for (uint32_t i = 0; i < samples; i++) {
dynamic->sample_locations.locations[i].x =
state->ms->sample_locations->locations[i].x;
dynamic->sample_locations.locations[i].y =
state->ms->sample_locations->locations[i].y;
}
dynamic->sample_locations.samples = samples;
} else {
dynamic->sample_locations.samples = 1;
dynamic->sample_locations.locations[0].x = 0.5;
dynamic->sample_locations.locations[0].y = 0.5;
}
}
if (state->cb != NULL) {
if (states & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE)
dynamic->color_writes = state->cb->color_write_enables;
if (states & ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP)
dynamic->logic_op = state->cb->logic_op;
}
if (states & ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE) {
dynamic->fragment_shading_rate.rate = state->fsr->fragment_size;
memcpy(dynamic->fragment_shading_rate.ops, state->fsr->combiner_ops,
sizeof(dynamic->fragment_shading_rate.ops));
}
/* When binding a mesh pipeline into a command buffer, it should not affect the
* pre-rasterization bits of legacy graphics pipelines. So remove all the
* pre-rasterization flags from the non-dynamic bits from the mesh pipelines
* here so we don't copy any of that stuff when binding those into a command
* buffer.
*/
if (pipeline->active_stages & VK_SHADER_STAGE_MESH_BIT_NV) {
states &= ~(ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE |
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE |
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY);
}
pipeline->non_dynamic_state_mask = states;
}
/**
* Calculate the desired L3 partitioning based on the current state of the
* pipeline. For now this simply returns the conservative defaults calculated
@ -2257,13 +2066,6 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline,
anv_batch_set_storage(&pipeline->base.batch, ANV_NULL_ADDRESS,
pipeline->batch_data, sizeof(pipeline->batch_data));
enum mesa_vk_dynamic_graphics_state s;
BITSET_FOREACH_SET(s, state->dynamic,
MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX) {
pipeline->dynamic_states |=
anv_cmd_dirty_bit_for_mesa_vk_dynamic_graphics_state(s);
}
pipeline->active_stages = 0;
for (uint32_t i = 0; i < pCreateInfo->stageCount; i++)
pipeline->active_stages |= pCreateInfo->pStages[i].stage;
@ -2274,7 +2076,8 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline,
if (anv_pipeline_is_mesh(pipeline))
assert(device->physical->vk.supported_extensions.NV_mesh_shader);
copy_non_dynamic_state(pipeline, state);
pipeline->dynamic_state.ms.sample_locations = &pipeline->sample_locations;
vk_dynamic_graphics_state_fill(&pipeline->dynamic_state, state);
pipeline->depth_clamp_enable = state->rs->depth_clamp_enable;
pipeline->depth_clip_enable = state->rs->depth_clip_enable;
@ -2316,6 +2119,9 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline,
/* TODO(mesh): Mesh vs. Multiview with Instancing. */
}
pipeline->negative_one_to_one =
state->vp != NULL && state->vp->negative_one_to_one;
/* Store line mode, polygon mode and rasterization samples, these are used
* for dynamic primitive topology.
*/

View File

@ -2199,137 +2199,13 @@ struct anv_buffer {
};
enum anv_cmd_dirty_bits {
ANV_CMD_DIRTY_DYNAMIC_VIEWPORT = 1 << 0, /* VK_DYNAMIC_STATE_VIEWPORT */
ANV_CMD_DIRTY_DYNAMIC_SCISSOR = 1 << 1, /* VK_DYNAMIC_STATE_SCISSOR */
ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH = 1 << 2, /* VK_DYNAMIC_STATE_LINE_WIDTH */
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS = 1 << 3, /* VK_DYNAMIC_STATE_DEPTH_BIAS */
ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS = 1 << 4, /* VK_DYNAMIC_STATE_BLEND_CONSTANTS */
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS = 1 << 5, /* VK_DYNAMIC_STATE_DEPTH_BOUNDS */
ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK = 1 << 6, /* VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK */
ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK = 1 << 7, /* VK_DYNAMIC_STATE_STENCIL_WRITE_MASK */
ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE = 1 << 8, /* VK_DYNAMIC_STATE_STENCIL_REFERENCE */
ANV_CMD_DIRTY_PIPELINE = 1 << 9,
ANV_CMD_DIRTY_INDEX_BUFFER = 1 << 10,
ANV_CMD_DIRTY_RENDER_TARGETS = 1 << 11,
ANV_CMD_DIRTY_XFB_ENABLE = 1 << 12,
ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE = 1 << 13, /* VK_DYNAMIC_STATE_LINE_STIPPLE_EXT */
ANV_CMD_DIRTY_DYNAMIC_CULL_MODE = 1 << 14, /* VK_DYNAMIC_STATE_CULL_MODE */
ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE = 1 << 15, /* VK_DYNAMIC_STATE_FRONT_FACE */
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY = 1 << 16, /* VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY */
ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE = 1 << 17, /* VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE */
ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE = 1 << 18, /* VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE */
ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE = 1 << 19, /* VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE */
ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP = 1 << 20, /* VK_DYNAMIC_STATE_DEPTH_COMPARE_OP */
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE = 1 << 21, /* VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE */
ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE = 1 << 22, /* VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE */
ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP = 1 << 23, /* VK_DYNAMIC_STATE_STENCIL_OP */
ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS = 1 << 24, /* VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT */
ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE = 1 << 25, /* VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT */
ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE = 1 << 26, /* VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR */
ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE = 1 << 27, /* VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE */
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE = 1 << 28, /* VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE */
ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP = 1 << 29, /* VK_DYNAMIC_STATE_LOGIC_OP_EXT */
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE = 1 << 30, /* VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE */
ANV_CMD_DIRTY_PIPELINE = 1 << 0,
ANV_CMD_DIRTY_INDEX_BUFFER = 1 << 1,
ANV_CMD_DIRTY_RENDER_TARGETS = 1 << 2,
ANV_CMD_DIRTY_XFB_ENABLE = 1 << 3,
};
typedef enum anv_cmd_dirty_bits anv_cmd_dirty_mask_t;
#define ANV_CMD_DIRTY_DYNAMIC_ALL \
(ANV_CMD_DIRTY_DYNAMIC_VIEWPORT | \
ANV_CMD_DIRTY_DYNAMIC_SCISSOR | \
ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH | \
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS | \
ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS | \
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS | \
ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK | \
ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK | \
ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE | \
ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE | \
ANV_CMD_DIRTY_DYNAMIC_CULL_MODE | \
ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE | \
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY | \
ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE | \
ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE | \
ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE | \
ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP | \
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE | \
ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE | \
ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP | \
ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS | \
ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE | \
ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE | \
ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE | \
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE | \
ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP | \
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE)
static inline enum anv_cmd_dirty_bits
anv_cmd_dirty_bit_for_mesa_vk_dynamic_graphics_state(
enum mesa_vk_dynamic_graphics_state state)
{
switch (state) {
case MESA_VK_DYNAMIC_VP_VIEWPORT_COUNT:
case MESA_VK_DYNAMIC_VP_VIEWPORTS:
return ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
case MESA_VK_DYNAMIC_VP_SCISSOR_COUNT:
case MESA_VK_DYNAMIC_VP_SCISSORS:
return ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
case MESA_VK_DYNAMIC_RS_LINE_WIDTH:
return ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH;
case MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS:
return ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
case MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS:
return ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
case MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS:
return ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS;
case MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK:
return ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK;
case MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK:
return ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK;
case MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE:
return ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;
case MESA_VK_DYNAMIC_RS_LINE_STIPPLE:
return ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE;
case MESA_VK_DYNAMIC_RS_CULL_MODE:
return ANV_CMD_DIRTY_DYNAMIC_CULL_MODE;
case MESA_VK_DYNAMIC_RS_FRONT_FACE:
return ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
case MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY:
return ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY;
case MESA_VK_DYNAMIC_VI_BINDING_STRIDES:
return ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE;
case MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE:
return ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE;
case MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE:
return ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE;
case MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP:
return ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP;
case MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE:
return ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE;
case MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE:
return ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE;
case MESA_VK_DYNAMIC_DS_STENCIL_OP:
return ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP;
case MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS:
return ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS;
case MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES:
return ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE;
case MESA_VK_DYNAMIC_FSR:
return ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE;
case MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE:
return ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE;
case MESA_VK_DYNAMIC_RS_DEPTH_BIAS_ENABLE:
return ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE;
case MESA_VK_DYNAMIC_CB_LOGIC_OP:
return ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP;
case MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE:
return ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
default:
assert(!"Unsupported dynamic state");
return 0;
}
}
enum anv_pipe_bits {
ANV_PIPE_DEPTH_CACHE_FLUSH_BIT = (1 << 0),
ANV_PIPE_STALL_AT_SCOREBOARD_BIT = (1 << 1),
@ -2598,7 +2474,6 @@ anv_pipe_invalidate_bits_for_access_flags(struct anv_device *device,
struct anv_vertex_binding {
struct anv_buffer * buffer;
VkDeviceSize offset;
VkDeviceSize stride;
VkDeviceSize size;
};
@ -2640,102 +2515,6 @@ struct anv_push_constants {
} cs;
};
struct anv_dynamic_state {
struct {
uint32_t count;
VkViewport viewports[MAX_VIEWPORTS];
} viewport;
struct {
uint32_t count;
VkRect2D scissors[MAX_SCISSORS];
} scissor;
float line_width;
struct {
float bias;
float clamp;
float slope;
} depth_bias;
float blend_constants[4];
struct {
float min;
float max;
} depth_bounds;
struct {
uint32_t front;
uint32_t back;
} stencil_compare_mask;
struct {
uint32_t front;
uint32_t back;
} stencil_write_mask;
struct {
uint32_t front;
uint32_t back;
} stencil_reference;
struct {
struct {
VkStencilOp fail_op;
VkStencilOp pass_op;
VkStencilOp depth_fail_op;
VkCompareOp compare_op;
} front;
struct {
VkStencilOp fail_op;
VkStencilOp pass_op;
VkStencilOp depth_fail_op;
VkCompareOp compare_op;
} back;
} stencil_op;
struct {
uint32_t factor;
uint16_t pattern;
} line_stipple;
struct {
struct intel_sample_position locations[16];
unsigned samples;
} sample_locations;
struct {
VkExtent2D rate;
VkFragmentShadingRateCombinerOpKHR ops[2];
} fragment_shading_rate;
VkCullModeFlags cull_mode;
VkFrontFace front_face;
VkPrimitiveTopology primitive_topology;
bool depth_test_enable;
bool depth_write_enable;
VkCompareOp depth_compare_op;
bool depth_bounds_test_enable;
bool stencil_test_enable;
bool raster_discard;
bool depth_bias_enable;
bool primitive_restart_enable;
VkLogicOp logic_op;
bool dyn_vbo_stride;
/* Bitfield, one bit per render target */
uint8_t color_writes;
};
extern const struct anv_dynamic_state default_dynamic_state;
void anv_dynamic_state_init(struct anv_dynamic_state *state);
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);
struct anv_surface_state {
struct anv_state state;
/** Address of the surface referred to by this state
@ -2876,13 +2655,13 @@ struct anv_cmd_graphics_state {
VkShaderStageFlags push_constant_stages;
struct anv_dynamic_state dynamic;
uint32_t primitive_topology;
struct anv_buffer *index_buffer;
uint32_t index_type; /**< 3DSTATE_INDEX_BUFFER.IndexFormat */
uint32_t index_offset;
struct vk_sample_locations_state sample_locations;
};
enum anv_depth_reg_mode {
@ -3306,21 +3085,13 @@ struct anv_pipeline {
struct anv_graphics_pipeline {
struct anv_pipeline base;
/* States declared dynamic at pipeline creation. */
anv_cmd_dirty_mask_t dynamic_states;
/* Shaders */
struct anv_shader_bin * shaders[ANV_GRAPHICS_SHADER_STAGE_COUNT];
VkShaderStageFlags active_stages;
/* States that need to be reemitted in cmd_buffer_flush_dynamic_state().
* This might cover more than the dynamic states specified at pipeline
* creation.
*/
anv_cmd_dirty_mask_t non_dynamic_state_mask;
struct anv_dynamic_state non_dynamic_state;
struct vk_sample_locations_state sample_locations;
struct vk_dynamic_graphics_state dynamic_state;
/* These fields are required with dynamic primitive topology,
* rasterization_samples used only with gen < 8.
@ -3342,7 +3113,6 @@ struct anv_graphics_pipeline {
bool depth_clamp_enable;
bool depth_clip_enable;
bool kill_pixel;
bool depth_bounds_test_enable;
bool force_fragment_thread_dispatch;
bool negative_one_to_one;
@ -3456,7 +3226,9 @@ static inline bool
anv_cmd_buffer_all_color_write_masked(const struct anv_cmd_buffer *cmd_buffer)
{
const struct anv_cmd_graphics_state *state = &cmd_buffer->state.gfx;
uint8_t color_writes = state->dynamic.color_writes;
const struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
uint8_t color_writes = dyn->cb.color_write_enables;
/* All writes disabled through vkCmdSetColorWriteEnableEXT */
if ((color_writes & ((1u << state->color_att_count) - 1)) == 0)

View File

@ -336,21 +336,26 @@ blorp_exec_on_render(struct blorp_batch *batch,
/* Calculate state that does not get touched by blorp.
* Flush everything else.
*/
anv_cmd_dirty_mask_t skip_bits = ANV_CMD_DIRTY_DYNAMIC_SCISSOR |
ANV_CMD_DIRTY_INDEX_BUFFER |
ANV_CMD_DIRTY_XFB_ENABLE |
ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE |
ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS |
ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE |
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
anv_cmd_dirty_mask_t dirty = ~(ANV_CMD_DIRTY_INDEX_BUFFER |
ANV_CMD_DIRTY_XFB_ENABLE);
BITSET_DECLARE(dyn_dirty, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
BITSET_ONES(dyn_dirty);
BITSET_CLEAR(dyn_dirty, MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE);
BITSET_CLEAR(dyn_dirty, MESA_VK_DYNAMIC_VP_SCISSOR_COUNT);
BITSET_CLEAR(dyn_dirty, MESA_VK_DYNAMIC_VP_SCISSORS);
BITSET_CLEAR(dyn_dirty, MESA_VK_DYNAMIC_RS_LINE_STIPPLE);
BITSET_CLEAR(dyn_dirty, MESA_VK_DYNAMIC_FSR);
BITSET_CLEAR(dyn_dirty, MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS);
if (!params->wm_prog_data) {
skip_bits |= ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE |
ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP;
BITSET_CLEAR(dyn_dirty, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES);
BITSET_CLEAR(dyn_dirty, MESA_VK_DYNAMIC_CB_LOGIC_OP);
}
cmd_buffer->state.gfx.vb_dirty = ~0;
cmd_buffer->state.gfx.dirty |= ~skip_bits;
cmd_buffer->state.gfx.dirty |= dirty;
BITSET_OR(cmd_buffer->vk.dynamic_graphics_state.dirty,
cmd_buffer->vk.dynamic_graphics_state.dirty, dyn_dirty);
cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_ALL_GRAPHICS;
}

View File

@ -1924,8 +1924,8 @@ genX(CmdExecuteCommands)(
primary->state.current_pipeline = UINT32_MAX;
primary->state.current_l3_config = NULL;
primary->state.current_hash_scale = 0;
primary->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_ALL;
primary->state.gfx.push_constant_stages = 0;
vk_dynamic_graphics_state_dirty_all(&primary->vk.dynamic_graphics_state);
/* Each of the secondary command buffers will use its own state base
* address. We need to re-emit state base address for the primary after
@ -3413,36 +3413,31 @@ cmd_buffer_flush_mesh_inline_data(struct anv_cmd_buffer *cmd_buffer,
static void
cmd_buffer_emit_clip(struct anv_cmd_buffer *cmd_buffer)
{
const uint32_t clip_states =
#if GFX_VER <= 7
ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE |
ANV_CMD_DIRTY_DYNAMIC_CULL_MODE |
#endif
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY |
ANV_CMD_DIRTY_DYNAMIC_VIEWPORT |
ANV_CMD_DIRTY_PIPELINE;
const struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
if ((cmd_buffer->state.gfx.dirty & clip_states) == 0)
if (!(cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) &&
!BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY) &&
#if GFX_VER <= 7
!BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_CULL_MODE) &&
!BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_FRONT_FACE) &&
#endif
!BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VP_VIEWPORT_COUNT))
return;
/* Take dynamic primitive topology in to account with
* 3DSTATE_CLIP::ViewportXYClipTestEnable
*/
VkPrimitiveTopology primitive_topology =
cmd_buffer->state.gfx.dynamic.primitive_topology;
VkPolygonMode dynamic_raster_mode =
genX(raster_polygon_mode)(cmd_buffer->state.gfx.pipeline,
primitive_topology);
dyn->ia.primitive_topology);
bool xy_clip_test_enable = (dynamic_raster_mode == VK_POLYGON_MODE_FILL);
#if GFX_VER <= 7
const struct anv_dynamic_state *d = &cmd_buffer->state.gfx.dynamic;
#endif
struct GENX(3DSTATE_CLIP) clip = {
GENX(3DSTATE_CLIP_header),
#if GFX_VER <= 7
.FrontWinding = genX(vk_to_intel_front_face)[d->front_face],
.CullMode = genX(vk_to_intel_cullmode)[d->cull_mode],
.FrontWinding = genX(vk_to_intel_front_face)[dyn->rs.front_face],
.CullMode = genX(vk_to_intel_cullmode)[dyn->rs.cull_mode],
#endif
.ViewportXYClipTestEnable = xy_clip_test_enable,
};
@ -3454,15 +3449,14 @@ cmd_buffer_emit_clip(struct anv_cmd_buffer *cmd_buffer)
const struct brw_vue_prog_data *last =
anv_pipeline_get_last_vue_prog_data(pipeline);
if (last->vue_map.slots_valid & VARYING_BIT_VIEWPORT) {
clip.MaximumVPIndex =
cmd_buffer->state.gfx.dynamic.viewport.count > 0 ?
cmd_buffer->state.gfx.dynamic.viewport.count - 1 : 0;
clip.MaximumVPIndex = dyn->vp.viewport_count > 0 ?
dyn->vp.viewport_count - 1 : 0;
}
} else if (anv_pipeline_is_mesh(pipeline)) {
const struct brw_mesh_prog_data *mesh_prog_data = get_mesh_prog_data(pipeline);
if (mesh_prog_data->map.start_dw[VARYING_SLOT_VIEWPORT] >= 0) {
uint32_t viewport_count = cmd_buffer->state.gfx.dynamic.viewport.count;
clip.MaximumVPIndex = viewport_count > 0 ? viewport_count - 1 : 0;
clip.MaximumVPIndex = dyn->vp.viewport_count > 0 ?
dyn->vp.viewport_count - 1 : 0;
}
}
@ -3475,8 +3469,10 @@ static void
cmd_buffer_emit_viewport(struct anv_cmd_buffer *cmd_buffer)
{
struct anv_cmd_graphics_state *gfx = &cmd_buffer->state.gfx;
uint32_t count = gfx->dynamic.viewport.count;
const VkViewport *viewports = gfx->dynamic.viewport.viewports;
const struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
uint32_t count = dyn->vp.viewport_count;
const VkViewport *viewports = dyn->vp.viewports;
struct anv_state sf_clip_state =
anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, count * 64, 64);
@ -3538,8 +3534,8 @@ cmd_buffer_emit_viewport(struct anv_cmd_buffer *cmd_buffer)
* It's theoretically possible that they could do all their clipping
* with clip planes but that'd be a bit odd.
*/
if (i < gfx->dynamic.scissor.count) {
const VkRect2D *scissor = &gfx->dynamic.scissor.scissors[i];
if (i < dyn->vp.scissor_count) {
const VkRect2D *scissor = &dyn->vp.scissors[i];
x_min = MAX2(x_min, scissor->offset.x);
x_max = MIN2(x_min, scissor->offset.x + scissor->extent.width);
y_min = MAX2(y_min, scissor->offset.y);
@ -3576,9 +3572,10 @@ static void
cmd_buffer_emit_depth_viewport(struct anv_cmd_buffer *cmd_buffer,
bool depth_clamp_enable)
{
uint32_t count = cmd_buffer->state.gfx.dynamic.viewport.count;
const VkViewport *viewports =
cmd_buffer->state.gfx.dynamic.viewport.viewports;
const struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
uint32_t count = dyn->vp.viewport_count;
const VkViewport *viewports = dyn->vp.viewports;
struct anv_state cc_state =
anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, count * 8, 32);
@ -3622,9 +3619,11 @@ static void
cmd_buffer_emit_scissor(struct anv_cmd_buffer *cmd_buffer)
{
struct anv_cmd_graphics_state *gfx = &cmd_buffer->state.gfx;
uint32_t count = gfx->dynamic.scissor.count;
const VkRect2D *scissors = gfx->dynamic.scissor.scissors;
const VkViewport *viewports = gfx->dynamic.viewport.viewports;
const struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
uint32_t count = dyn->vp.scissor_count;
const VkRect2D *scissors = dyn->vp.scissors;
const VkViewport *viewports = dyn->vp.viewports;
/* Wa_1409725701:
* "The viewport-specific state used by the SF unit (SCISSOR_RECT) is
@ -3697,7 +3696,8 @@ cmd_buffer_emit_scissor(struct anv_cmd_buffer *cmd_buffer)
static void
cmd_buffer_emit_streamout(struct anv_cmd_buffer *cmd_buffer)
{
const struct anv_dynamic_state *d = &cmd_buffer->state.gfx.dynamic;
const struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
#if GFX_VER == 7
@ -3710,7 +3710,7 @@ cmd_buffer_emit_streamout(struct anv_cmd_buffer *cmd_buffer)
struct GENX(3DSTATE_STREAMOUT) so = {
GENX(3DSTATE_STREAMOUT_header),
.RenderingDisable = d->raster_discard,
.RenderingDisable = dyn->rs.rasterizer_discard_enable,
};
GENX(3DSTATE_STREAMOUT_pack)(NULL, dwords, &so);
anv_batch_emit_merge(&cmd_buffer->batch, dwords, streamout_state_dw);
@ -3720,6 +3720,8 @@ void
genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
{
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
const struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
uint32_t *p;
assert((pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT) == 0);
@ -3751,15 +3753,9 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
struct anv_buffer *buffer = cmd_buffer->state.vertex_bindings[vb].buffer;
uint32_t offset = cmd_buffer->state.vertex_bindings[vb].offset;
/* If dynamic, use stride/size from vertex binding, otherwise use
* stride/size that was setup in the pipeline object.
*/
bool dynamic_stride = cmd_buffer->state.gfx.dynamic.dyn_vbo_stride;
struct GENX(VERTEX_BUFFER_STATE) state;
if (buffer) {
uint32_t stride = dynamic_stride ?
cmd_buffer->state.vertex_bindings[vb].stride : pipeline->vb[vb].stride;
uint32_t stride = dyn->vi_binding_strides[vb];
UNUSED uint32_t size = cmd_buffer->state.vertex_bindings[vb].size;
#if GFX_VER <= 7
@ -3821,6 +3817,7 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
uint32_t descriptors_dirty = cmd_buffer->state.descriptors_dirty &
pipeline->active_stages;
if (!cmd_buffer->state.gfx.dirty && !descriptors_dirty &&
!vk_dynamic_graphics_state_any_dirty(dyn) &&
!cmd_buffer->state.push_constants_dirty)
return;
@ -3964,33 +3961,32 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
cmd_buffer_emit_clip(cmd_buffer);
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE |
ANV_CMD_DIRTY_XFB_ENABLE))
if ((cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_XFB_ENABLE)) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE))
cmd_buffer_emit_streamout(cmd_buffer);
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_DYNAMIC_SCISSOR |
ANV_CMD_DIRTY_RENDER_TARGETS |
ANV_CMD_DIRTY_DYNAMIC_VIEWPORT |
ANV_CMD_DIRTY_PIPELINE)) {
if ((cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_RENDER_TARGETS)) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VP_VIEWPORTS) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VP_SCISSORS)) {
cmd_buffer_emit_viewport(cmd_buffer);
cmd_buffer_emit_depth_viewport(cmd_buffer,
pipeline->depth_clamp_enable);
}
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_DYNAMIC_SCISSOR |
ANV_CMD_DIRTY_RENDER_TARGETS |
ANV_CMD_DIRTY_DYNAMIC_VIEWPORT))
if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_RENDER_TARGETS) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VP_VIEWPORTS) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VP_SCISSORS))
cmd_buffer_emit_scissor(cmd_buffer);
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY)) {
const struct anv_dynamic_state *d = &cmd_buffer->state.gfx.dynamic;
if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY)) {
uint32_t topology;
if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL))
topology = _3DPRIM_PATCHLIST(pipeline->patch_control_points);
else
topology = genX(vk_to_intel_primitive_type)[d->primitive_topology];
topology = genX(vk_to_intel_primitive_type)[dyn->ia.primitive_topology];
cmd_buffer->state.gfx.primitive_topology = topology;

View File

@ -318,6 +318,7 @@ genX(cmd_buffer_so_memcpy)(struct anv_cmd_buffer *cmd_buffer,
/* Invalidate pipeline & raster discard since we touch
* 3DSTATE_STREAMOUT.
*/
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_PIPELINE;
BITSET_SET(cmd_buffer->vk.dynamic_graphics_state.dirty,
MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE);
}

View File

@ -987,7 +987,6 @@ emit_ds_state(struct anv_graphics_pipeline *pipeline,
pipeline->stencil_test_enable = false;
pipeline->writes_depth = false;
pipeline->depth_test_enable = false;
pipeline->depth_bounds_test_enable = false;
return;
}
@ -1005,7 +1004,6 @@ emit_ds_state(struct anv_graphics_pipeline *pipeline,
pipeline->stencil_test_enable = ds.stencil.test_enable;
pipeline->writes_depth = ds.depth.write_enable;
pipeline->depth_test_enable = ds.depth.test_enable;
pipeline->depth_bounds_test_enable = ds.depth.bounds_test.enable;
}
static bool

View File

@ -35,6 +35,7 @@
#include "genxml/gen_macros.h"
#include "genxml/genX_pack.h"
#include "vk_standard_sample_locations.h"
#include "vk_util.h"
static void
@ -530,7 +531,7 @@ genX(init_cps_device_state)(struct anv_device *device)
#if GFX_VER >= 12
static uint32_t
get_cps_state_offset(struct anv_device *device, bool cps_enabled,
const struct anv_dynamic_state *d)
const struct vk_fragment_shading_rate_state *fsr)
{
if (!cps_enabled)
return device->cps_states.offset;
@ -545,15 +546,15 @@ get_cps_state_offset(struct anv_device *device, bool cps_enabled,
#if GFX_VERx10 >= 125
offset =
1 + /* skip disabled */
d->fragment_shading_rate.ops[0] * 5 * 3 * 3 +
d->fragment_shading_rate.ops[1] * 3 * 3 +
size_index[d->fragment_shading_rate.rate.width] * 3 +
size_index[d->fragment_shading_rate.rate.height];
fsr->combiner_ops[0] * 5 * 3 * 3 +
fsr->combiner_ops[1] * 3 * 3 +
size_index[fsr->fragment_size.width] * 3 +
size_index[fsr->fragment_size.height];
#else
offset =
1 + /* skip disabled */
size_index[d->fragment_shading_rate.rate.width] * 3 +
size_index[d->fragment_shading_rate.rate.height];
size_index[fsr->fragment_size.width] * 3 +
size_index[fsr->fragment_size.height];
#endif
offset *= MAX_VIEWPORTS * GENX(CPS_STATE_length) * 4;
@ -686,8 +687,16 @@ genX(emit_l3_config)(struct anv_batch *batch,
void
genX(emit_multisample)(struct anv_batch *batch, uint32_t samples,
const struct intel_sample_position *positions)
const struct vk_sample_locations_state *sl)
{
if (sl != NULL) {
assert(sl->per_pixel == samples);
assert(sl->grid_size.width == 1);
assert(sl->grid_size.height == 1);
} else {
sl = vk_standard_sample_locations_state(samples);
}
anv_batch_emit(batch, GENX(3DSTATE_MULTISAMPLE), ms) {
ms.NumberofMultisamples = __builtin_ffs(samples) - 1;
@ -702,16 +711,16 @@ genX(emit_multisample)(struct anv_batch *batch, uint32_t samples,
#else
switch (samples) {
case 1:
INTEL_SAMPLE_POS_1X_ARRAY(ms.Sample, positions);
INTEL_SAMPLE_POS_1X_ARRAY(ms.Sample, sl->locations);
break;
case 2:
INTEL_SAMPLE_POS_2X_ARRAY(ms.Sample, positions);
INTEL_SAMPLE_POS_2X_ARRAY(ms.Sample, sl->locations);
break;
case 4:
INTEL_SAMPLE_POS_4X_ARRAY(ms.Sample, positions);
INTEL_SAMPLE_POS_4X_ARRAY(ms.Sample, sl->locations);
break;
case 8:
INTEL_SAMPLE_POS_8X_ARRAY(ms.Sample, positions);
INTEL_SAMPLE_POS_8X_ARRAY(ms.Sample, sl->locations);
break;
default:
break;
@ -723,8 +732,11 @@ genX(emit_multisample)(struct anv_batch *batch, uint32_t samples,
#if GFX_VER >= 8
void
genX(emit_sample_pattern)(struct anv_batch *batch,
const struct anv_dynamic_state *d)
const struct vk_sample_locations_state *sl)
{
assert(sl == NULL || sl->grid_size.width == 1);
assert(sl == NULL || sl->grid_size.height == 1);
/* See the Vulkan 1.0 spec Table 24.1 "Standard sample locations" and
* VkPhysicalDeviceFeatures::standardSampleLocations.
*/
@ -749,37 +761,37 @@ genX(emit_sample_pattern)(struct anv_batch *batch,
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);
if (sl && sl->per_pixel == i) {
INTEL_SAMPLE_POS_1X_ARRAY(sp._1xSample, sl->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);
if (sl && sl->per_pixel == i) {
INTEL_SAMPLE_POS_2X_ARRAY(sp._2xSample, sl->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);
if (sl && sl->per_pixel == i) {
INTEL_SAMPLE_POS_4X_ARRAY(sp._4xSample, sl->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);
if (sl && sl->per_pixel == i) {
INTEL_SAMPLE_POS_8X_ARRAY(sp._8xSample, sl->locations);
} else {
INTEL_SAMPLE_POS_8X(sp._8xSample);
}
break;
#if GFX_VER >= 9
case VK_SAMPLE_COUNT_16_BIT:
if (d && d->sample_locations.samples == i) {
INTEL_SAMPLE_POS_16X_ARRAY(sp._16xSample, d->sample_locations.locations);
if (sl && sl->per_pixel == i) {
INTEL_SAMPLE_POS_16X_ARRAY(sp._16xSample, sl->locations);
} else {
INTEL_SAMPLE_POS_16X(sp._16xSample);
}
@ -797,7 +809,7 @@ genX(emit_sample_pattern)(struct anv_batch *batch,
void
genX(emit_shading_rate)(struct anv_batch *batch,
const struct anv_graphics_pipeline *pipeline,
struct anv_dynamic_state *dynamic_state)
const struct vk_fragment_shading_rate_state *fsr)
{
const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline);
const bool cps_enable = wm_prog_data && wm_prog_data->per_coarse_pixel_dispatch;
@ -806,8 +818,8 @@ genX(emit_shading_rate)(struct anv_batch *batch,
anv_batch_emit(batch, GENX(3DSTATE_CPS), cps) {
cps.CoarsePixelShadingMode = cps_enable ? CPS_MODE_CONSTANT : CPS_MODE_NONE;
if (cps_enable) {
cps.MinCPSizeX = dynamic_state->fragment_shading_rate.rate.width;
cps.MinCPSizeY = dynamic_state->fragment_shading_rate.rate.height;
cps.MinCPSizeX = fsr->fragment_size.width;
cps.MinCPSizeY = fsr->fragment_size.height;
}
}
#elif GFX_VER >= 12
@ -833,7 +845,7 @@ genX(emit_shading_rate)(struct anv_batch *batch,
struct anv_device *device = pipeline->base.device;
cps.CoarsePixelShadingStateArrayPointer =
get_cps_state_offset(device, cps_enable, dynamic_state);
get_cps_state_offset(device, cps_enable, fsr);
}
#endif
}

View File

@ -60,60 +60,63 @@ void
genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
{
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
struct anv_dynamic_state *d = &cmd_buffer->state.gfx.dynamic;
const struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_RENDER_TARGETS |
ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS |
ANV_CMD_DIRTY_DYNAMIC_CULL_MODE |
ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE |
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY)) {
if ((cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_RENDER_TARGETS)) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_CULL_MODE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_FRONT_FACE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_LINE_WIDTH)) {
/* Take dynamic primitive topology in to account with
* 3DSTATE_SF::MultisampleRasterizationMode
*/
VkPolygonMode dynamic_raster_mode =
genX(raster_polygon_mode)(cmd_buffer->state.gfx.pipeline,
d->primitive_topology);
dyn->ia.primitive_topology);
uint32_t ms_rast_mode =
genX(ms_rasterization_mode)(pipeline, dynamic_raster_mode);
bool aa_enable = anv_rasterization_aa_mode(dynamic_raster_mode,
pipeline->line_mode);
uint32_t sf_dw[GENX(3DSTATE_SF_length)];
struct GENX(3DSTATE_SF) sf = {
GENX(3DSTATE_SF_header),
.DepthBufferSurfaceFormat = get_depth_format(cmd_buffer),
.LineWidth = d->line_width,
.GlobalDepthOffsetConstant = d->depth_bias.bias,
.GlobalDepthOffsetScale = d->depth_bias.slope,
.GlobalDepthOffsetClamp = d->depth_bias.clamp,
.FrontWinding = genX(vk_to_intel_front_face)[d->front_face],
.CullMode = genX(vk_to_intel_cullmode)[d->cull_mode],
.GlobalDepthOffsetEnableSolid = d->depth_bias_enable,
.GlobalDepthOffsetEnableWireframe = d->depth_bias_enable,
.GlobalDepthOffsetEnablePoint = d->depth_bias_enable,
.LineWidth = dyn->rs.line.width,
.AntialiasingEnable = aa_enable,
.CullMode = genX(vk_to_intel_cullmode)[dyn->rs.cull_mode],
.FrontWinding = genX(vk_to_intel_front_face)[dyn->rs.front_face],
.MultisampleRasterizationMode = ms_rast_mode,
.AntialiasingEnable = anv_rasterization_aa_mode(dynamic_raster_mode,
pipeline->line_mode),
.GlobalDepthOffsetEnableSolid = dyn->rs.depth_bias.enable,
.GlobalDepthOffsetEnableWireframe = dyn->rs.depth_bias.enable,
.GlobalDepthOffsetEnablePoint = dyn->rs.depth_bias.enable,
.GlobalDepthOffsetConstant = dyn->rs.depth_bias.constant,
.GlobalDepthOffsetScale = dyn->rs.depth_bias.slope,
.GlobalDepthOffsetClamp = dyn->rs.depth_bias.clamp,
};
GENX(3DSTATE_SF_pack)(NULL, sf_dw, &sf);
anv_batch_emit_merge(&cmd_buffer->batch, sf_dw, pipeline->gfx7.sf);
}
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE)) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS)) {
struct anv_state cc_state =
anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
GENX(COLOR_CALC_STATE_length) * 4,
64);
struct GENX(COLOR_CALC_STATE) cc = {
.BlendConstantColorRed = d->blend_constants[0],
.BlendConstantColorGreen = d->blend_constants[1],
.BlendConstantColorBlue = d->blend_constants[2],
.BlendConstantColorAlpha = d->blend_constants[3],
.StencilReferenceValue = d->stencil_reference.front & 0xff,
.BackfaceStencilReferenceValue = d->stencil_reference.back & 0xff,
.BlendConstantColorRed = dyn->cb.blend_constants[0],
.BlendConstantColorGreen = dyn->cb.blend_constants[1],
.BlendConstantColorBlue = dyn->cb.blend_constants[2],
.BlendConstantColorAlpha = dyn->cb.blend_constants[3],
.StencilReferenceValue = dyn->ds.stencil.front.reference & 0xff,
.BackfaceStencilReferenceValue = dyn->ds.stencil.back.reference & 0xff,
};
GENX(COLOR_CALC_STATE_pack)(NULL, cc_state.map, &cc);
@ -122,51 +125,53 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
}
}
if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_LINE_STIPPLE)) {
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_LINE_STIPPLE), ls) {
ls.LineStipplePattern = d->line_stipple.pattern;
ls.LineStipplePattern = dyn->rs.line.stipple.pattern;
ls.LineStippleInverseRepeatCount =
1.0f / MAX2(1, d->line_stipple.factor);
ls.LineStippleRepeatCount = d->line_stipple.factor;
1.0f / MAX2(1, dyn->rs.line.stipple.factor);
ls.LineStippleRepeatCount = dyn->rs.line.stipple.factor;
}
}
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_RENDER_TARGETS |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP)) {
if ((cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_RENDER_TARGETS)) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_OP) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK)) {
uint32_t depth_stencil_dw[GENX(DEPTH_STENCIL_STATE_length)];
struct GENX(DEPTH_STENCIL_STATE) depth_stencil = {
.DoubleSidedStencilEnable = true,
.StencilTestMask = d->stencil_compare_mask.front & 0xff,
.StencilWriteMask = d->stencil_write_mask.front & 0xff,
.StencilTestMask = dyn->ds.stencil.front.compare_mask & 0xff,
.StencilWriteMask = dyn->ds.stencil.front.write_mask & 0xff,
.BackfaceStencilTestMask = d->stencil_compare_mask.back & 0xff,
.BackfaceStencilWriteMask = d->stencil_write_mask.back & 0xff,
.BackfaceStencilTestMask = dyn->ds.stencil.back.compare_mask & 0xff,
.BackfaceStencilWriteMask = dyn->ds.stencil.back.write_mask & 0xff,
.StencilBufferWriteEnable =
(d->stencil_write_mask.front || d->stencil_write_mask.back) &&
d->stencil_test_enable,
(dyn->ds.stencil.back.write_mask ||
dyn->ds.stencil.front.write_mask) &&
dyn->ds.stencil.test_enable,
.DepthTestEnable = d->depth_test_enable,
.DepthBufferWriteEnable = d->depth_test_enable && d->depth_write_enable,
.DepthTestFunction = genX(vk_to_intel_compare_op)[d->depth_compare_op],
.StencilTestEnable = d->stencil_test_enable,
.StencilFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.front.fail_op],
.StencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[d->stencil_op.front.pass_op],
.StencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.front.depth_fail_op],
.StencilTestFunction = genX(vk_to_intel_compare_op)[d->stencil_op.front.compare_op],
.BackfaceStencilFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.back.fail_op],
.BackfaceStencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[d->stencil_op.back.pass_op],
.BackfaceStencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.back.depth_fail_op],
.BackfaceStencilTestFunction = genX(vk_to_intel_compare_op)[d->stencil_op.back.compare_op],
.DepthTestEnable = dyn->ds.depth.test_enable,
.DepthBufferWriteEnable = dyn->ds.depth.test_enable &&
dyn->ds.depth.write_enable,
.DepthTestFunction = genX(vk_to_intel_compare_op)[dyn->ds.depth.compare_op],
.StencilTestEnable = dyn->ds.stencil.test_enable,
.StencilFailOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.front.op.fail],
.StencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.front.op.pass],
.StencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.front.op.depth_fail],
.StencilTestFunction = genX(vk_to_intel_compare_op)[dyn->ds.stencil.front.op.compare],
.BackfaceStencilFailOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.back.op.fail],
.BackfaceStencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.back.op.pass],
.BackfaceStencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.back.op.depth_fail],
.BackfaceStencilTestFunction = genX(vk_to_intel_compare_op)[dyn->ds.stencil.back.op.compare],
};
GENX(DEPTH_STENCIL_STATE_pack)(NULL, depth_stencil_dw, &depth_stencil);
@ -181,22 +186,22 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
}
if (cmd_buffer->state.gfx.index_buffer &&
cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_INDEX_BUFFER |
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE)) {
((cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_INDEX_BUFFER)) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE))) {
struct anv_buffer *buffer = cmd_buffer->state.gfx.index_buffer;
uint32_t offset = cmd_buffer->state.gfx.index_offset;
#if GFX_VERx10 == 75
anv_batch_emit(&cmd_buffer->batch, GFX75_3DSTATE_VF, vf) {
vf.IndexedDrawCutIndexEnable = d->primitive_restart_enable;
vf.IndexedDrawCutIndexEnable = dyn->ia.primitive_restart_enable;
vf.CutIndex = cmd_buffer->state.gfx.restart_index;
}
#endif
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_INDEX_BUFFER), ib) {
#if GFX_VERx10 != 75
ib.CutIndexEnable = d->primitive_restart_enable;
ib.CutIndexEnable = dyn->ia.primitive_restart_enable;
#endif
ib.IndexFormat = cmd_buffer->state.gfx.index_type;
ib.MOCS = anv_mocs(cmd_buffer->device,
@ -213,14 +218,12 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
* threads or if we have dirty dynamic primitive topology state and
* need to toggle 3DSTATE_WM::MultisampleRasterizationMode dynamically.
*/
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE |
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY)) {
VkPolygonMode dynamic_raster_mode;
VkPrimitiveTopology primitive_topology = d->primitive_topology;
dynamic_raster_mode =
if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES)) {
VkPolygonMode dynamic_raster_mode =
genX(raster_polygon_mode)(cmd_buffer->state.gfx.pipeline,
primitive_topology);
dyn->ia.primitive_topology);
uint32_t dwords[GENX(3DSTATE_WM_length)];
struct GENX(3DSTATE_WM) wm = {
@ -238,18 +241,18 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
anv_batch_emit_merge(&cmd_buffer->batch, dwords, pipeline->gfx7.wm);
}
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,
d->sample_locations.samples,
d->sample_locations.locations);
if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_RENDER_TARGETS) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS)) {
const uint32_t samples = MAX2(1, cmd_buffer->state.gfx.samples);
const struct vk_sample_locations_state *sl = dyn->ms.sample_locations;
genX(emit_multisample)(&cmd_buffer->batch, samples,
sl->per_pixel == samples ? sl : NULL);
}
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE |
ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP)) {
const uint8_t color_writes = cmd_buffer->state.gfx.dynamic.color_writes;
if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_LOGIC_OP) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES)) {
const uint8_t color_writes = dyn->cb.color_write_enables;
/* Blend states of each RT */
uint32_t blend_dws[GENX(BLEND_STATE_length) +
@ -277,7 +280,7 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
.WriteDisableBlue = write_disabled ||
(pipeline->color_comp_writes[i] &
VK_COLOR_COMPONENT_B_BIT) == 0,
.LogicOpFunction = genX(vk_to_intel_logic_op)[d->logic_op],
.LogicOpFunction = genX(vk_to_intel_logic_op)[dyn->cb.logic_op],
};
GENX(BLEND_STATE_ENTRY_pack)(NULL, dws, &entry);
dws += GENX(BLEND_STATE_ENTRY_length);
@ -294,6 +297,8 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
}
}
/* When we're done, there is no more dirty gfx state. */
vk_dynamic_graphics_state_clear_dirty(&cmd_buffer->vk.dynamic_graphics_state);
cmd_buffer->state.gfx.dirty = 0;
}

View File

@ -198,6 +198,9 @@ want_depth_pma_fix(struct anv_cmd_buffer *cmd_buffer)
UNUSED static bool
want_stencil_pma_fix(struct anv_cmd_buffer *cmd_buffer)
{
const struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
if (GFX_VER > 9)
return false;
assert(GFX_VER == 9);
@ -293,8 +296,8 @@ want_stencil_pma_fix(struct anv_cmd_buffer *cmd_buffer)
*/
const bool stc_write_en =
cmd_buffer->state.gfx.stencil_att.iview != NULL &&
(cmd_buffer->state.gfx.dynamic.stencil_write_mask.front ||
cmd_buffer->state.gfx.dynamic.stencil_write_mask.back) &&
(dyn->ds.stencil.front.write_mask ||
dyn->ds.stencil.back.write_mask) &&
pipeline->writes_stencil;
/* STC_TEST_EN && 3DSTATE_PS_EXTRA::PixelShaderComputesStencil */
@ -320,39 +323,40 @@ void
genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
{
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
struct anv_dynamic_state *d = &cmd_buffer->state.gfx.dynamic;
const struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
#if GFX_VER >= 11
if (cmd_buffer->device->vk.enabled_extensions.KHR_fragment_shading_rate &&
cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE)
genX(emit_shading_rate)(&cmd_buffer->batch, pipeline, d);
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_FSR))
genX(emit_shading_rate)(&cmd_buffer->batch, pipeline, &dyn->fsr);
#endif /* GFX_VER >= 11 */
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH)) {
if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_LINE_WIDTH)) {
uint32_t sf_dw[GENX(3DSTATE_SF_length)];
struct GENX(3DSTATE_SF) sf = {
GENX(3DSTATE_SF_header),
};
#if GFX_VER == 8
if (cmd_buffer->device->info.platform == INTEL_PLATFORM_CHV) {
sf.CHVLineWidth = d->line_width;
sf.CHVLineWidth = dyn->rs.line.width;
} else {
sf.LineWidth = d->line_width;
sf.LineWidth = dyn->rs.line.width;
}
#else
sf.LineWidth = d->line_width,
sf.LineWidth = dyn->rs.line.width,
#endif
GENX(3DSTATE_SF_pack)(NULL, sf_dw, &sf);
anv_batch_emit_merge(&cmd_buffer->batch, sf_dw, pipeline->gfx8.sf);
}
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS |
ANV_CMD_DIRTY_DYNAMIC_CULL_MODE |
ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE |
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY)) {
if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_CULL_MODE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_FRONT_FACE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS)) {
/* Take dynamic primitive topology in to account with
* 3DSTATE_RASTER::APIMode
* 3DSTATE_RASTER::DXMultisampleRasterizationEnable
@ -363,15 +367,14 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
VkPolygonMode dynamic_raster_mode =
genX(raster_polygon_mode)(cmd_buffer->state.gfx.pipeline,
d->primitive_topology);
dyn->ia.primitive_topology);
genX(rasterization_mode)(
dynamic_raster_mode, pipeline->line_mode, d->line_width,
&api_mode, &msaa_raster_enable);
genX(rasterization_mode)(dynamic_raster_mode,
pipeline->line_mode, dyn->rs.line.width,
&api_mode, &msaa_raster_enable);
bool aa_enable =
anv_rasterization_aa_mode(dynamic_raster_mode,
pipeline->line_mode);
bool aa_enable = anv_rasterization_aa_mode(dynamic_raster_mode,
pipeline->line_mode);
uint32_t raster_dw[GENX(3DSTATE_RASTER_length)];
struct GENX(3DSTATE_RASTER) raster = {
@ -379,14 +382,14 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
.APIMode = api_mode,
.DXMultisampleRasterizationEnable = msaa_raster_enable,
.AntialiasingEnable = aa_enable,
.GlobalDepthOffsetConstant = d->depth_bias.bias,
.GlobalDepthOffsetScale = d->depth_bias.slope,
.GlobalDepthOffsetClamp = d->depth_bias.clamp,
.CullMode = genX(vk_to_intel_cullmode)[d->cull_mode],
.FrontWinding = genX(vk_to_intel_front_face)[d->front_face],
.GlobalDepthOffsetEnableSolid = d->depth_bias_enable,
.GlobalDepthOffsetEnableWireframe = d->depth_bias_enable,
.GlobalDepthOffsetEnablePoint = d->depth_bias_enable,
.CullMode = genX(vk_to_intel_cullmode)[dyn->rs.cull_mode],
.FrontWinding = genX(vk_to_intel_front_face)[dyn->rs.front_face],
.GlobalDepthOffsetEnableSolid = dyn->rs.depth_bias.enable,
.GlobalDepthOffsetEnableWireframe = dyn->rs.depth_bias.enable,
.GlobalDepthOffsetEnablePoint = dyn->rs.depth_bias.enable,
.GlobalDepthOffsetConstant = dyn->rs.depth_bias.constant,
.GlobalDepthOffsetScale = dyn->rs.depth_bias.slope,
.GlobalDepthOffsetClamp = dyn->rs.depth_bias.clamp,
};
GENX(3DSTATE_RASTER_pack)(NULL, raster_dw, &raster);
anv_batch_emit_merge(&cmd_buffer->batch, raster_dw,
@ -399,19 +402,19 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
* using a big old #if switch here.
*/
#if GFX_VER == 8
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE)) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS)) {
struct anv_state cc_state =
anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
GENX(COLOR_CALC_STATE_length) * 4,
64);
struct GENX(COLOR_CALC_STATE) cc = {
.BlendConstantColorRed = d->blend_constants[0],
.BlendConstantColorGreen = d->blend_constants[1],
.BlendConstantColorBlue = d->blend_constants[2],
.BlendConstantColorAlpha = d->blend_constants[3],
.StencilReferenceValue = d->stencil_reference.front & 0xff,
.BackfaceStencilReferenceValue = d->stencil_reference.back & 0xff,
.BlendConstantColorRed = dyn->cb.blend_constants[0],
.BlendConstantColorGreen = dyn->cb.blend_constants[1],
.BlendConstantColorBlue = dyn->cb.blend_constants[2],
.BlendConstantColorAlpha = dyn->cb.blend_constants[3],
.StencilReferenceValue = dyn->ds.stencil.front.reference & 0xff,
.BackfaceStencilReferenceValue = dyn->ds.stencil.back.reference & 0xff,
};
GENX(COLOR_CALC_STATE_pack)(NULL, cc_state.map, &cc);
@ -421,56 +424,58 @@ 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_RENDER_TARGETS |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP)) {
if ((cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_RENDER_TARGETS)) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_OP) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK)) {
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_WM_DEPTH_STENCIL), ds) {
ds.DoubleSidedStencilEnable = true;
ds.StencilTestMask = d->stencil_compare_mask.front & 0xff;
ds.StencilWriteMask = d->stencil_write_mask.front & 0xff;
ds.StencilTestMask = dyn->ds.stencil.front.compare_mask & 0xff;
ds.StencilWriteMask = dyn->ds.stencil.front.write_mask & 0xff;
ds.BackfaceStencilTestMask = d->stencil_compare_mask.back & 0xff;
ds.BackfaceStencilWriteMask = d->stencil_write_mask.back & 0xff;
ds.BackfaceStencilTestMask = dyn->ds.stencil.back.compare_mask & 0xff;
ds.BackfaceStencilWriteMask = dyn->ds.stencil.back.write_mask & 0xff;
ds.StencilBufferWriteEnable =
(d->stencil_write_mask.front || d->stencil_write_mask.back) &&
d->stencil_test_enable;
(dyn->ds.stencil.front.write_mask ||
dyn->ds.stencil.back.write_mask) &&
dyn->ds.stencil.test_enable;
ds.DepthTestEnable = d->depth_test_enable;
ds.DepthBufferWriteEnable = d->depth_test_enable && d->depth_write_enable;
ds.DepthTestFunction = genX(vk_to_intel_compare_op)[d->depth_compare_op];
ds.StencilTestEnable = d->stencil_test_enable;
ds.StencilFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.front.fail_op];
ds.StencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[d->stencil_op.front.pass_op];
ds.StencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.front.depth_fail_op];
ds.StencilTestFunction = genX(vk_to_intel_compare_op)[d->stencil_op.front.compare_op];
ds.BackfaceStencilFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.back.fail_op];
ds.BackfaceStencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[d->stencil_op.back.pass_op];
ds.BackfaceStencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.back.depth_fail_op];
ds.BackfaceStencilTestFunction = genX(vk_to_intel_compare_op)[d->stencil_op.back.compare_op];
ds.DepthTestEnable = dyn->ds.depth.test_enable;
ds.DepthBufferWriteEnable = dyn->ds.depth.test_enable &&
dyn->ds.depth.write_enable;
ds.DepthTestFunction = genX(vk_to_intel_compare_op)[dyn->ds.depth.compare_op];
ds.StencilTestEnable = dyn->ds.stencil.test_enable;
ds.StencilFailOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.front.op.fail];
ds.StencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.front.op.pass];
ds.StencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.front.op.depth_fail];
ds.StencilTestFunction = genX(vk_to_intel_compare_op)[dyn->ds.stencil.front.op.compare];
ds.BackfaceStencilFailOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.back.op.fail];
ds.BackfaceStencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.back.op.pass];
ds.BackfaceStencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.back.op.depth_fail];
ds.BackfaceStencilTestFunction = genX(vk_to_intel_compare_op)[dyn->ds.stencil.back.op.compare];
}
genX(cmd_buffer_enable_pma_fix)(cmd_buffer,
want_depth_pma_fix(cmd_buffer));
}
#else
if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS)) {
struct anv_state cc_state =
anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
GENX(COLOR_CALC_STATE_length) * 4,
64);
struct GENX(COLOR_CALC_STATE) cc = {
.BlendConstantColorRed = d->blend_constants[0],
.BlendConstantColorGreen = d->blend_constants[1],
.BlendConstantColorBlue = d->blend_constants[2],
.BlendConstantColorAlpha = d->blend_constants[3],
.BlendConstantColorRed = dyn->cb.blend_constants[0],
.BlendConstantColorGreen = dyn->cb.blend_constants[1],
.BlendConstantColorBlue = dyn->cb.blend_constants[2],
.BlendConstantColorAlpha = dyn->cb.blend_constants[3],
};
GENX(COLOR_CALC_STATE_pack)(NULL, cc_state.map, &cc);
@ -480,44 +485,46 @@ 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_RENDER_TARGETS |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP)) {
if ((cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_RENDER_TARGETS)) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_OP) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE)) {
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_WM_DEPTH_STENCIL), ds) {
ds.DoubleSidedStencilEnable = true;
ds.StencilTestMask = d->stencil_compare_mask.front & 0xff;
ds.StencilWriteMask = d->stencil_write_mask.front & 0xff;
ds.StencilTestMask = dyn->ds.stencil.front.compare_mask & 0xff;
ds.StencilWriteMask = dyn->ds.stencil.front.write_mask & 0xff;
ds.BackfaceStencilTestMask = d->stencil_compare_mask.back & 0xff;
ds.BackfaceStencilWriteMask = d->stencil_write_mask.back & 0xff;
ds.BackfaceStencilTestMask = dyn->ds.stencil.back.compare_mask & 0xff;
ds.BackfaceStencilWriteMask = dyn->ds.stencil.back.write_mask & 0xff;
ds.StencilReferenceValue = d->stencil_reference.front & 0xff;
ds.BackfaceStencilReferenceValue = d->stencil_reference.back & 0xff;
ds.StencilReferenceValue = dyn->ds.stencil.front.reference & 0xff;
ds.BackfaceStencilReferenceValue = dyn->ds.stencil.back.reference & 0xff;
ds.StencilBufferWriteEnable =
(d->stencil_write_mask.front || d->stencil_write_mask.back) &&
d->stencil_test_enable;
(dyn->ds.stencil.front.write_mask ||
dyn->ds.stencil.back.write_mask) &&
dyn->ds.stencil.test_enable;
ds.DepthTestEnable = d->depth_test_enable;
ds.DepthBufferWriteEnable = d->depth_test_enable && d->depth_write_enable;
ds.DepthTestFunction = genX(vk_to_intel_compare_op)[d->depth_compare_op];
ds.StencilTestEnable = d->stencil_test_enable;
ds.StencilFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.front.fail_op];
ds.StencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[d->stencil_op.front.pass_op];
ds.StencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.front.depth_fail_op];
ds.StencilTestFunction = genX(vk_to_intel_compare_op)[d->stencil_op.front.compare_op];
ds.BackfaceStencilFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.back.fail_op];
ds.BackfaceStencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[d->stencil_op.back.pass_op];
ds.BackfaceStencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.back.depth_fail_op];
ds.BackfaceStencilTestFunction = genX(vk_to_intel_compare_op)[d->stencil_op.back.compare_op];
ds.DepthTestEnable = dyn->ds.depth.test_enable;
ds.DepthBufferWriteEnable = dyn->ds.depth.test_enable &&
dyn->ds.depth.write_enable;
ds.DepthTestFunction = genX(vk_to_intel_compare_op)[dyn->ds.depth.compare_op];
ds.StencilTestEnable = dyn->ds.stencil.test_enable;
ds.StencilFailOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.front.op.fail];
ds.StencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.front.op.pass];
ds.StencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.front.op.depth_fail];
ds.StencilTestFunction = genX(vk_to_intel_compare_op)[dyn->ds.stencil.front.op.compare];
ds.BackfaceStencilFailOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.back.op.fail];
ds.BackfaceStencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.back.op.pass];
ds.BackfaceStencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[dyn->ds.stencil.back.op.depth_fail];
ds.BackfaceStencilTestFunction = genX(vk_to_intel_compare_op)[dyn->ds.stencil.back.op.compare];
}
@ -527,33 +534,33 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
#endif
#if GFX_VER >= 12
if(cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE)) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS)) {
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_DEPTH_BOUNDS), db) {
db.DepthBoundsTestEnable = d->depth_bounds_test_enable;
db.DepthBoundsTestMinValue = d->depth_bounds.min;
db.DepthBoundsTestMaxValue = d->depth_bounds.max;
db.DepthBoundsTestEnable = dyn->ds.depth.bounds_test.enable;
db.DepthBoundsTestMinValue = dyn->ds.depth.bounds_test.min;
db.DepthBoundsTestMaxValue = dyn->ds.depth.bounds_test.max;
}
}
#endif
if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_LINE_STIPPLE)) {
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_LINE_STIPPLE), ls) {
ls.LineStipplePattern = d->line_stipple.pattern;
ls.LineStipplePattern = dyn->rs.line.stipple.pattern;
ls.LineStippleInverseRepeatCount =
1.0f / MAX2(1, d->line_stipple.factor);
ls.LineStippleRepeatCount = d->line_stipple.factor;
1.0f / MAX2(1, dyn->rs.line.stipple.factor);
ls.LineStippleRepeatCount = dyn->rs.line.stipple.factor;
}
}
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_INDEX_BUFFER |
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE)) {
if ((cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_INDEX_BUFFER)) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE)) {
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VF), vf) {
#if GFX_VERx10 >= 125
vf.GeometryDistributionEnable = true;
#endif
vf.IndexedDrawCutIndexEnable = d->primitive_restart_enable;
vf.IndexedDrawCutIndexEnable = dyn->ia.primitive_restart_enable;
vf.CutIndex = cmd_buffer->state.gfx.restart_index;
}
}
@ -576,8 +583,8 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
}
#if GFX_VERx10 >= 125
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE)) {
if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE)) {
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VFG), vfg) {
/* If 3DSTATE_TE: TE Enable == 1 then RR_STRICT else RR_FREE*/
vfg.DistributionMode =
@ -587,7 +594,7 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
/* Wa_14014890652 */
if (intel_device_info_is_dg2(&cmd_buffer->device->info))
vfg.GranularityThresholdDisable = 1;
vfg.ListCutIndexEnable = d->primitive_restart_enable;
vfg.ListCutIndexEnable = dyn->ia.primitive_restart_enable;
/* 192 vertices for TRILIST_ADJ */
vfg.ListNBatchSizeScale = 0;
/* Batch size of 384 vertices */
@ -607,11 +614,11 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
#endif
if (pipeline->base.device->vk.enabled_extensions.EXT_sample_locations &&
cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS)
genX(emit_sample_pattern)(&cmd_buffer->batch, d);
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS))
genX(emit_sample_pattern)(&cmd_buffer->batch, dyn->ms.sample_locations);
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE)) {
if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES)) {
/* 3DSTATE_WM in the hope we can avoid spawning fragment shaders
* threads.
*/
@ -629,10 +636,10 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
anv_batch_emit_merge(&cmd_buffer->batch, wm_dwords, pipeline->gfx8.wm);
}
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE |
ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP)) {
const uint8_t color_writes = d->color_writes;
if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_LOGIC_OP) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES)) {
const uint8_t color_writes = dyn->cb.color_write_enables;
const struct anv_cmd_graphics_state *state = &cmd_buffer->state.gfx;
bool has_writeable_rt =
anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT) &&
@ -675,7 +682,7 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
.WriteDisableBlue = write_disabled ||
(pipeline->color_comp_writes[i] &
VK_COLOR_COMPONENT_B_BIT) == 0,
.LogicOpFunction = genX(vk_to_intel_logic_op)[d->logic_op],
.LogicOpFunction = genX(vk_to_intel_logic_op)[dyn->cb.logic_op],
};
GENX(BLEND_STATE_ENTRY_pack)(NULL, dws, &entry);
dws += GENX(BLEND_STATE_ENTRY_length);
@ -693,5 +700,7 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
}
}
/* When we're done, there is no more dirty gfx state. */
vk_dynamic_graphics_state_clear_dirty(&cmd_buffer->vk.dynamic_graphics_state);
cmd_buffer->state.gfx.dirty = 0;
}