1 /* 2 * Copyright © 2022 Imagination Technologies Ltd. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a copy 5 * of this software and associated documentation files (the "Software"), to deal 6 * in the Software without restriction, including without limitation the rights 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 * copies of the Software, and to permit persons to whom the Software is 9 * furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 */ 23 24 #ifndef PVR_HW_PASS_H 25 #define PVR_HW_PASS_H 26 27 #include <stdbool.h> 28 #include <stdint.h> 29 #include <vulkan/vulkan.h> 30 31 struct pvr_device; 32 struct pvr_render_pass; 33 34 /* Specifies the location of render target writes. */ 35 enum usc_mrt_resource_type { 36 USC_MRT_RESOURCE_TYPE_INVALID = 0, /* explicitly treat 0 as invalid. */ 37 USC_MRT_RESOURCE_TYPE_OUTPUT_REG, 38 USC_MRT_RESOURCE_TYPE_MEMORY, 39 }; 40 41 enum pvr_resolve_type { 42 PVR_RESOLVE_TYPE_INVALID = 0, /* explicitly treat 0 as invalid. */ 43 PVR_RESOLVE_TYPE_PBE, 44 PVR_RESOLVE_TYPE_TRANSFER, 45 }; 46 47 enum pvr_renderpass_hwsetup_input_access { 48 /* The attachment must be loaded using a texture sample. */ 49 PVR_RENDERPASS_HWSETUP_INPUT_ACCESS_OFFCHIP, 50 /* The attachment can be loaded from an output register or tile buffer. */ 51 PVR_RENDERPASS_HWSETUP_INPUT_ACCESS_ONCHIP, 52 /* As _ONCHIP but the attachment is the result of a Z replicate in the same 53 * subpass. 54 */ 55 PVR_RENDERPASS_HWSETUP_INPUT_ACCESS_ONCHIP_ZREPLICATE, 56 }; 57 58 #define PVR_USC_RENDER_TARGET_MAXIMUM_SIZE_IN_DWORDS (4) 59 60 struct usc_mrt_desc { 61 /* Size (in bytes) of the intermediate storage required for each pixel in the 62 * render target. 63 */ 64 uint32_t intermediate_size; 65 66 /* Mask of the bits from each dword which are read by the PBE. */ 67 uint32_t valid_mask[PVR_USC_RENDER_TARGET_MAXIMUM_SIZE_IN_DWORDS]; 68 69 /* Higher number = higher priority. Used to decide which render targets get 70 * allocated dedicated output registers. 71 */ 72 uint32_t priority; 73 }; 74 75 struct usc_mrt_resource { 76 /* Input description of render target. */ 77 struct usc_mrt_desc mrt_desc; 78 79 /* Resource type allocated for render target. */ 80 enum usc_mrt_resource_type type; 81 82 /* Intermediate pixel size (in bytes). */ 83 uint32_t intermediate_size; 84 85 union { 86 /* If type == USC_MRT_RESOURCE_TYPE_OUTPUT_REG. */ 87 struct { 88 /* The output register to use. */ 89 uint32_t output_reg; 90 91 /* The offset in bytes into the output register. */ 92 uint32_t offset; 93 } reg; 94 95 /* If type == USC_MRT_RESOURCE_TYPE_MEMORY. */ 96 struct { 97 /* The index of the tile buffer to use. */ 98 uint32_t tile_buffer; 99 100 /* The offset in dwords within the tile buffer. */ 101 uint32_t offset_dw; 102 } mem; 103 }; 104 }; 105 106 struct usc_mrt_setup { 107 /* Number of render targets present. */ 108 uint32_t num_render_targets; 109 110 /* Number of output registers used per-pixel (1, 2 or 4). */ 111 uint32_t num_output_regs; 112 113 /* Number of tile buffers used. */ 114 uint32_t num_tile_buffers; 115 116 /* Size of a tile buffer in bytes. */ 117 uint32_t tile_buffer_size; 118 119 /* Array of MRT resources allocated for each render target. The number of 120 * elements is determined by usc_mrt_setup::num_render_targets. 121 */ 122 struct usc_mrt_resource *mrt_resources; 123 124 /* Don't set up source pos in emit. */ 125 bool disable_source_pos_override; 126 127 /* Hash unique to this particular setup. */ 128 uint32_t hash; 129 }; 130 131 struct pvr_renderpass_hwsetup_eot_surface { 132 /* MRT index to store from. Also used to index into 133 * usc_mrt_setup::mrt_resources. 134 */ 135 uint32_t mrt_idx; 136 137 /* Index of pvr_render_pass_info::attachments to store into. */ 138 uint32_t attachment_idx; 139 140 /* True if the surface should be resolved. */ 141 bool need_resolve; 142 143 /* How the surface should be resolved at the end of a render. Only valid if 144 * pvr_renderpass_hwsetup_eot_surface::need_resolve is set to true. 145 */ 146 enum pvr_resolve_type resolve_type; 147 148 /* Index of pvr_render_pass_info::attachments to resolve from. Only valid if 149 * pvr_renderpass_hwsetup_eot_surface::need_resolve is set to true. 150 */ 151 uint32_t src_attachment_idx; 152 }; 153 154 struct pvr_renderpass_hwsetup_subpass { 155 /* Mapping from fragment stage pixel outputs to hardware storage for all 156 * fragment programs in the subpass. 157 */ 158 struct usc_mrt_setup setup; 159 160 /* If >=0 then copy the depth into this pixel output for all fragment 161 * programs in the subpass. 162 */ 163 int32_t z_replicate; 164 165 /* The operation to perform on the depth at the start of the subpass. Loads 166 * are deferred to subpasses when depth has been replicated. 167 */ 168 VkAttachmentLoadOp depth_initop; 169 170 /* If true then clear the stencil at the start of the subpass. */ 171 bool stencil_clear; 172 173 /* Subpass index from the input pvr_render_subpass structure. */ 174 uint32_t index; 175 176 /* For each color attachment to the subpass the operation to perform at 177 * the start of the subpass. 178 */ 179 VkAttachmentLoadOp *color_initops; 180 181 struct pvr_load_op *load_op; 182 183 struct { 184 enum pvr_renderpass_hwsetup_input_access type; 185 uint32_t on_chip_rt; 186 } * input_access; 187 188 uint8_t output_register_mask; 189 }; 190 191 struct pvr_renderpass_colorinit { 192 /* Source attachment for the operation. */ 193 uint32_t index; 194 195 /* Type of operation either clear or load. */ 196 VkAttachmentLoadOp op; 197 }; 198 199 struct pvr_renderpass_hwsetup_render { 200 /* Number of pixel output registers to allocate for this render. */ 201 uint32_t output_regs_count; 202 203 /* Number of tile buffers to allocate for this render. */ 204 uint32_t tile_buffers_count; 205 206 /* Number of subpasses in this render. */ 207 uint32_t subpass_count; 208 209 /* Description of each subpass. */ 210 struct pvr_renderpass_hwsetup_subpass *subpasses; 211 212 /* The sample count of every color attachment (or depth attachment if 213 * z-only) in this render. 214 */ 215 uint32_t sample_count; 216 217 /* Index of the attachment to use for depth/stencil load/store in this 218 * render. 219 */ 220 uint32_t ds_attach_idx; 221 222 /* Operation on the on-chip depth at the start of the render. 223 * Either load from 'ds_attach_idx', clear using 'ds_attach_idx' or leave 224 * uninitialized. 225 */ 226 VkAttachmentLoadOp depth_init; 227 228 /* Operation on the on-chip stencil at the start of the render. */ 229 VkAttachmentLoadOp stencil_init; 230 231 /* Count of operations on on-chip color storage at the start of the render. 232 */ 233 uint32_t color_init_count; 234 235 /* For each operation: the destination in the on-chip color storage. */ 236 struct usc_mrt_setup init_setup; 237 238 /* How to initialize render targets at the start of the render. */ 239 struct pvr_renderpass_colorinit *color_init; 240 241 /* true to store depth to 'ds_attach_idx' at the end of the render. */ 242 bool depth_store; 243 /* true to store stencil to 'ds_attach_idx' at the end of the render. */ 244 bool stencil_store; 245 246 /* Describes the location of the source data for each stored surface. */ 247 struct usc_mrt_setup eot_setup; 248 249 struct pvr_renderpass_hwsetup_eot_surface *eot_surfaces; 250 uint32_t eot_surface_count; 251 252 uint32_t pbe_emits; 253 254 /* true if this HW render has lasting effects on its attachments. */ 255 bool has_side_effects; 256 257 struct pvr_load_op *load_op; 258 }; 259 260 struct pvr_renderpass_hw_map { 261 uint32_t render; 262 uint32_t subpass; 263 }; 264 265 struct pvr_renderpass_hwsetup { 266 /* Number of renders. */ 267 uint32_t render_count; 268 269 /* Description of each render. */ 270 struct pvr_renderpass_hwsetup_render *renders; 271 272 /* Maps indices from pvr_render_pass::subpasses to the 273 * pvr_renderpass_hwsetup_render/pvr_renderpass_hwsetup_subpass relative to 274 * that render where the subpass is scheduled. 275 */ 276 struct pvr_renderpass_hw_map *subpass_map; 277 278 bool *surface_allocate; 279 }; 280 281 VkResult pvr_create_renderpass_hwsetup( 282 struct pvr_device *device, 283 const VkAllocationCallbacks *alloc, 284 struct pvr_render_pass *pass, 285 bool disable_merge, 286 struct pvr_renderpass_hwsetup **const hw_setup_out); 287 288 void pvr_destroy_renderpass_hwsetup(const VkAllocationCallbacks *alloc, 289 struct pvr_renderpass_hwsetup *hw_setup); 290 291 uint32_t pvr_get_tile_buffer_size(const struct pvr_device *device); 292 293 #endif /* PVR_HW_PASS_H */ 294