radv: implement VK_EXT_line_rasterization
[mesa.git] / src / amd / vulkan / radv_cmd_buffer.c
index d516c26d96c604706a6402c89c9e96d454a6be4f..66c7d0721ba9dc58984b54c3bdfacac9b81f46ac 100644 (file)
@@ -92,6 +92,10 @@ const struct radv_dynamic_state default_dynamic_state = {
                .front = 0u,
                .back = 0u,
        },
+       .line_stipple = {
+               .factor = 0u,
+               .pattern = 0u,
+       },
 };
 
 static void
@@ -212,6 +216,14 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer,
                }
        }
 
+       if (copy_mask & RADV_DYNAMIC_LINE_STIPPLE) {
+               if (memcmp(&dest->line_stipple, &src->line_stipple,
+                          sizeof(src->line_stipple))) {
+                       dest->line_stipple = src->line_stipple;
+                       dest_mask |= RADV_DYNAMIC_LINE_STIPPLE;
+               }
+       }
+
        cmd_buffer->state.dirty |= dest_mask;
 }
 
@@ -1317,6 +1329,22 @@ radv_emit_depth_bias(struct radv_cmd_buffer *cmd_buffer)
        radeon_emit(cmd_buffer->cs, bias); /* BACK OFFSET */
 }
 
+static void
+radv_emit_line_stipple(struct radv_cmd_buffer *cmd_buffer)
+{
+       struct radv_dynamic_state *d = &cmd_buffer->state.dynamic;
+       struct radv_pipeline *pipeline = cmd_buffer->state.pipeline;
+       uint32_t auto_reset_cntl = 1;
+
+       if (pipeline->graphics.topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP)
+               auto_reset_cntl = 2;
+
+       radeon_set_context_reg(cmd_buffer->cs, R_028A0C_PA_SC_LINE_STIPPLE,
+                              S_028A0C_LINE_PATTERN(d->line_stipple.pattern) |
+                              S_028A0C_REPEAT_COUNT(d->line_stipple.factor - 1) |
+                              S_028A0C_AUTO_RESET_CNTL(auto_reset_cntl));
+}
+
 static void
 radv_emit_fb_color_state(struct radv_cmd_buffer *cmd_buffer,
                         int index,
@@ -2202,6 +2230,9 @@ radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer)
        if (states & RADV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS)
                radv_emit_sample_locations(cmd_buffer);
 
+       if (states & RADV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE)
+               radv_emit_line_stipple(cmd_buffer);
+
        cmd_buffer->state.dirty &= ~states;
 }
 
@@ -4107,6 +4138,20 @@ void radv_CmdSetSampleLocationsEXT(
        state->dirty |= RADV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS;
 }
 
+void radv_CmdSetLineStippleEXT(
+       VkCommandBuffer                             commandBuffer,
+       uint32_t                                    lineStippleFactor,
+       uint16_t                                    lineStipplePattern)
+{
+       RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+       struct radv_cmd_state *state = &cmd_buffer->state;
+
+       state->dynamic.line_stipple.factor = lineStippleFactor;
+       state->dynamic.line_stipple.pattern = lineStipplePattern;
+
+       state->dirty |= RADV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE;
+}
+
 void radv_CmdExecuteCommands(
        VkCommandBuffer                             commandBuffer,
        uint32_t                                    commandBufferCount,