summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFredrik Höglund <fredrik@kde.org>2017-09-04 18:45:42 +0200
committerFredrik Höglund <fredrik@kde.org>2017-09-18 22:07:50 +0200
commit7ca1257845c4e5471bbb5d7f5903de7734a2d8f5 (patch)
tree07587b4c5202a86632d8aae5a489b46daa76d0ca
parent603382a2fab5057813ff7a122a050252ea1e610f (diff)
radv: Implement VK_EXT_discard_rectanglesradv-discard-rectangles
-rw-r--r--src/amd/vulkan/radv_cmd_buffer.c56
-rw-r--r--src/amd/vulkan/radv_device.c10
-rw-r--r--src/amd/vulkan/radv_entrypoints_gen.py1
-rw-r--r--src/amd/vulkan/radv_pipeline.c59
-rw-r--r--src/amd/vulkan/radv_private.h17
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;