.factor = 0u,
.pattern = 0u,
},
+ .cull_mode = 0u,
+ .front_face = 0u,
};
static void
}
}
+ if (copy_mask & RADV_DYNAMIC_CULL_MODE) {
+ if (dest->cull_mode != src->cull_mode) {
+ dest->cull_mode = src->cull_mode;
+ dest_mask |= RADV_DYNAMIC_CULL_MODE;
+ }
+ }
+
+ if (copy_mask & RADV_DYNAMIC_FRONT_FACE) {
+ if (dest->front_face != src->front_face) {
+ dest->front_face = src->front_face;
+ dest_mask |= RADV_DYNAMIC_FRONT_FACE;
+ }
+ }
+
cmd_buffer->state.dirty |= dest_mask;
}
pipeline->graphics.can_use_guardband)
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_SCISSOR;
+ if (!cmd_buffer->state.emitted_pipeline ||
+ cmd_buffer->state.emitted_pipeline->graphics.pa_su_sc_mode_cntl !=
+ pipeline->graphics.pa_su_sc_mode_cntl)
+ cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_CULL_MODE |
+ RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
+
radeon_emit_array(cmd_buffer->cs, pipeline->cs.buf, pipeline->cs.cdw);
if (!cmd_buffer->state.emitted_pipeline ||
S_028A0C_AUTO_RESET_CNTL(auto_reset_cntl));
}
+static void
+radv_emit_culling(struct radv_cmd_buffer *cmd_buffer, uint32_t states)
+{
+ unsigned pa_su_sc_mode_cntl = cmd_buffer->state.pipeline->graphics.pa_su_sc_mode_cntl;
+ struct radv_dynamic_state *d = &cmd_buffer->state.dynamic;
+
+ if (states & RADV_CMD_DIRTY_DYNAMIC_CULL_MODE) {
+ pa_su_sc_mode_cntl &= C_028814_CULL_FRONT;
+ pa_su_sc_mode_cntl |= S_028814_CULL_FRONT(!!(d->cull_mode & VK_CULL_MODE_FRONT_BIT));
+
+ pa_su_sc_mode_cntl &= C_028814_CULL_BACK;
+ pa_su_sc_mode_cntl |= S_028814_CULL_BACK(!!(d->cull_mode & VK_CULL_MODE_BACK_BIT));
+ }
+
+ if (states & RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE) {
+ pa_su_sc_mode_cntl &= C_028814_FACE;
+ pa_su_sc_mode_cntl |= S_028814_FACE(d->front_face);
+ }
+
+ radeon_set_context_reg(cmd_buffer->cs, R_028814_PA_SU_SC_MODE_CNTL,
+ pa_su_sc_mode_cntl);
+}
+
static void
radv_emit_fb_color_state(struct radv_cmd_buffer *cmd_buffer,
int index,
if (states & RADV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE)
radv_emit_line_stipple(cmd_buffer);
+ if (states & (RADV_CMD_DIRTY_DYNAMIC_CULL_MODE |
+ RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE))
+ radv_emit_culling(cmd_buffer, states);
+
cmd_buffer->state.dirty &= ~states;
}
state->dirty |= RADV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE;
}
+void radv_CmdSetCullModeEXT(
+ VkCommandBuffer commandBuffer,
+ VkCullModeFlags cullMode)
+{
+ RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+ struct radv_cmd_state *state = &cmd_buffer->state;
+
+ if (state->dynamic.cull_mode == cullMode)
+ return;
+
+ state->dynamic.cull_mode = cullMode;
+
+ state->dirty |= RADV_CMD_DIRTY_DYNAMIC_CULL_MODE;
+}
+
+void radv_CmdSetFrontFaceEXT(
+ VkCommandBuffer commandBuffer,
+ VkFrontFace frontFace)
+{
+ RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+ struct radv_cmd_state *state = &cmd_buffer->state;
+
+ if (state->dynamic.front_face == frontFace)
+ return;
+
+ state->dynamic.front_face = frontFace;
+
+ state->dirty |= RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
+}
+
void radv_CmdExecuteCommands(
VkCommandBuffer commandBuffer,
uint32_t commandBufferCount,
typed_memcpy(state->scissor.scissors,
cmd_buffer->state.dynamic.scissor.scissors,
MAX_SCISSORS);
+
+ state->cull_mode = cmd_buffer->state.dynamic.cull_mode;
+ state->front_face = cmd_buffer->state.dynamic.front_face;
}
if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {
state->scissor.scissors,
MAX_SCISSORS);
+ cmd_buffer->state.dynamic.cull_mode = state->cull_mode;
+ cmd_buffer->state.dynamic.front_face = state->front_face;
+
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_VIEWPORT |
- RADV_CMD_DIRTY_DYNAMIC_SCISSOR;
+ RADV_CMD_DIRTY_DYNAMIC_SCISSOR |
+ RADV_CMD_DIRTY_DYNAMIC_CULL_MODE |
+ RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
}
if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {
struct radv_attachment_state *attachments;
struct radv_framebuffer *framebuffer;
VkRect2D render_area;
+
+ VkCullModeFlags cull_mode;
+ VkFrontFace front_face;
};
VkResult radv_device_init_meta_clear_state(struct radv_device *device, bool on_demand);
return RADV_DYNAMIC_SAMPLE_LOCATIONS;
case VK_DYNAMIC_STATE_LINE_STIPPLE_EXT:
return RADV_DYNAMIC_LINE_STIPPLE;
+ case VK_DYNAMIC_STATE_CULL_MODE_EXT:
+ return RADV_DYNAMIC_CULL_MODE;
+ case VK_DYNAMIC_STATE_FRONT_FACE_EXT:
+ return RADV_DYNAMIC_FRONT_FACE;
default:
unreachable("Unhandled dynamic state");
}
pCreateInfo->pColorBlendState->blendConstants, 4);
}
+ if (states & RADV_DYNAMIC_CULL_MODE) {
+ dynamic->cull_mode =
+ pCreateInfo->pRasterizationState->cullMode;
+ }
+
+ if (states & RADV_DYNAMIC_FRONT_FACE) {
+ dynamic->front_face =
+ pCreateInfo->pRasterizationState->frontFace;
+ }
+
/* If there is no depthstencil attachment, then don't read
* pDepthStencilState. The Vulkan spec states that pDepthStencilState may
* be NULL in this case. Even if pDepthStencilState is non-NULL, there is
S_028BE4_ROUND_MODE(V_028BE4_X_ROUND_TO_EVEN) |
S_028BE4_QUANT_MODE(V_028BE4_X_16_8_FIXED_POINT_1_256TH));
- radeon_set_context_reg(ctx_cs, R_028814_PA_SU_SC_MODE_CNTL,
- S_028814_FACE(vkraster->frontFace) |
- S_028814_CULL_FRONT(!!(vkraster->cullMode & VK_CULL_MODE_FRONT_BIT)) |
- S_028814_CULL_BACK(!!(vkraster->cullMode & VK_CULL_MODE_BACK_BIT)) |
- S_028814_POLY_MODE(vkraster->polygonMode != VK_POLYGON_MODE_FILL) |
- S_028814_POLYMODE_FRONT_PTYPE(si_translate_fill(vkraster->polygonMode)) |
- S_028814_POLYMODE_BACK_PTYPE(si_translate_fill(vkraster->polygonMode)) |
- S_028814_POLY_OFFSET_FRONT_ENABLE(vkraster->depthBiasEnable ? 1 : 0) |
- S_028814_POLY_OFFSET_BACK_ENABLE(vkraster->depthBiasEnable ? 1 : 0) |
- S_028814_POLY_OFFSET_PARA_ENABLE(vkraster->depthBiasEnable ? 1 : 0));
+ pipeline->graphics.pa_su_sc_mode_cntl =
+ S_028814_FACE(vkraster->frontFace) |
+ S_028814_CULL_FRONT(!!(vkraster->cullMode & VK_CULL_MODE_FRONT_BIT)) |
+ S_028814_CULL_BACK(!!(vkraster->cullMode & VK_CULL_MODE_BACK_BIT)) |
+ S_028814_POLY_MODE(vkraster->polygonMode != VK_POLYGON_MODE_FILL) |
+ S_028814_POLYMODE_FRONT_PTYPE(si_translate_fill(vkraster->polygonMode)) |
+ S_028814_POLYMODE_BACK_PTYPE(si_translate_fill(vkraster->polygonMode)) |
+ S_028814_POLY_OFFSET_FRONT_ENABLE(vkraster->depthBiasEnable ? 1 : 0) |
+ S_028814_POLY_OFFSET_BACK_ENABLE(vkraster->depthBiasEnable ? 1 : 0) |
+ S_028814_POLY_OFFSET_PARA_ENABLE(vkraster->depthBiasEnable ? 1 : 0);
/* Conservative rasterization. */
if (mode != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT) {
uint32_t factor;
uint16_t pattern;
} line_stipple;
+
+ VkCullModeFlags cull_mode;
+ VkFrontFace front_face;
};
extern const struct radv_dynamic_state default_dynamic_state;
bool disable_out_of_order_rast_for_occlusion;
uint8_t topology;
unsigned tess_patch_control_points;
+ unsigned pa_su_sc_mode_cntl;
/* Used for rbplus */
uint32_t col_format;