diff options
author | Alejandro PiƱeiro <apinheiro@igalia.com> | 2019-12-28 11:59:32 +0100 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2020-10-13 21:21:26 +0000 |
commit | 5285d8397455b918b370630e0f92de256f57839e (patch) | |
tree | 0120b8b02b90159af6e08f906aa2ea9d4253b3c0 | |
parent | fca4dcee9f23af036ff2094406c91c46c34ced8d (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.c | 63 | ||||
-rw-r--r-- | src/broadcom/vulkan/v3dv_device.c | 2 | ||||
-rw-r--r-- | src/broadcom/vulkan/v3dv_private.h | 53 |
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 { |