diff options
author | Fredrik Höglund <fredrik@kde.org> | 2017-09-04 18:45:42 +0200 |
---|---|---|
committer | Fredrik Höglund <fredrik@kde.org> | 2017-09-18 22:07:50 +0200 |
commit | 7ca1257845c4e5471bbb5d7f5903de7734a2d8f5 (patch) | |
tree | 07587b4c5202a86632d8aae5a489b46daa76d0ca | |
parent | 603382a2fab5057813ff7a122a050252ea1e610f (diff) |
radv: Implement VK_EXT_discard_rectanglesradv-discard-rectangles
-rw-r--r-- | src/amd/vulkan/radv_cmd_buffer.c | 56 | ||||
-rw-r--r-- | src/amd/vulkan/radv_device.c | 10 | ||||
-rw-r--r-- | src/amd/vulkan/radv_entrypoints_gen.py | 1 | ||||
-rw-r--r-- | src/amd/vulkan/radv_pipeline.c | 59 | ||||
-rw-r--r-- | src/amd/vulkan/radv_private.h | 17 |
5 files changed, 137 insertions, 6 deletions
diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 99f996d5f1..90a7524e6c 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -53,6 +53,9 @@ const struct radv_dynamic_state default_dynamic_state = { .scissor = { .count = 0, }, + .discard_rectangle = { + .count = 0, + }, .line_width = 1.0f, .depth_bias = { .bias = 0.0f, @@ -96,6 +99,12 @@ radv_dynamic_state_copy(struct radv_dynamic_state *dest, src->scissor.count); } + dest->discard_rectangle.count = src->discard_rectangle.count; + if (copy_mask & RADV_DYNAMIC_STATE_DISCARD_RECTANGLE_BIT) { + typed_memcpy(dest->discard_rectangle.rects, src->discard_rectangle.rects, + src->discard_rectangle.count); + } + if (copy_mask & RADV_DYNAMIC_STATE_LINE_WIDTH_BIT) dest->line_width = src->line_width; @@ -982,6 +991,11 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer) 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_sc_cliprect_rule != + pipeline->graphics.pa_sc_cliprect_rule) + radeon_set_context_reg(cmd_buffer->cs, R_02820C_PA_SC_CLIPRECT_RULE, pipeline->graphics.pa_sc_cliprect_rule); + radeon_set_context_reg(cmd_buffer->cs, R_028B54_VGT_SHADER_STAGES_EN, pipeline->graphics.vgt_shader_stages_en); if (cmd_buffer->device->physical_device->rad_info.chip_class >= CIK) { @@ -1016,6 +1030,27 @@ radv_emit_scissor(struct radv_cmd_buffer *cmd_buffer) } static void +radv_emit_discard_rectangle(struct radv_cmd_buffer *cmd_buffer) +{ + const VkRect2D *rects = cmd_buffer->state.dynamic.discard_rectangle.rects; + const uint32_t count = cmd_buffer->state.dynamic.discard_rectangle.count; + uint32_t i; + + MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws, cmd_buffer->cs, 2 + count * 2); + + radeon_set_context_reg_seq(cmd_buffer->cs, R_028210_PA_SC_CLIPRECT_0_TL, count * 2); + + for (i = 0; i < count; i++) { + radeon_emit(cmd_buffer->cs, + S_028210_TL_X(rects[i].offset.x) | + S_028210_TL_Y(rects[i].offset.y)); + radeon_emit(cmd_buffer->cs, + S_028214_BR_X(rects[i].offset.x + rects[i].extent.width) | + S_028214_BR_Y(rects[i].offset.y + rects[i].extent.height)); + } +} + +static void radv_emit_line_width(struct radv_cmd_buffer *cmd_buffer) { unsigned width = cmd_buffer->state.dynamic.line_width * 8; @@ -1442,6 +1477,9 @@ radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer) if (G_028810_DX_RASTERIZATION_KILL(cmd_buffer->state.pipeline->graphics.raster.pa_cl_clip_cntl)) return; + if (cmd_buffer->state.dirty & RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE) + radv_emit_discard_rectangle(cmd_buffer); + if (cmd_buffer->state.dirty & (RADV_CMD_DIRTY_DYNAMIC_VIEWPORT)) radv_emit_viewport(cmd_buffer); @@ -3630,3 +3668,21 @@ void radv_CmdWaitEvents(VkCommandBuffer commandBuffer, RADV_CMD_FLAG_INV_VMEM_L1 | RADV_CMD_FLAG_INV_SMEM_L1; } + +void radv_CmdSetDiscardRectangleEXT(VkCommandBuffer commandBuffer, + uint32_t firstDiscardRectangle, + uint32_t discardRectangleCount, + const VkRect2D *pDiscardRectangles) +{ + RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); + + /* Note that dynamic_state_mask is actually a mask of states that are not dynamic */ + assert(!(cmd_buffer->state.pipeline->dynamic_state_mask & RADV_DYNAMIC_STATE_DISCARD_RECTANGLE_BIT)); + assert(discardRectangleCount > 0); + assert(firstDiscardRectangle + discardRectangleCount <= MAX_DISCARD_RECTANGLES); + + memcpy(cmd_buffer->state.dynamic.discard_rectangle.rects + firstDiscardRectangle, + pDiscardRectangles, discardRectangleCount * sizeof(VkRect2D)); + + cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE; +} diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index e6d595dfbe..e690fae51c 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -174,6 +174,10 @@ static const VkExtensionProperties common_device_extensions[] = { .extensionName = VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, .specVersion = 1, }, + { + .extensionName = VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME, + .specVersion = 1, + }, }; static const VkExtensionProperties ext_sema_device_extensions[] = { { @@ -845,6 +849,12 @@ void radv_GetPhysicalDeviceProperties2KHR( properties->maxMultiviewInstanceIndex = INT_MAX; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT: { + VkPhysicalDeviceDiscardRectanglePropertiesEXT *properties = + (VkPhysicalDeviceDiscardRectanglePropertiesEXT *) ext; + properties->maxDiscardRectangles = MAX_DISCARD_RECTANGLES; + break; + } default: break; } diff --git a/src/amd/vulkan/radv_entrypoints_gen.py b/src/amd/vulkan/radv_entrypoints_gen.py index 9634f76fcd..0ff9eca327 100644 --- a/src/amd/vulkan/radv_entrypoints_gen.py +++ b/src/amd/vulkan/radv_entrypoints_gen.py @@ -57,6 +57,7 @@ SUPPORTED_EXTENSIONS = [ 'VK_KHR_external_semaphore_capabilities', 'VK_KHR_external_semaphore', 'VK_KHR_external_semaphore_fd', + 'VK_EXT_discard_rectangles', ] # We generate a static hash table for entry point lookup diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index e1b11b09c5..3abfa05edd 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -44,6 +44,7 @@ #include "ac_llvm_util.h" #include "ac_nir_to_llvm.h" #include "vk_format.h" +#include "vk_util.h" #include "util/debug.h" #include "ac_exp_param.h" @@ -1229,8 +1230,18 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline, if (pCreateInfo->pDynamicState) { /* Remove all of the states that are marked as dynamic */ uint32_t count = pCreateInfo->pDynamicState->dynamicStateCount; - for (uint32_t s = 0; s < count; s++) - states &= ~(1 << pCreateInfo->pDynamicState->pDynamicStates[s]); + for (uint32_t s = 0; s < count; s++) { + const VkDynamicState state = pCreateInfo->pDynamicState->pDynamicStates[s]; + switch (state) { + case VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT: + states &= ~RADV_DYNAMIC_STATE_DISCARD_RECTANGLE_BIT; + break; + default: + if (state <= VK_DYNAMIC_STATE_STENCIL_REFERENCE) + states &= ~(1 << state); + break; + } + } } struct radv_dynamic_state *dynamic = &pipeline->dynamic_state; @@ -1338,6 +1349,50 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline, } } + pipeline->graphics.pa_sc_cliprect_rule = S_02820C_CLIP_RULE(0xffff); + + vk_foreach_struct(ext, pCreateInfo->pNext) { + switch (ext->sType) { + case VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT: { + const struct VkPipelineDiscardRectangleStateCreateInfoEXT *state = (const void *) ext; + + assert(state->discardRectangleCount <= MAX_DISCARD_RECTANGLES); + + /* The hardware computes a 4-bit inside_mask for each pixel, where bit n [3..0] corresponds + * to cliprect n. If the pixel is inside the respective cliprect, the corresponding bit is + * set to one. The pixel passes if (cliprect_rule & (1 << inside_mask)) is true; otherwise + * it is discarded. + */ + if (state->discardRectangleMode == VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT) { + switch (state->discardRectangleCount) { + case 4: pipeline->graphics.pa_sc_cliprect_rule = S_02820C_CLIP_RULE(0xfffe); break; + case 3: pipeline->graphics.pa_sc_cliprect_rule = S_02820C_CLIP_RULE(0xfefe); break; + case 2: pipeline->graphics.pa_sc_cliprect_rule = S_02820C_CLIP_RULE(0xeeee); break; + case 1: pipeline->graphics.pa_sc_cliprect_rule = S_02820C_CLIP_RULE(0xaaaa); break; + default: break; + } + } else { + switch (state->discardRectangleCount) { + case 4: pipeline->graphics.pa_sc_cliprect_rule = S_02820C_CLIP_RULE(0x0001); break; + case 3: pipeline->graphics.pa_sc_cliprect_rule = S_02820C_CLIP_RULE(0x0101); break; + case 2: pipeline->graphics.pa_sc_cliprect_rule = S_02820C_CLIP_RULE(0x1111); break; + case 1: pipeline->graphics.pa_sc_cliprect_rule = S_02820C_CLIP_RULE(0x5555); break; + default: break; + } + } + + dynamic->discard_rectangle.count = state->discardRectangleCount; + if (states & RADV_DYNAMIC_STATE_DISCARD_RECTANGLE_BIT) { + typed_memcpy(dynamic->discard_rectangle.rects, + state->pDiscardRectangles, state->discardRectangleCount); + } + break; + } + default: + break; + } + } + pipeline->dynamic_state_mask = states; } diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 8b007dceca..a18534f060 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -79,6 +79,7 @@ typedef uint32_t xcb_window_t; #define MAX_RTS 8 #define MAX_VIEWPORTS 16 #define MAX_SCISSORS 16 +#define MAX_DISCARD_RECTANGLES 4 #define MAX_PUSH_CONSTANTS_SIZE 128 #define MAX_PUSH_DESCRIPTORS 32 #define MAX_DYNAMIC_BUFFERS 16 @@ -114,6 +115,7 @@ enum radv_dynamic_state_flag { RADV_DYNAMIC_STATE_STENCIL_COMPARE_MASK_BIT = (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK), RADV_DYNAMIC_STATE_STENCIL_WRITE_MASK_BIT = (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK), RADV_DYNAMIC_STATE_STENCIL_REFERENCE_BIT = (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE), + RADV_DYNAMIC_STATE_DISCARD_RECTANGLE_BIT = (1 << 9), }; #define radv_printflike(a, b) __attribute__((__format__(__printf__, a, b))) @@ -670,10 +672,11 @@ enum radv_cmd_dirty_bits { RADV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK = 1 << 6, /* RADV_DYNAMIC_STATE_STENCIL_COMPARE_MASK_BIT */ RADV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK = 1 << 7, /* RADV_DYNAMIC_STATE_STENCIL_WRITE_MASK_BIT */ RADV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE = 1 << 8, /* RADV_DYNAMIC_STATE_STENCIL_REFERENCE_BIT */ - RADV_CMD_DIRTY_DYNAMIC_ALL = (1 << 9) - 1, - RADV_CMD_DIRTY_PIPELINE = 1 << 9, - RADV_CMD_DIRTY_INDEX_BUFFER = 1 << 10, - RADV_CMD_DIRTY_RENDER_TARGETS = 1 << 11, + RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE = 1 << 9, /* RADV_DYNAMIC_STATE_DISCARD_RECTANGLE_BIT */ + RADV_CMD_DIRTY_DYNAMIC_ALL = (1 << 10) - 1, + RADV_CMD_DIRTY_PIPELINE = 1 << 10, + RADV_CMD_DIRTY_INDEX_BUFFER = 1 << 11, + RADV_CMD_DIRTY_RENDER_TARGETS = 1 << 12, }; typedef uint32_t radv_cmd_dirty_mask_t; @@ -720,6 +723,11 @@ struct radv_dynamic_state { VkRect2D scissors[MAX_SCISSORS]; } scissor; + struct { + uint32_t count; + VkRect2D rects[MAX_DISCARD_RECTANGLES]; + } discard_rectangle; + float line_width; struct { @@ -1103,6 +1111,7 @@ struct radv_pipeline { uint32_t ps_input_cntl[32]; uint32_t ps_input_cntl_num; uint32_t pa_cl_vs_out_cntl; + uint32_t pa_sc_cliprect_rule; uint32_t vgt_shader_stages_en; uint32_t vtx_base_sgpr; uint32_t base_ia_multi_vgt_param; |