From 556c9401495930c23a10ca2a26db098d12663e27 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Fri, 13 Sep 2019 13:40:44 +0200 Subject: [PATCH] radv: implement VK_EXT_line_rasterization Only Bresenham lines are supported. GFX9 is currently disabled because there is some CTS failures for some weird reasons. Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen Tested-by: Marge Bot Part-of: --- src/amd/vulkan/radv_cmd_buffer.c | 45 +++++++++++++++++++++++++++++++++++++++ src/amd/vulkan/radv_device.c | 17 +++++++++++++++ src/amd/vulkan/radv_extensions.py | 2 ++ src/amd/vulkan/radv_pipeline.c | 33 ++++++++++++++++++++++++++++ src/amd/vulkan/radv_private.h | 22 +++++++++++++------ 5 files changed, 112 insertions(+), 7 deletions(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index d516c26..66c7d07 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -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; } @@ -1318,6 +1330,22 @@ radv_emit_depth_bias(struct radv_cmd_buffer *cmd_buffer) } 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, struct radv_color_buffer_info *cb, @@ -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, diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index a016ff3..ca0909f 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -1270,6 +1270,17 @@ void radv_GetPhysicalDeviceFeatures2( features->subgroupBroadcastDynamicId = true; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: { + VkPhysicalDeviceLineRasterizationFeaturesEXT *features = + (VkPhysicalDeviceLineRasterizationFeaturesEXT *)ext; + features->rectangularLines = false; + features->bresenhamLines = true; + features->smoothLines = false; + features->stippledRectangularLines = false; + features->stippledBresenhamLines = true; + features->stippledSmoothLines = false; + break; + } default: break; } @@ -1889,6 +1900,12 @@ void radv_GetPhysicalDeviceProperties2( case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES: radv_get_physical_device_properties_1_2(pdevice, (void *)ext); break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT: { + VkPhysicalDeviceLineRasterizationPropertiesEXT *props = + (VkPhysicalDeviceLineRasterizationPropertiesEXT *)ext; + props->lineSubPixelPrecisionBits = 4; + break; + } default: break; } diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py index 57aa67b..32e14a6 100644 --- a/src/amd/vulkan/radv_extensions.py +++ b/src/amd/vulkan/radv_extensions.py @@ -128,6 +128,8 @@ EXTENSIONS = [ Extension('VK_EXT_host_query_reset', 1, True), Extension('VK_EXT_index_type_uint8', 1, 'device->rad_info.chip_class >= GFX8'), Extension('VK_EXT_inline_uniform_block', 1, True), + # Disable line rasterization on GFX9 until the CTS failures have been resolved. + Extension('VK_EXT_line_rasterization', 1, 'device->rad_info.chip_class != GFX9'), Extension('VK_EXT_memory_budget', 1, True), Extension('VK_EXT_memory_priority', 1, True), Extension('VK_EXT_pci_bus_info', 2, True), diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index b065ca4..c3c69b3 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -1242,6 +1242,23 @@ radv_pipeline_init_multisample_state(struct radv_pipeline *pipeline, ms->pa_sc_mode_cntl_0 = S_028A48_ALTERNATE_RBS_PER_TILE(pipeline->device->physical_device->rad_info.chip_class >= GFX9) | S_028A48_VPORT_SCISSOR_ENABLE(1); + const VkPipelineRasterizationLineStateCreateInfoEXT *rast_line = + vk_find_struct_const(pCreateInfo->pRasterizationState->pNext, + PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT); + if (rast_line) { + ms->pa_sc_mode_cntl_0 |= S_028A48_LINE_STIPPLE_ENABLE(rast_line->stippledLineEnable); + if (rast_line->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT) { + /* From the Vulkan spec 1.1.129: + * + * "When VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT lines + * are being rasterized, sample locations may all be + * treated as being at the pixel center (this may + * affect attribute and depth interpolation)." + */ + ms->num_samples = 1; + } + } + if (ms->num_samples > 1) { RADV_FROM_HANDLE(radv_render_pass, pass, pCreateInfo->renderPass); struct radv_subpass *subpass = &pass->subpasses[pCreateInfo->subpass]; @@ -1397,6 +1414,8 @@ static unsigned radv_dynamic_state_mask(VkDynamicState state) return RADV_DYNAMIC_DISCARD_RECTANGLE; case VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT: return RADV_DYNAMIC_SAMPLE_LOCATIONS; + case VK_DYNAMIC_STATE_LINE_STIPPLE_EXT: + return RADV_DYNAMIC_LINE_STIPPLE; default: unreachable("Unhandled dynamic state"); } @@ -1432,6 +1451,11 @@ static uint32_t radv_pipeline_needed_dynamic_state(const VkGraphicsPipelineCreat PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT)) states &= ~RADV_DYNAMIC_SAMPLE_LOCATIONS; + if (!pCreateInfo->pRasterizationState || + !vk_find_struct_const(pCreateInfo->pRasterizationState->pNext, + PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT)) + states &= ~RADV_DYNAMIC_LINE_STIPPLE; + /* TODO: blend constants & line width. */ return states; @@ -1584,6 +1608,14 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline, } } + const VkPipelineRasterizationLineStateCreateInfoEXT *rast_line_info = + vk_find_struct_const(pCreateInfo->pRasterizationState->pNext, + PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT); + if (needed_states & RADV_DYNAMIC_LINE_STIPPLE) { + dynamic->line_stipple.factor = rast_line_info->lineStippleFactor; + dynamic->line_stipple.pattern = rast_line_info->lineStipplePattern; + } + pipeline->dynamic_state.mask = states; } @@ -5019,6 +5051,7 @@ radv_pipeline_init(struct radv_pipeline *pipeline, uint32_t gs_out; uint32_t prim = si_translate_prim(pCreateInfo->pInputAssemblyState->topology); + pipeline->graphics.topology = pCreateInfo->pInputAssemblyState->topology; pipeline->graphics.can_use_guardband = radv_prim_can_use_guardband(pCreateInfo->pInputAssemblyState->topology); if (radv_pipeline_has_gs(pipeline)) { diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 537355f..af2f058 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -971,7 +971,8 @@ enum radv_dynamic_state_bits { RADV_DYNAMIC_STENCIL_REFERENCE = 1 << 8, RADV_DYNAMIC_DISCARD_RECTANGLE = 1 << 9, RADV_DYNAMIC_SAMPLE_LOCATIONS = 1 << 10, - RADV_DYNAMIC_ALL = (1 << 11) - 1, + RADV_DYNAMIC_LINE_STIPPLE = 1 << 11, + RADV_DYNAMIC_ALL = (1 << 12) - 1, }; enum radv_cmd_dirty_bits { @@ -988,12 +989,13 @@ enum radv_cmd_dirty_bits { RADV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE = 1 << 8, RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE = 1 << 9, RADV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS = 1 << 10, - RADV_CMD_DIRTY_DYNAMIC_ALL = (1 << 11) - 1, - RADV_CMD_DIRTY_PIPELINE = 1 << 11, - RADV_CMD_DIRTY_INDEX_BUFFER = 1 << 12, - RADV_CMD_DIRTY_FRAMEBUFFER = 1 << 13, - RADV_CMD_DIRTY_VERTEX_BUFFER = 1 << 14, - RADV_CMD_DIRTY_STREAMOUT_BUFFER = 1 << 15, + RADV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE = 1 << 11, + RADV_CMD_DIRTY_DYNAMIC_ALL = (1 << 12) - 1, + RADV_CMD_DIRTY_PIPELINE = 1 << 12, + RADV_CMD_DIRTY_INDEX_BUFFER = 1 << 13, + RADV_CMD_DIRTY_FRAMEBUFFER = 1 << 14, + RADV_CMD_DIRTY_VERTEX_BUFFER = 1 << 15, + RADV_CMD_DIRTY_STREAMOUT_BUFFER = 1 << 16, }; enum radv_cmd_flush_bits { @@ -1125,6 +1127,11 @@ struct radv_dynamic_state { struct radv_discard_rectangle_state discard_rectangle; struct radv_sample_locations_state sample_location; + + struct { + uint32_t factor; + uint16_t pattern; + } line_stipple; }; extern const struct radv_dynamic_state default_dynamic_state; @@ -1640,6 +1647,7 @@ struct radv_pipeline { bool can_use_guardband; uint32_t needed_dynamic_state; bool disable_out_of_order_rast_for_occlusion; + uint8_t topology; /* Used for rbplus */ uint32_t col_format; -- 2.7.4