summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlejandro PiƱeiro <apinheiro@igalia.com>2019-12-28 11:59:32 +0100
committerMarge Bot <eric+marge@anholt.net>2020-10-13 21:21:26 +0000
commit5285d8397455b918b370630e0f92de256f57839e (patch)
tree0120b8b02b90159af6e08f906aa2ea9d4253b3c0
parentfca4dcee9f23af036ff2094406c91c46c34ced8d (diff)
v3dv: CmdSetViewport and CmdSetScissor implementation
This commit also introduces adding dynamic state definitions, dirty flags, and setting them on such methods, although this commit still doesn't use all that info yet. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
-rw-r--r--src/broadcom/vulkan/v3dv_cmd_buffer.c63
-rw-r--r--src/broadcom/vulkan/v3dv_device.c2
-rw-r--r--src/broadcom/vulkan/v3dv_private.h53
3 files changed, 117 insertions, 1 deletions
diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c
index aa8a71cda28..c44d35537a4 100644
--- a/src/broadcom/vulkan/v3dv_cmd_buffer.c
+++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c
@@ -904,6 +904,8 @@ v3dv_CmdBindPipeline(VkCommandBuffer commandBuffer,
return;
cmd_buffer->state.pipeline = pipeline;
+
+ cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_PIPELINE;
break;
default:
@@ -911,3 +913,64 @@ v3dv_CmdBindPipeline(VkCommandBuffer commandBuffer,
break;
}
}
+
+
+void
+v3dv_CmdSetViewport(VkCommandBuffer commandBuffer,
+ uint32_t firstViewport,
+ uint32_t viewportCount,
+ const VkViewport *pViewports)
+{
+ V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
+ struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
+ const uint32_t total_count = firstViewport + viewportCount;
+
+ assert(firstViewport < MAX_VIEWPORTS);
+ assert(total_count >= 1 && total_count <= MAX_VIEWPORTS);
+
+ /* anv allows CmdSetViewPort to change how many viewports are being used,
+ * while radv not, using the value set on the pipeline creation. spec
+ * doesn't specify, but radv approach makes more sense, as CmdSetViewport
+ * is intended to set dynamically a specific viewport, increasing the
+ * number of viewport used seems like a non-defined collateral
+ * effect. Would make sense to open a spec issue to clarify. For now, as we
+ * only support one, it is not really important, but we follow radv
+ * approach.
+ */
+ if (!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 |= V3DV_CMD_DIRTY_DYNAMIC_VIEWPORT;
+}
+
+void
+v3dv_CmdSetScissor(VkCommandBuffer commandBuffer,
+ uint32_t firstScissor,
+ uint32_t scissorCount,
+ const VkRect2D *pScissors)
+{
+ V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
+ struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
+ const uint32_t total_count = firstScissor + scissorCount;
+
+ assert(firstScissor < MAX_SCISSORS);
+ assert(total_count >= 1 && total_count <= MAX_SCISSORS);
+
+ /* See note on CmdSetViewport related to anv/radv differences about setting
+ * total viewports used. Also applies to scissor.
+ */
+ if (!memcmp(state->dynamic.scissor.scissors + firstScissor,
+ pScissors, scissorCount * sizeof(*pScissors))) {
+ return;
+ }
+
+ memcpy(state->dynamic.scissor.scissors + firstScissor, pScissors,
+ scissorCount * sizeof(*pScissors));
+
+ cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_DYNAMIC_SCISSOR;
+}
diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c
index 20ecbf185a1..de3ad21945f 100644
--- a/src/broadcom/vulkan/v3dv_device.c
+++ b/src/broadcom/vulkan/v3dv_device.c
@@ -589,7 +589,7 @@ v3dv_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
.maxDrawIndirectCount = 0x7fffffff,
.maxSamplerLodBias = 14.0f,
.maxSamplerAnisotropy = 16.0f,
- .maxViewports = 1,
+ .maxViewports = MAX_VIEWPORTS,
.maxViewportDimensions = { max_fb_size, max_fb_size },
.viewportBoundsRange = { -2.0 * max_fb_size,
2.0 * max_fb_size - 1 },
diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h
index 3633756ba42..789eafd10b9 100644
--- a/src/broadcom/vulkan/v3dv_private.h
+++ b/src/broadcom/vulkan/v3dv_private.h
@@ -94,6 +94,13 @@ pack_emit_reloc(void *cl, const void *reloc) {}
#define v3dv_assert(x)
#endif
+/* From vulkan spec "If the multiple viewports feature is not enabled,
+ * scissorCount must be 1", ditto for viewportCount. For now we don't support
+ * that feature.
+ */
+#define MAX_VIEWPORTS 1
+#define MAX_SCISSORS 1
+
struct v3dv_instance;
#ifdef USE_V3D_SIMULATOR
@@ -378,6 +385,49 @@ struct v3dv_cmd_buffer_attachment_state {
union v3dv_clear_value clear_value;
};
+struct v3dv_viewport_state {
+ uint32_t count;
+ VkViewport viewports[MAX_VIEWPORTS];
+};
+
+struct v3dv_scissor_state {
+ uint32_t count;
+ VkRect2D scissors[MAX_SCISSORS];
+};
+
+/* Mostly a v3dv mapping of VkDynamicState, used to track which data as
+ * defined as dynamic
+ */
+enum v3dv_dynamic_state_bits {
+ V3DV_DYNAMIC_VIEWPORT = 1 << 0,
+ V3DV_DYNAMIC_SCISSOR = 1 << 1,
+ V3DV_DYNAMIC_ALL = (1 << 2) - 1,
+};
+
+/* To track which cmd buffer elements are "dirty" so would need an
+ * update. This includes viewport, scissor (so vk dynamic info), plus any
+ * other more high level resource, like pipeline, etc.
+ */
+enum v3dv_cmd_dirty_bits {
+ V3DV_CMD_DIRTY_DYNAMIC_VIEWPORT = 1 << 0,
+ V3DV_CMD_DIRTY_DYNAMIC_SCISSOR = 1 << 1,
+ V3DV_CMD_DIRTY_DYNAMIC_ALL = (1 << 2) - 1,
+ V3DV_CMD_DIRTY_PIPELINE = 1 << 2,
+};
+
+
+struct v3dv_dynamic_state {
+ /**
+ * Bitmask of (1 << VK_DYNAMIC_STATE_*).
+ * Defines the set of saved dynamic state.
+ */
+ uint32_t mask;
+
+ struct v3dv_viewport_state viewport;
+
+ struct v3dv_scissor_state scissor;
+};
+
struct v3dv_cmd_buffer_state {
const struct v3dv_render_pass *pass;
const struct v3dv_framebuffer *framebuffer;
@@ -391,6 +441,9 @@ struct v3dv_cmd_buffer_state {
struct v3dv_cmd_buffer_attachment_state attachments[6]; /* 4 color + D + S */
struct v3dv_pipeline *pipeline;
+
+ struct v3dv_dynamic_state dynamic;
+ uint32_t dirty;
};
struct v3dv_cmd_buffer {