| // Copyright (c) 2020 Qualcomm Technologies, Inc. |
| // |
| // SPDX-License-Identifier: CC-BY-4.0 |
| |
| include::{generated}/meta/{refprefix}VK_QCOM_render_pass_transform.txt[] |
| |
| === Other Extension Metadata |
| |
| *Last Modified Date*:: |
| 2021-03-09 |
| *Interactions and External Dependencies*:: |
| - This extension requires `apiext:VK_KHR_swapchain` |
| - This extension interacts with `apiext:VK_EXT_fragment_density_map` |
| - This extension interacts with `apiext:VK_KHR_fragment_shading_rate` |
| *Contributors*:: |
| - Jeff Leger, Qualcomm Technologies, Inc. |
| - Brandon Light, Qualcomm Technologies, Inc. |
| - Matthew Netsch, Qualcomm Technologies, Inc. |
| |
| === Description |
| |
| This extension provides a mechanism for applications to enable driver |
| support for <<vertexpostproc-renderpass-transform, render pass transform>>. |
| |
| Mobile devices can be rotated and mobile applications need to render |
| properly when a device is held in a landscape or portrait orientation. |
| When the current orientation differs from the device's native orientation, a |
| rotation is required so that the "`up`" direction of the rendered scene |
| matches the current orientation. |
| |
| If the Display Processing Unit (DPU) doesnt natively support rotation, the |
| Vulkan presentation engine can handle this rotation in a separate |
| composition pass. |
| Alternatively, the application can render frames "`pre-rotated`" to avoid |
| this extra pass. |
| The latter is preferred to reduce power consumption and achieve the best |
| performance because it avoids tasking the GPU with extra work to perform the |
| copy/rotate operation. |
| |
| Unlike OpenGL ES, the burden of pre-rotation in Vulkan falls on the |
| application. |
| To implement pre-rotation, applications render into swapchain images |
| matching the device native aspect ratio of the display and "`pre-rotate`" |
| the rendering content to match the device's current orientation. |
| The burden is more than adjusting the Model View Projection (MVP) matrix in |
| the vertex shader to account for rotation and aspect ratio. |
| The coordinate systems of scissors, viewports, derivatives and several |
| shader built-ins may need to be adapted to produce the correct result. |
| |
| It is difficult for some game engines to manage this burden; many chose to |
| simply accept the performance/power overhead of performing rotation in the |
| presentation engine. |
| |
| This extension allows applications to achieve the performance benefits of |
| pre-rotated rendering by moving much of the above-mentioned burden to the |
| graphics driver. |
| The following is unchanged with this extension: |
| |
| * Applications create a swapchain matching the native orientation of the |
| display. |
| Applications must also set the |
| slink:VkSwapchainCreateInfoKHR::pname:preTransform equal to the |
| pname:currentTransform as returned by |
| flink:vkGetPhysicalDeviceSurfaceCapabilitiesKHR. |
| |
| The following is changed with this extension: |
| |
| * At flink:vkCmdBeginRenderPass, the application provides extension struct |
| slink:VkRenderPassTransformBeginInfoQCOM specifying the render pass |
| transform parameters. |
| * At flink:vkBeginCommandBuffer for secondary command buffers, the |
| application provides extension struct |
| slink:VkCommandBufferInheritanceRenderPassTransformInfoQCOM specifying |
| the render pass transform parameters. |
| * The pname:renderArea, viewports, scissors, and pname:fragmentSize are |
| all provided in the current (non-rotated) coordinate system. |
| The implementation will transform those into the native (rotated) |
| coordinate system. |
| * The implementation is responsible for transforming shader built-ins |
| (code:FragCoord, code:PointCoord, code:SamplePosition, |
| code:PrimitiveShadingRateKHR, interpolateAt(), dFdx, dFdy, fWidth) into |
| the rotated coordinate system. |
| * The implementation is responsible for transforming code:position to the |
| rotated coordinate system. |
| |
| include::{generated}/interfaces/VK_QCOM_render_pass_transform.txt[] |
| |
| === Issues |
| 1) Some early Adreno drivers (October 2019 through March 2020) advertised |
| support for this extension but expected VK_STRUCTURE_TYPE values different |
| from those in the vukan headers. |
| To cover all Adreno devices on the market, applications need to detect the |
| driver version and use the appropriate VK_STRUCTURE_TYPE values from the |
| table below. |
| |
| The driver version reported in VkPhysicalDeviceProperties.driverVersion is a |
| code:uint32_t type. |
| You can decode the code:uint32_t value into a major.minor.patch version as |
| shown below: |
| [source,c] |
| --------------------------------------------------- |
| uint32_t major = ((driverVersion) >> 22); |
| uint32_t minor = ((driverVersion) >> 12) & 0x3ff); |
| uint32_t patch = ((driverVersion) & 0xfff); |
| --------------------------------------------------- |
| |
| If the Adreno major.minor.patch version is greater than or equal to to |
| 512.469.0, then simply use the VK_STRUCTURE_TYPE values as defined in |
| vulkan_core.h. |
| If the version is less than or equal to to 512.468.0, then use the alternate |
| values for the two VK_STRUCTURE_TYPEs in the table below. |
| |
| .fname:Adreno Driver Requirements |
| [width="80%",options="header"] |
| |==== |
| | 2+| Adreno Driver Version |
| | | 512.468.0 and earlier | 512.469.0 and later |
| |VK_STRUCTURE_TYPE_ RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM | 1000282000 | 1000282001 |
| |VK_STRUCTURE_TYPE_ COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM| 1000282001 | 1000282000 |
| |==== |
| |
| 2) Should the extension support only rotations (e.g. 90, 180, 270-degrees), |
| or also mirror transforms (e.g. vertical flips)? Mobile use-cases only |
| require rotation. |
| Other display systems such as projectors might require a flipped transform. |
| |
| *RESOLVED*: In this version of the extension, the functionality is |
| restricted to 90, 180, and 270-degree rotations to address mobile use-cases. |
| |
| 3) How does this extension interact with VK_EXT_fragment_density_map? |
| |
| *RESOLVED* Some implementations may not be able to support a render pass |
| that enables both render pass transform and fragment density maps. |
| For simplicity, this extension disallows enabling both features within a |
| single render pass. |
| |
| 4) What should this extension be named? |
| |
| We considered names such as "`rotated_rendering`", "`pre_rotation`" and |
| others. |
| Since the functionality is limited to a render pass, it seemed the name |
| should include "`render_pass`". |
| While the current extension is limited to rotations, it could be extended to |
| other transforms (like mirror) in the future. |
| |
| *RESOLVED* The name "`render_pass_transform`" seems like the most accurate |
| description of the introduced functionality. |
| |
| 5) How does this extension interact with VK_KHR_fragment_shading_rate? |
| |
| *RESOLVED*: For the same reasons as issue 3, this extension disallows |
| enabling both pname:pFragmentShadingRateAttachment and render pass transform |
| within a single render pass. |
| |
| However, pipeline shading rate and primitive shading rate are supported, and |
| their respective pname:fragmentSize and code:PrimitiveShadingRateKHR are |
| provided in the current (non-rotated) coordinate system. |
| The implementation is responsible for transforming them to the rotated |
| coordinate system. |
| |
| The <<primsrast-fragment-shading-rate, set of supported shading rates>> may: |
| be different per transform. |
| Supported rates queried from |
| flink:vkGetPhysicalDeviceFragmentShadingRatesKHR are in the native (rotated) |
| coordinate system. |
| This means that the application must: swap the x/y of the reported rates to |
| get the set of rates supported for 90 and 270 degree rotation. |
| |
| |
| === Version History |
| |
| * Revision 1, 2020-02-05 (Jeff Leger) |
| * Revision 2, 2021-03-09 (Matthew Netsch) |
| - Adds interactions with VK_KHR_fragment_shading_rate |