diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index 8ef04677601..b3a2a2cc2e1 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -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) diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h index 0df5f8219d8..102514d5e7d 100644 --- a/src/intel/vulkan/anv_genX.h +++ b/src/intel/vulkan/anv_genX.h @@ -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, diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c index 20d5e0f9e5c..453760a5f7e 100644 --- a/src/intel/vulkan/anv_pipeline.c +++ b/src/intel/vulkan/anv_pipeline.c @@ -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. */ diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 8be0252f22c..5babcf1ee77 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -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) diff --git a/src/intel/vulkan/genX_blorp_exec.c b/src/intel/vulkan/genX_blorp_exec.c index 05452cd5003..e85f96b9624 100644 --- a/src/intel/vulkan/genX_blorp_exec.c +++ b/src/intel/vulkan/genX_blorp_exec.c @@ -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; } diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 4c2787834f4..0ef0c40b398 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -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; diff --git a/src/intel/vulkan/genX_gpu_memcpy.c b/src/intel/vulkan/genX_gpu_memcpy.c index 1ec94158c4d..76839ac25f2 100644 --- a/src/intel/vulkan/genX_gpu_memcpy.c +++ b/src/intel/vulkan/genX_gpu_memcpy.c @@ -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); } diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c index 2105eefbec0..2508de9d66c 100644 --- a/src/intel/vulkan/genX_pipeline.c +++ b/src/intel/vulkan/genX_pipeline.c @@ -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 diff --git a/src/intel/vulkan/genX_state.c b/src/intel/vulkan/genX_state.c index 2a3c3732dcf..dd2355146fe 100644 --- a/src/intel/vulkan/genX_state.c +++ b/src/intel/vulkan/genX_state.c @@ -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 } diff --git a/src/intel/vulkan/gfx7_cmd_buffer.c b/src/intel/vulkan/gfx7_cmd_buffer.c index 5d778e40f0b..32bf9645cc4 100644 --- a/src/intel/vulkan/gfx7_cmd_buffer.c +++ b/src/intel/vulkan/gfx7_cmd_buffer.c @@ -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; } diff --git a/src/intel/vulkan/gfx8_cmd_buffer.c b/src/intel/vulkan/gfx8_cmd_buffer.c index 98b31fb5a35..d2ef8816a82 100644 --- a/src/intel/vulkan/gfx8_cmd_buffer.c +++ b/src/intel/vulkan/gfx8_cmd_buffer.c @@ -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; }