*/
dest->viewport.count = src->viewport.count;
dest->scissor.count = src->scissor.count;
+ dest->discard_rectangle.count = src->discard_rectangle.count;
- if (copy_mask & (1 << VK_DYNAMIC_STATE_VIEWPORT)) {
+ if (copy_mask & RADV_DYNAMIC_VIEWPORT) {
if (memcmp(&dest->viewport.viewports, &src->viewport.viewports,
src->viewport.count * sizeof(VkViewport))) {
typed_memcpy(dest->viewport.viewports,
src->viewport.viewports,
src->viewport.count);
- dest_mask |= 1 << VK_DYNAMIC_STATE_VIEWPORT;
+ dest_mask |= RADV_DYNAMIC_VIEWPORT;
}
}
- if (copy_mask & (1 << VK_DYNAMIC_STATE_SCISSOR)) {
+ if (copy_mask & RADV_DYNAMIC_SCISSOR) {
if (memcmp(&dest->scissor.scissors, &src->scissor.scissors,
src->scissor.count * sizeof(VkRect2D))) {
typed_memcpy(dest->scissor.scissors,
src->scissor.scissors, src->scissor.count);
- dest_mask |= 1 << VK_DYNAMIC_STATE_SCISSOR;
+ dest_mask |= RADV_DYNAMIC_SCISSOR;
}
}
- if (copy_mask & (1 << VK_DYNAMIC_STATE_LINE_WIDTH)) {
+ if (copy_mask & RADV_DYNAMIC_LINE_WIDTH) {
if (dest->line_width != src->line_width) {
dest->line_width = src->line_width;
- dest_mask |= 1 << VK_DYNAMIC_STATE_LINE_WIDTH;
+ dest_mask |= RADV_DYNAMIC_LINE_WIDTH;
}
}
- if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BIAS)) {
+ if (copy_mask & RADV_DYNAMIC_DEPTH_BIAS) {
if (memcmp(&dest->depth_bias, &src->depth_bias,
sizeof(src->depth_bias))) {
dest->depth_bias = src->depth_bias;
- dest_mask |= 1 << VK_DYNAMIC_STATE_DEPTH_BIAS;
+ dest_mask |= RADV_DYNAMIC_DEPTH_BIAS;
}
}
- if (copy_mask & (1 << VK_DYNAMIC_STATE_BLEND_CONSTANTS)) {
+ if (copy_mask & RADV_DYNAMIC_BLEND_CONSTANTS) {
if (memcmp(&dest->blend_constants, &src->blend_constants,
sizeof(src->blend_constants))) {
typed_memcpy(dest->blend_constants,
src->blend_constants, 4);
- dest_mask |= 1 << VK_DYNAMIC_STATE_BLEND_CONSTANTS;
+ dest_mask |= RADV_DYNAMIC_BLEND_CONSTANTS;
}
}
- if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS)) {
+ if (copy_mask & RADV_DYNAMIC_DEPTH_BOUNDS) {
if (memcmp(&dest->depth_bounds, &src->depth_bounds,
sizeof(src->depth_bounds))) {
dest->depth_bounds = src->depth_bounds;
- dest_mask |= 1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS;
+ dest_mask |= RADV_DYNAMIC_DEPTH_BOUNDS;
}
}
- if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK)) {
+ if (copy_mask & RADV_DYNAMIC_STENCIL_COMPARE_MASK) {
if (memcmp(&dest->stencil_compare_mask,
&src->stencil_compare_mask,
sizeof(src->stencil_compare_mask))) {
dest->stencil_compare_mask = src->stencil_compare_mask;
- dest_mask |= 1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
+ dest_mask |= RADV_DYNAMIC_STENCIL_COMPARE_MASK;
}
}
- if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) {
+ if (copy_mask & RADV_DYNAMIC_STENCIL_WRITE_MASK) {
if (memcmp(&dest->stencil_write_mask, &src->stencil_write_mask,
sizeof(src->stencil_write_mask))) {
dest->stencil_write_mask = src->stencil_write_mask;
- dest_mask |= 1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
+ dest_mask |= RADV_DYNAMIC_STENCIL_WRITE_MASK;
}
}
- if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE)) {
+ if (copy_mask & RADV_DYNAMIC_STENCIL_REFERENCE) {
if (memcmp(&dest->stencil_reference, &src->stencil_reference,
sizeof(src->stencil_reference))) {
dest->stencil_reference = src->stencil_reference;
- dest_mask |= 1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE;
+ dest_mask |= RADV_DYNAMIC_STENCIL_REFERENCE;
+ }
+ }
+
+ if (copy_mask & RADV_DYNAMIC_DISCARD_RECTANGLE) {
+ if (memcmp(&dest->discard_rectangle.rectangles, &src->discard_rectangle.rectangles,
+ src->discard_rectangle.count * sizeof(VkRect2D))) {
+ typed_memcpy(dest->discard_rectangle.rectangles,
+ src->discard_rectangle.rectangles,
+ src->discard_rectangle.count);
+ dest_mask |= RADV_DYNAMIC_DISCARD_RECTANGLE;
}
}
}
radeon_set_context_reg(cmd_buffer->cs, R_028A6C_VGT_GS_OUT_PRIM_TYPE, pipeline->graphics.gs_out);
+ radeon_set_context_reg(cmd_buffer->cs, R_02820C_PA_SC_CLIPRECT_RULE, pipeline->graphics.pa_sc_cliprect_rule);
+
if (unlikely(cmd_buffer->device->trace_bo))
radv_save_pipeline(cmd_buffer, pipeline, RING_GFX);
cmd_buffer->state.pipeline->graphics.ms.pa_sc_mode_cntl_0 | S_028A48_VPORT_SCISSOR_ENABLE(count ? 1 : 0));
}
+static void
+radv_emit_discard_rectangle(struct radv_cmd_buffer *cmd_buffer)
+{
+ if (!cmd_buffer->state.dynamic.discard_rectangle.count)
+ return;
+
+ radeon_set_context_reg_seq(cmd_buffer->cs, R_028210_PA_SC_CLIPRECT_0_TL,
+ cmd_buffer->state.dynamic.discard_rectangle.count * 2);
+ for (unsigned i = 0; i < cmd_buffer->state.dynamic.discard_rectangle.count; ++i) {
+ VkRect2D rect = cmd_buffer->state.dynamic.discard_rectangle.rectangles[i];
+ radeon_emit(cmd_buffer->cs, S_028210_TL_X(rect.offset.x) | S_028210_TL_Y(rect.offset.y));
+ radeon_emit(cmd_buffer->cs, S_028214_BR_X(rect.offset.x + rect.extent.width) |
+ S_028214_BR_Y(rect.offset.y + rect.extent.height));
+ }
+}
+
static void
radv_emit_line_width(struct radv_cmd_buffer *cmd_buffer)
{
RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS))
radv_emit_depth_biais(cmd_buffer);
+ if (cmd_buffer->state.dirty & RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE)
+ radv_emit_discard_rectangle(cmd_buffer);
+
cmd_buffer->state.dirty &= ~RADV_CMD_DIRTY_DYNAMIC_ALL;
}
const VkViewport* pViewports)
{
RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+ struct radv_cmd_state *state = &cmd_buffer->state;
MAYBE_UNUSED const uint32_t total_count = firstViewport + viewportCount;
assert(firstViewport < MAX_VIEWPORTS);
assert(total_count >= 1 && total_count <= MAX_VIEWPORTS);
- memcpy(cmd_buffer->state.dynamic.viewport.viewports + firstViewport,
- pViewports, viewportCount * sizeof(*pViewports));
+ if (cmd_buffer->device->physical_device->has_scissor_bug) {
+ /* Try to skip unnecessary PS partial flushes when the viewports
+ * don't change.
+ */
+ if (!(state->dirty & (RADV_CMD_DIRTY_DYNAMIC_VIEWPORT |
+ RADV_CMD_DIRTY_DYNAMIC_SCISSOR)) &&
+ !memcmp(state->dynamic.viewport.viewports + firstViewport,
+ pViewports, viewportCount * sizeof(*pViewports))) {
+ return;
+ }
+ }
+
+ memcpy(state->dynamic.viewport.viewports + firstViewport, pViewports,
+ viewportCount * sizeof(*pViewports));
- cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_VIEWPORT;
+ state->dirty |= RADV_CMD_DIRTY_DYNAMIC_VIEWPORT;
}
void radv_CmdSetScissor(
const VkRect2D* pScissors)
{
RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+ struct radv_cmd_state *state = &cmd_buffer->state;
MAYBE_UNUSED const uint32_t total_count = firstScissor + scissorCount;
assert(firstScissor < MAX_SCISSORS);
assert(total_count >= 1 && total_count <= MAX_SCISSORS);
- memcpy(cmd_buffer->state.dynamic.scissor.scissors + firstScissor,
- pScissors, scissorCount * sizeof(*pScissors));
- cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_SCISSOR;
+ if (cmd_buffer->device->physical_device->has_scissor_bug) {
+ /* Try to skip unnecessary PS partial flushes when the scissors
+ * don't change.
+ */
+ if (!(state->dirty & (RADV_CMD_DIRTY_DYNAMIC_VIEWPORT |
+ RADV_CMD_DIRTY_DYNAMIC_SCISSOR)) &&
+ !memcmp(state->dynamic.scissor.scissors + firstScissor,
+ pScissors, scissorCount * sizeof(*pScissors))) {
+ return;
+ }
+ }
+
+ memcpy(state->dynamic.scissor.scissors + firstScissor, pScissors,
+ scissorCount * sizeof(*pScissors));
+
+ state->dirty |= RADV_CMD_DIRTY_DYNAMIC_SCISSOR;
}
void radv_CmdSetLineWidth(
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;
}
+void radv_CmdSetDiscardRectangleEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstDiscardRectangle,
+ uint32_t discardRectangleCount,
+ const VkRect2D* pDiscardRectangles)
+{
+ RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+ struct radv_cmd_state *state = &cmd_buffer->state;
+ MAYBE_UNUSED const uint32_t total_count = firstDiscardRectangle + discardRectangleCount;
+
+ assert(firstDiscardRectangle < MAX_DISCARD_RECTANGLES);
+ assert(total_count >= 1 && total_count <= MAX_DISCARD_RECTANGLES);
+
+ typed_memcpy(&state->dynamic.discard_rectangle.rectangles[firstDiscardRectangle],
+ pDiscardRectangles, discardRectangleCount);
+
+ state->dirty |= RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE;
+}
+
void radv_CmdExecuteCommands(
VkCommandBuffer commandBuffer,
uint32_t commandBufferCount,