anv: Switch to using common dynamic state tracking
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17564>
This commit is contained in:
parent
cc89232f2e
commit
7d25c04236
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue