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_CLEAR_H
25 #define PVR_CLEAR_H
26
27 #include <stdbool.h>
28 #include <stdint.h>
29 #include <vulkan/vulkan_core.h>
30
31 #include "pvr_csb.h"
32 #include "pvr_device_info.h"
33 #include "util/macros.h"
34
35 #define PVR_CLEAR_VERTEX_COUNT 4
36 #define PVR_CLEAR_VERTEX_COORDINATES 3
37
38 #define PVR_STATIC_CLEAR_PDS_STATE_COUNT \
39 (pvr_cmd_length(TA_STATE_PDS_SHADERBASE) + \
40 pvr_cmd_length(TA_STATE_PDS_TEXUNICODEBASE) + \
41 pvr_cmd_length(TA_STATE_PDS_SIZEINFO1) + \
42 pvr_cmd_length(TA_STATE_PDS_SIZEINFO2) + \
43 pvr_cmd_length(TA_STATE_PDS_VARYINGBASE) + \
44 pvr_cmd_length(TA_STATE_PDS_TEXTUREDATABASE))
45
46 /* These can be used as offsets within a PVR_STATIC_CLEAR_PDS_STATE_COUNT dwords
47 * sized array to get the respective state word.
48 *
49 * The values are based on the lengths of the state words.
50 */
51 enum pvr_static_clear_ppp_pds_state_type {
52 /* Words enabled by pres_pds_state_ptr0. */
53 PVR_STATIC_CLEAR_PPP_PDS_TYPE_SHADERBASE = 0,
54 PVR_STATIC_CLEAR_PPP_PDS_TYPE_TEXUNICODEBASE = 1,
55 PVR_STATIC_CLEAR_PPP_PDS_TYPE_SIZEINFO1 = 2,
56 PVR_STATIC_CLEAR_PPP_PDS_TYPE_SIZEINFO2 = 3,
57
58 /* Word enabled by pres_pds_state_ptr1. */
59 PVR_STATIC_CLEAR_PPP_PDS_TYPE_VARYINGBASE = 4,
60
61 /* Word enabled by pres_pds_state_ptr2. */
62 PVR_STATIC_CLEAR_PPP_PDS_TYPE_TEXTUREDATABASE = 5,
63 };
64
65 static_assert(PVR_STATIC_CLEAR_PPP_PDS_TYPE_TEXTUREDATABASE + 1 ==
66 PVR_STATIC_CLEAR_PDS_STATE_COUNT,
67 "pvr_static_clear_ppp_pds_state_type might require fixing.");
68
69 #define PVR_STATIC_CLEAR_VARIANT_COUNT (VK_IMAGE_ASPECT_STENCIL_BIT << 1U)
70
71 struct pvr_bo;
72 struct pvr_cmd_buffer;
73 struct pvr_device;
74 struct pvr_pds_upload;
75 struct pvr_pds_vertex_shader_program;
76
77 struct pvr_static_clear_ppp_base {
78 uint32_t wclamp;
79 uint32_t varying_word[3];
80 uint32_t ppp_ctrl;
81 uint32_t stream_out0;
82 };
83
84 struct pvr_static_clear_ppp_template {
85 /* Pre-packed control words. */
86 uint32_t header;
87 uint32_t ispb;
88
89 bool requires_pds_state;
90
91 /* Configurable control words.
92 * These are initialized and can be modified as needed before emitting them.
93 */
94 struct {
95 struct PVRX(TA_STATE_ISPCTL) ispctl;
96 struct PVRX(TA_STATE_ISPA) ispa;
97
98 /* In case the template requires_pds_state this needs to be a valid
99 * pointer to a pre-packed PDS state before emitting.
100 *
101 * Note: this is a pointer to an array of const uint32_t and not an array
102 * of pointers or a function pointer.
103 */
104 const uint32_t (*pds_state)[PVR_STATIC_CLEAR_PDS_STATE_COUNT];
105
106 struct PVRX(TA_REGION_CLIP0) region_clip0;
107 struct PVRX(TA_REGION_CLIP1) region_clip1;
108
109 struct PVRX(TA_OUTPUT_SEL) output_sel;
110 } config;
111 };
112
113 VkResult pvr_device_init_graphics_static_clear_state(struct pvr_device *device);
114 void pvr_device_finish_graphics_static_clear_state(struct pvr_device *device);
115
116 VkResult pvr_emit_ppp_from_template(
117 struct pvr_csb *const csb,
118 const struct pvr_static_clear_ppp_template *const template,
119 struct pvr_suballoc_bo **const pvr_bo_out);
120
121 void pvr_pds_clear_vertex_shader_program_init_base(
122 struct pvr_pds_vertex_shader_program *program,
123 const struct pvr_suballoc_bo *usc_shader_bo);
124
125 VkResult pvr_pds_clear_vertex_shader_program_create_and_upload(
126 struct pvr_pds_vertex_shader_program *program,
127 struct pvr_device *device,
128 const struct pvr_suballoc_bo *vertices_bo,
129 struct pvr_pds_upload *const upload_out);
130 VkResult pvr_pds_clear_vertex_shader_program_create_and_upload_data(
131 struct pvr_pds_vertex_shader_program *program,
132 struct pvr_cmd_buffer *cmd_buffer,
133 struct pvr_suballoc_bo *vertices_bo,
134 struct pvr_pds_upload *const pds_upload_out);
135
136 void pvr_pds_clear_rta_vertex_shader_program_init_base(
137 struct pvr_pds_vertex_shader_program *program,
138 const struct pvr_suballoc_bo *usc_shader_bo);
139
140 /* Each code and data upload function clears the other's fields in the
141 * pds_upload_out. So when uploading the code, the data fields will be 0.
142 */
143 VkResult pvr_pds_clear_rta_vertex_shader_program_create_and_upload_code(
144 struct pvr_pds_vertex_shader_program *program,
145 struct pvr_cmd_buffer *cmd_buffer,
146 uint32_t base_array_layer,
147 struct pvr_pds_upload *const pds_upload_out);
148
149 static inline VkResult
pvr_pds_clear_rta_vertex_shader_program_create_and_upload_data(struct pvr_pds_vertex_shader_program * program,struct pvr_cmd_buffer * cmd_buffer,struct pvr_suballoc_bo * vertices_bo,struct pvr_pds_upload * const pds_upload_out)150 pvr_pds_clear_rta_vertex_shader_program_create_and_upload_data(
151 struct pvr_pds_vertex_shader_program *program,
152 struct pvr_cmd_buffer *cmd_buffer,
153 struct pvr_suballoc_bo *vertices_bo,
154 struct pvr_pds_upload *const pds_upload_out)
155 {
156 return pvr_pds_clear_vertex_shader_program_create_and_upload_data(
157 program,
158 cmd_buffer,
159 vertices_bo,
160 pds_upload_out);
161 }
162
163 static inline uint32_t
pvr_clear_vdm_state_get_size_in_dw(const struct pvr_device_info * const dev_info,uint32_t layer_count)164 pvr_clear_vdm_state_get_size_in_dw(const struct pvr_device_info *const dev_info,
165 uint32_t layer_count)
166 {
167 uint32_t size_in_dw =
168 pvr_cmd_length(VDMCTRL_VDM_STATE0) + pvr_cmd_length(VDMCTRL_VDM_STATE2) +
169 pvr_cmd_length(VDMCTRL_VDM_STATE3) + pvr_cmd_length(VDMCTRL_VDM_STATE4) +
170 pvr_cmd_length(VDMCTRL_VDM_STATE5) + pvr_cmd_length(VDMCTRL_INDEX_LIST0) +
171 pvr_cmd_length(VDMCTRL_INDEX_LIST2);
172
173 const bool needs_instance_count =
174 !PVR_HAS_FEATURE(dev_info, gs_rta_support) && layer_count > 1;
175
176 if (needs_instance_count)
177 size_in_dw += pvr_cmd_length(VDMCTRL_INDEX_LIST3);
178
179 return size_in_dw;
180 }
181
182 void pvr_pack_clear_vdm_state(const struct pvr_device_info *const dev_info,
183 const struct pvr_pds_upload *const program,
184 uint32_t temps,
185 uint32_t index_count,
186 uint32_t vs_output_size_in_bytes,
187 uint32_t layer_count,
188 uint32_t *const state_buffer);
189
190 VkResult pvr_clear_vertices_upload(struct pvr_device *device,
191 const VkRect2D *rect,
192 float depth,
193 struct pvr_suballoc_bo **const pvr_bo_out);
194
195 #endif /* PVR_CLEAR_H */
196