1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2022 Imagination Technologies Ltd.
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * based in part on v3dv driver which is:
5*61046927SAndroid Build Coastguard Worker * Copyright © 2019 Raspberry Pi
6*61046927SAndroid Build Coastguard Worker *
7*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a copy
8*61046927SAndroid Build Coastguard Worker * of this software and associated documentation files (the "Software"), to deal
9*61046927SAndroid Build Coastguard Worker * in the Software without restriction, including without limitation the rights
10*61046927SAndroid Build Coastguard Worker * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11*61046927SAndroid Build Coastguard Worker * copies of the Software, and to permit persons to whom the Software is
12*61046927SAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions:
13*61046927SAndroid Build Coastguard Worker *
14*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
15*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
16*61046927SAndroid Build Coastguard Worker * Software.
17*61046927SAndroid Build Coastguard Worker *
18*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21*61046927SAndroid Build Coastguard Worker * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23*61046927SAndroid Build Coastguard Worker * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24*61046927SAndroid Build Coastguard Worker * SOFTWARE.
25*61046927SAndroid Build Coastguard Worker */
26*61046927SAndroid Build Coastguard Worker
27*61046927SAndroid Build Coastguard Worker #include <assert.h>
28*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
29*61046927SAndroid Build Coastguard Worker #include <stdint.h>
30*61046927SAndroid Build Coastguard Worker #include <string.h>
31*61046927SAndroid Build Coastguard Worker #include <vulkan/vulkan.h>
32*61046927SAndroid Build Coastguard Worker
33*61046927SAndroid Build Coastguard Worker #include "compiler/shader_enums.h"
34*61046927SAndroid Build Coastguard Worker #include "hwdef/rogue_hw_utils.h"
35*61046927SAndroid Build Coastguard Worker #include "nir/nir.h"
36*61046927SAndroid Build Coastguard Worker #include "pvr_bo.h"
37*61046927SAndroid Build Coastguard Worker #include "pvr_csb.h"
38*61046927SAndroid Build Coastguard Worker #include "pvr_csb_enum_helpers.h"
39*61046927SAndroid Build Coastguard Worker #include "pvr_hardcode.h"
40*61046927SAndroid Build Coastguard Worker #include "pvr_pds.h"
41*61046927SAndroid Build Coastguard Worker #include "pvr_private.h"
42*61046927SAndroid Build Coastguard Worker #include "pvr_robustness.h"
43*61046927SAndroid Build Coastguard Worker #include "pvr_shader.h"
44*61046927SAndroid Build Coastguard Worker #include "pvr_types.h"
45*61046927SAndroid Build Coastguard Worker #include "rogue/rogue.h"
46*61046927SAndroid Build Coastguard Worker #include "util/log.h"
47*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
48*61046927SAndroid Build Coastguard Worker #include "util/ralloc.h"
49*61046927SAndroid Build Coastguard Worker #include "util/u_dynarray.h"
50*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
51*61046927SAndroid Build Coastguard Worker #include "vk_alloc.h"
52*61046927SAndroid Build Coastguard Worker #include "vk_format.h"
53*61046927SAndroid Build Coastguard Worker #include "vk_graphics_state.h"
54*61046927SAndroid Build Coastguard Worker #include "vk_log.h"
55*61046927SAndroid Build Coastguard Worker #include "vk_object.h"
56*61046927SAndroid Build Coastguard Worker #include "vk_pipeline_cache.h"
57*61046927SAndroid Build Coastguard Worker #include "vk_render_pass.h"
58*61046927SAndroid Build Coastguard Worker #include "vk_util.h"
59*61046927SAndroid Build Coastguard Worker
60*61046927SAndroid Build Coastguard Worker /*****************************************************************************
61*61046927SAndroid Build Coastguard Worker PDS functions
62*61046927SAndroid Build Coastguard Worker *****************************************************************************/
63*61046927SAndroid Build Coastguard Worker
64*61046927SAndroid Build Coastguard Worker /* If allocator == NULL, the internal one will be used. */
pvr_pds_coeff_program_create_and_upload(struct pvr_device * device,const VkAllocationCallbacks * allocator,const uint32_t * fpu_iterators,uint32_t fpu_iterators_count,const uint32_t * destinations,struct pvr_pds_upload * const pds_upload_out,uint32_t * const pds_temps_count_out)65*61046927SAndroid Build Coastguard Worker static VkResult pvr_pds_coeff_program_create_and_upload(
66*61046927SAndroid Build Coastguard Worker struct pvr_device *device,
67*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *allocator,
68*61046927SAndroid Build Coastguard Worker const uint32_t *fpu_iterators,
69*61046927SAndroid Build Coastguard Worker uint32_t fpu_iterators_count,
70*61046927SAndroid Build Coastguard Worker const uint32_t *destinations,
71*61046927SAndroid Build Coastguard Worker struct pvr_pds_upload *const pds_upload_out,
72*61046927SAndroid Build Coastguard Worker uint32_t *const pds_temps_count_out)
73*61046927SAndroid Build Coastguard Worker {
74*61046927SAndroid Build Coastguard Worker struct pvr_pds_coeff_loading_program program = {
75*61046927SAndroid Build Coastguard Worker .num_fpu_iterators = fpu_iterators_count,
76*61046927SAndroid Build Coastguard Worker };
77*61046927SAndroid Build Coastguard Worker uint32_t staging_buffer_size;
78*61046927SAndroid Build Coastguard Worker uint32_t *staging_buffer;
79*61046927SAndroid Build Coastguard Worker VkResult result;
80*61046927SAndroid Build Coastguard Worker
81*61046927SAndroid Build Coastguard Worker assert(fpu_iterators_count < PVR_MAXIMUM_ITERATIONS);
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Worker /* Get the size of the program and then allocate that much memory. */
84*61046927SAndroid Build Coastguard Worker pvr_pds_coefficient_loading(&program, NULL, PDS_GENERATE_SIZES);
85*61046927SAndroid Build Coastguard Worker
86*61046927SAndroid Build Coastguard Worker if (!program.code_size) {
87*61046927SAndroid Build Coastguard Worker pds_upload_out->pvr_bo = NULL;
88*61046927SAndroid Build Coastguard Worker pds_upload_out->code_size = 0;
89*61046927SAndroid Build Coastguard Worker pds_upload_out->data_size = 0;
90*61046927SAndroid Build Coastguard Worker *pds_temps_count_out = 0;
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
93*61046927SAndroid Build Coastguard Worker }
94*61046927SAndroid Build Coastguard Worker
95*61046927SAndroid Build Coastguard Worker staging_buffer_size = PVR_DW_TO_BYTES(program.code_size + program.data_size);
96*61046927SAndroid Build Coastguard Worker
97*61046927SAndroid Build Coastguard Worker staging_buffer = vk_alloc2(&device->vk.alloc,
98*61046927SAndroid Build Coastguard Worker allocator,
99*61046927SAndroid Build Coastguard Worker staging_buffer_size,
100*61046927SAndroid Build Coastguard Worker 8,
101*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
102*61046927SAndroid Build Coastguard Worker if (!staging_buffer)
103*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Worker /* FIXME: Should we save pointers when we redesign the pds gen api ? */
106*61046927SAndroid Build Coastguard Worker typed_memcpy(program.FPU_iterators,
107*61046927SAndroid Build Coastguard Worker fpu_iterators,
108*61046927SAndroid Build Coastguard Worker program.num_fpu_iterators);
109*61046927SAndroid Build Coastguard Worker
110*61046927SAndroid Build Coastguard Worker typed_memcpy(program.destination, destinations, program.num_fpu_iterators);
111*61046927SAndroid Build Coastguard Worker
112*61046927SAndroid Build Coastguard Worker /* Generate the program into is the staging_buffer. */
113*61046927SAndroid Build Coastguard Worker pvr_pds_coefficient_loading(&program,
114*61046927SAndroid Build Coastguard Worker staging_buffer,
115*61046927SAndroid Build Coastguard Worker PDS_GENERATE_CODEDATA_SEGMENTS);
116*61046927SAndroid Build Coastguard Worker
117*61046927SAndroid Build Coastguard Worker /* FIXME: Figure out the define for alignment of 16. */
118*61046927SAndroid Build Coastguard Worker result = pvr_gpu_upload_pds(device,
119*61046927SAndroid Build Coastguard Worker &staging_buffer[0],
120*61046927SAndroid Build Coastguard Worker program.data_size,
121*61046927SAndroid Build Coastguard Worker 16,
122*61046927SAndroid Build Coastguard Worker &staging_buffer[program.data_size],
123*61046927SAndroid Build Coastguard Worker program.code_size,
124*61046927SAndroid Build Coastguard Worker 16,
125*61046927SAndroid Build Coastguard Worker 16,
126*61046927SAndroid Build Coastguard Worker pds_upload_out);
127*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
128*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, staging_buffer);
129*61046927SAndroid Build Coastguard Worker return result;
130*61046927SAndroid Build Coastguard Worker }
131*61046927SAndroid Build Coastguard Worker
132*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, staging_buffer);
133*61046927SAndroid Build Coastguard Worker
134*61046927SAndroid Build Coastguard Worker *pds_temps_count_out = program.temps_used;
135*61046927SAndroid Build Coastguard Worker
136*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
137*61046927SAndroid Build Coastguard Worker }
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker /* FIXME: move this elsewhere since it's also called in pvr_pass.c? */
140*61046927SAndroid Build Coastguard Worker /* If allocator == NULL, the internal one will be used. */
pvr_pds_fragment_program_create_and_upload(struct pvr_device * device,const VkAllocationCallbacks * allocator,const struct pvr_suballoc_bo * fragment_shader_bo,uint32_t fragment_temp_count,enum rogue_msaa_mode msaa_mode,bool has_phase_rate_change,struct pvr_pds_upload * const pds_upload_out)141*61046927SAndroid Build Coastguard Worker VkResult pvr_pds_fragment_program_create_and_upload(
142*61046927SAndroid Build Coastguard Worker struct pvr_device *device,
143*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *allocator,
144*61046927SAndroid Build Coastguard Worker const struct pvr_suballoc_bo *fragment_shader_bo,
145*61046927SAndroid Build Coastguard Worker uint32_t fragment_temp_count,
146*61046927SAndroid Build Coastguard Worker enum rogue_msaa_mode msaa_mode,
147*61046927SAndroid Build Coastguard Worker bool has_phase_rate_change,
148*61046927SAndroid Build Coastguard Worker struct pvr_pds_upload *const pds_upload_out)
149*61046927SAndroid Build Coastguard Worker {
150*61046927SAndroid Build Coastguard Worker const enum PVRX(PDSINST_DOUTU_SAMPLE_RATE)
151*61046927SAndroid Build Coastguard Worker sample_rate = pvr_pdsinst_doutu_sample_rate_from_rogue(msaa_mode);
152*61046927SAndroid Build Coastguard Worker struct pvr_pds_kickusc_program program = { 0 };
153*61046927SAndroid Build Coastguard Worker uint32_t staging_buffer_size;
154*61046927SAndroid Build Coastguard Worker uint32_t *staging_buffer;
155*61046927SAndroid Build Coastguard Worker VkResult result;
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker /* FIXME: Should it be passing in the USC offset rather than address here?
158*61046927SAndroid Build Coastguard Worker */
159*61046927SAndroid Build Coastguard Worker /* Note this is not strictly required to be done before calculating the
160*61046927SAndroid Build Coastguard Worker * staging_buffer_size in this particular case. It can also be done after
161*61046927SAndroid Build Coastguard Worker * allocating the buffer. The size from pvr_pds_kick_usc() is constant.
162*61046927SAndroid Build Coastguard Worker */
163*61046927SAndroid Build Coastguard Worker pvr_pds_setup_doutu(&program.usc_task_control,
164*61046927SAndroid Build Coastguard Worker fragment_shader_bo->dev_addr.addr,
165*61046927SAndroid Build Coastguard Worker fragment_temp_count,
166*61046927SAndroid Build Coastguard Worker sample_rate,
167*61046927SAndroid Build Coastguard Worker has_phase_rate_change);
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard Worker pvr_pds_kick_usc(&program, NULL, 0, false, PDS_GENERATE_SIZES);
170*61046927SAndroid Build Coastguard Worker
171*61046927SAndroid Build Coastguard Worker staging_buffer_size = PVR_DW_TO_BYTES(program.code_size + program.data_size);
172*61046927SAndroid Build Coastguard Worker
173*61046927SAndroid Build Coastguard Worker staging_buffer = vk_alloc2(&device->vk.alloc,
174*61046927SAndroid Build Coastguard Worker allocator,
175*61046927SAndroid Build Coastguard Worker staging_buffer_size,
176*61046927SAndroid Build Coastguard Worker 8,
177*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
178*61046927SAndroid Build Coastguard Worker if (!staging_buffer)
179*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
180*61046927SAndroid Build Coastguard Worker
181*61046927SAndroid Build Coastguard Worker pvr_pds_kick_usc(&program,
182*61046927SAndroid Build Coastguard Worker staging_buffer,
183*61046927SAndroid Build Coastguard Worker 0,
184*61046927SAndroid Build Coastguard Worker false,
185*61046927SAndroid Build Coastguard Worker PDS_GENERATE_CODEDATA_SEGMENTS);
186*61046927SAndroid Build Coastguard Worker
187*61046927SAndroid Build Coastguard Worker /* FIXME: Figure out the define for alignment of 16. */
188*61046927SAndroid Build Coastguard Worker result = pvr_gpu_upload_pds(device,
189*61046927SAndroid Build Coastguard Worker &staging_buffer[0],
190*61046927SAndroid Build Coastguard Worker program.data_size,
191*61046927SAndroid Build Coastguard Worker 16,
192*61046927SAndroid Build Coastguard Worker &staging_buffer[program.data_size],
193*61046927SAndroid Build Coastguard Worker program.code_size,
194*61046927SAndroid Build Coastguard Worker 16,
195*61046927SAndroid Build Coastguard Worker 16,
196*61046927SAndroid Build Coastguard Worker pds_upload_out);
197*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
198*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, staging_buffer);
199*61046927SAndroid Build Coastguard Worker return result;
200*61046927SAndroid Build Coastguard Worker }
201*61046927SAndroid Build Coastguard Worker
202*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, staging_buffer);
203*61046927SAndroid Build Coastguard Worker
204*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
205*61046927SAndroid Build Coastguard Worker }
206*61046927SAndroid Build Coastguard Worker
pvr_pds_get_max_vertex_program_const_map_size_in_bytes(const struct pvr_device_info * dev_info,bool robust_buffer_access)207*61046927SAndroid Build Coastguard Worker static inline size_t pvr_pds_get_max_vertex_program_const_map_size_in_bytes(
208*61046927SAndroid Build Coastguard Worker const struct pvr_device_info *dev_info,
209*61046927SAndroid Build Coastguard Worker bool robust_buffer_access)
210*61046927SAndroid Build Coastguard Worker {
211*61046927SAndroid Build Coastguard Worker /* FIXME: Use more local variable to improve formatting. */
212*61046927SAndroid Build Coastguard Worker
213*61046927SAndroid Build Coastguard Worker /* Maximum memory allocation needed for const map entries in
214*61046927SAndroid Build Coastguard Worker * pvr_pds_generate_vertex_primary_program().
215*61046927SAndroid Build Coastguard Worker * When robustBufferAccess is disabled, it must be >= 410.
216*61046927SAndroid Build Coastguard Worker * When robustBufferAccess is enabled, it must be >= 570.
217*61046927SAndroid Build Coastguard Worker *
218*61046927SAndroid Build Coastguard Worker * 1. Size of entry for base instance
219*61046927SAndroid Build Coastguard Worker * (pvr_const_map_entry_base_instance)
220*61046927SAndroid Build Coastguard Worker *
221*61046927SAndroid Build Coastguard Worker * 2. Max. number of vertex inputs (PVR_MAX_VERTEX_INPUT_BINDINGS) * (
222*61046927SAndroid Build Coastguard Worker * if (!robustBufferAccess)
223*61046927SAndroid Build Coastguard Worker * size of vertex attribute entry
224*61046927SAndroid Build Coastguard Worker * (pvr_const_map_entry_vertex_attribute_address) +
225*61046927SAndroid Build Coastguard Worker * else
226*61046927SAndroid Build Coastguard Worker * size of robust vertex attribute entry
227*61046927SAndroid Build Coastguard Worker * (pvr_const_map_entry_robust_vertex_attribute_address) +
228*61046927SAndroid Build Coastguard Worker * size of entry for max attribute index
229*61046927SAndroid Build Coastguard Worker * (pvr_const_map_entry_vertex_attribute_max_index) +
230*61046927SAndroid Build Coastguard Worker * fi
231*61046927SAndroid Build Coastguard Worker * size of Unified Store burst entry
232*61046927SAndroid Build Coastguard Worker * (pvr_const_map_entry_literal32) +
233*61046927SAndroid Build Coastguard Worker * size of entry for vertex stride
234*61046927SAndroid Build Coastguard Worker * (pvr_const_map_entry_literal32) +
235*61046927SAndroid Build Coastguard Worker * size of entries for DDMAD control word
236*61046927SAndroid Build Coastguard Worker * (num_ddmad_literals * pvr_const_map_entry_literal32))
237*61046927SAndroid Build Coastguard Worker *
238*61046927SAndroid Build Coastguard Worker * 3. Size of entry for DOUTW vertex/instance control word
239*61046927SAndroid Build Coastguard Worker * (pvr_const_map_entry_literal32)
240*61046927SAndroid Build Coastguard Worker *
241*61046927SAndroid Build Coastguard Worker * 4. Size of DOUTU entry (pvr_const_map_entry_doutu_address)
242*61046927SAndroid Build Coastguard Worker */
243*61046927SAndroid Build Coastguard Worker
244*61046927SAndroid Build Coastguard Worker const size_t attribute_size =
245*61046927SAndroid Build Coastguard Worker (!robust_buffer_access)
246*61046927SAndroid Build Coastguard Worker ? sizeof(struct pvr_const_map_entry_vertex_attribute_address)
247*61046927SAndroid Build Coastguard Worker : sizeof(struct pvr_const_map_entry_robust_vertex_attribute_address) +
248*61046927SAndroid Build Coastguard Worker sizeof(struct pvr_const_map_entry_vertex_attribute_max_index);
249*61046927SAndroid Build Coastguard Worker
250*61046927SAndroid Build Coastguard Worker /* If has_pds_ddmadt the DDMAD control word is now a DDMADT control word
251*61046927SAndroid Build Coastguard Worker * and is increased by one DWORD to contain the data for the DDMADT's
252*61046927SAndroid Build Coastguard Worker * out-of-bounds check.
253*61046927SAndroid Build Coastguard Worker */
254*61046927SAndroid Build Coastguard Worker const size_t pvr_pds_const_map_vertex_entry_num_ddmad_literals =
255*61046927SAndroid Build Coastguard Worker 1U + (size_t)PVR_HAS_FEATURE(dev_info, pds_ddmadt);
256*61046927SAndroid Build Coastguard Worker
257*61046927SAndroid Build Coastguard Worker return (sizeof(struct pvr_const_map_entry_base_instance) +
258*61046927SAndroid Build Coastguard Worker PVR_MAX_VERTEX_INPUT_BINDINGS *
259*61046927SAndroid Build Coastguard Worker (attribute_size +
260*61046927SAndroid Build Coastguard Worker (2 + pvr_pds_const_map_vertex_entry_num_ddmad_literals) *
261*61046927SAndroid Build Coastguard Worker sizeof(struct pvr_const_map_entry_literal32)) +
262*61046927SAndroid Build Coastguard Worker sizeof(struct pvr_const_map_entry_literal32) +
263*61046927SAndroid Build Coastguard Worker sizeof(struct pvr_const_map_entry_doutu_address));
264*61046927SAndroid Build Coastguard Worker }
265*61046927SAndroid Build Coastguard Worker
266*61046927SAndroid Build Coastguard Worker /* This is a const pointer to an array of pvr_pds_vertex_dma structs.
267*61046927SAndroid Build Coastguard Worker * The array being pointed to is of PVR_MAX_VERTEX_ATTRIB_DMAS size.
268*61046927SAndroid Build Coastguard Worker */
269*61046927SAndroid Build Coastguard Worker typedef struct pvr_pds_vertex_dma (
270*61046927SAndroid Build Coastguard Worker *const
271*61046927SAndroid Build Coastguard Worker pvr_pds_attrib_dma_descriptions_array_ptr)[PVR_MAX_VERTEX_ATTRIB_DMAS];
272*61046927SAndroid Build Coastguard Worker
273*61046927SAndroid Build Coastguard Worker /* dma_descriptions_out_ptr is a pointer to the array used as output.
274*61046927SAndroid Build Coastguard Worker * The whole array might not be filled so dma_count_out indicates how many
275*61046927SAndroid Build Coastguard Worker * elements were used.
276*61046927SAndroid Build Coastguard Worker */
pvr_pds_vertex_attrib_init_dma_descriptions(const VkPipelineVertexInputStateCreateInfo * const vertex_input_state,const struct rogue_vs_build_data * vs_data,pvr_pds_attrib_dma_descriptions_array_ptr dma_descriptions_out_ptr,uint32_t * const dma_count_out)277*61046927SAndroid Build Coastguard Worker static void pvr_pds_vertex_attrib_init_dma_descriptions(
278*61046927SAndroid Build Coastguard Worker const VkPipelineVertexInputStateCreateInfo *const vertex_input_state,
279*61046927SAndroid Build Coastguard Worker const struct rogue_vs_build_data *vs_data,
280*61046927SAndroid Build Coastguard Worker pvr_pds_attrib_dma_descriptions_array_ptr dma_descriptions_out_ptr,
281*61046927SAndroid Build Coastguard Worker uint32_t *const dma_count_out)
282*61046927SAndroid Build Coastguard Worker {
283*61046927SAndroid Build Coastguard Worker struct pvr_pds_vertex_dma *const dma_descriptions =
284*61046927SAndroid Build Coastguard Worker *dma_descriptions_out_ptr;
285*61046927SAndroid Build Coastguard Worker uint32_t dma_count = 0;
286*61046927SAndroid Build Coastguard Worker
287*61046927SAndroid Build Coastguard Worker if (!vertex_input_state) {
288*61046927SAndroid Build Coastguard Worker *dma_count_out = 0;
289*61046927SAndroid Build Coastguard Worker return;
290*61046927SAndroid Build Coastguard Worker }
291*61046927SAndroid Build Coastguard Worker
292*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < vertex_input_state->vertexAttributeDescriptionCount;
293*61046927SAndroid Build Coastguard Worker i++) {
294*61046927SAndroid Build Coastguard Worker const VkVertexInputAttributeDescription *const attrib_desc =
295*61046927SAndroid Build Coastguard Worker &vertex_input_state->pVertexAttributeDescriptions[i];
296*61046927SAndroid Build Coastguard Worker const VkVertexInputBindingDescription *binding_desc = NULL;
297*61046927SAndroid Build Coastguard Worker struct pvr_pds_vertex_dma *const dma_desc = &dma_descriptions[dma_count];
298*61046927SAndroid Build Coastguard Worker size_t location = attrib_desc->location;
299*61046927SAndroid Build Coastguard Worker
300*61046927SAndroid Build Coastguard Worker assert(location < vs_data->inputs.num_input_vars);
301*61046927SAndroid Build Coastguard Worker
302*61046927SAndroid Build Coastguard Worker /* Finding the matching binding description. */
303*61046927SAndroid Build Coastguard Worker for (uint32_t j = 0;
304*61046927SAndroid Build Coastguard Worker j < vertex_input_state->vertexBindingDescriptionCount;
305*61046927SAndroid Build Coastguard Worker j++) {
306*61046927SAndroid Build Coastguard Worker const VkVertexInputBindingDescription *const current_binding_desc =
307*61046927SAndroid Build Coastguard Worker &vertex_input_state->pVertexBindingDescriptions[j];
308*61046927SAndroid Build Coastguard Worker
309*61046927SAndroid Build Coastguard Worker if (current_binding_desc->binding == attrib_desc->binding) {
310*61046927SAndroid Build Coastguard Worker binding_desc = current_binding_desc;
311*61046927SAndroid Build Coastguard Worker break;
312*61046927SAndroid Build Coastguard Worker }
313*61046927SAndroid Build Coastguard Worker }
314*61046927SAndroid Build Coastguard Worker
315*61046927SAndroid Build Coastguard Worker /* From the Vulkan 1.2.195 spec for
316*61046927SAndroid Build Coastguard Worker * VkPipelineVertexInputStateCreateInfo:
317*61046927SAndroid Build Coastguard Worker *
318*61046927SAndroid Build Coastguard Worker * "For every binding specified by each element of
319*61046927SAndroid Build Coastguard Worker * pVertexAttributeDescriptions, a
320*61046927SAndroid Build Coastguard Worker * VkVertexInputBindingDescription must exist in
321*61046927SAndroid Build Coastguard Worker * pVertexBindingDescriptions with the same value of binding"
322*61046927SAndroid Build Coastguard Worker */
323*61046927SAndroid Build Coastguard Worker assert(binding_desc);
324*61046927SAndroid Build Coastguard Worker
325*61046927SAndroid Build Coastguard Worker dma_desc->offset = attrib_desc->offset;
326*61046927SAndroid Build Coastguard Worker dma_desc->stride = binding_desc->stride;
327*61046927SAndroid Build Coastguard Worker
328*61046927SAndroid Build Coastguard Worker dma_desc->flags = 0;
329*61046927SAndroid Build Coastguard Worker
330*61046927SAndroid Build Coastguard Worker if (binding_desc->inputRate == VK_VERTEX_INPUT_RATE_INSTANCE)
331*61046927SAndroid Build Coastguard Worker dma_desc->flags |= PVR_PDS_VERTEX_DMA_FLAGS_INSTANCE_RATE;
332*61046927SAndroid Build Coastguard Worker
333*61046927SAndroid Build Coastguard Worker dma_desc->size_in_dwords = vs_data->inputs.components[location];
334*61046927SAndroid Build Coastguard Worker /* TODO: This will be different when other types are supported.
335*61046927SAndroid Build Coastguard Worker * Store in vs_data with base and components?
336*61046927SAndroid Build Coastguard Worker */
337*61046927SAndroid Build Coastguard Worker /* TODO: Use attrib_desc->format. */
338*61046927SAndroid Build Coastguard Worker dma_desc->component_size_in_bytes = ROGUE_REG_SIZE_BYTES;
339*61046927SAndroid Build Coastguard Worker dma_desc->destination = vs_data->inputs.base[location];
340*61046927SAndroid Build Coastguard Worker dma_desc->binding_index = attrib_desc->binding;
341*61046927SAndroid Build Coastguard Worker dma_desc->divisor = 1;
342*61046927SAndroid Build Coastguard Worker
343*61046927SAndroid Build Coastguard Worker dma_desc->robustness_buffer_offset =
344*61046927SAndroid Build Coastguard Worker pvr_get_robustness_buffer_format_offset(attrib_desc->format);
345*61046927SAndroid Build Coastguard Worker
346*61046927SAndroid Build Coastguard Worker ++dma_count;
347*61046927SAndroid Build Coastguard Worker }
348*61046927SAndroid Build Coastguard Worker
349*61046927SAndroid Build Coastguard Worker *dma_count_out = dma_count;
350*61046927SAndroid Build Coastguard Worker }
351*61046927SAndroid Build Coastguard Worker
pvr_pds_vertex_attrib_program_create_and_upload(struct pvr_device * const device,const VkAllocationCallbacks * const allocator,struct pvr_pds_vertex_primary_program_input * const input,struct pvr_pds_attrib_program * const program_out)352*61046927SAndroid Build Coastguard Worker static VkResult pvr_pds_vertex_attrib_program_create_and_upload(
353*61046927SAndroid Build Coastguard Worker struct pvr_device *const device,
354*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *const allocator,
355*61046927SAndroid Build Coastguard Worker struct pvr_pds_vertex_primary_program_input *const input,
356*61046927SAndroid Build Coastguard Worker struct pvr_pds_attrib_program *const program_out)
357*61046927SAndroid Build Coastguard Worker {
358*61046927SAndroid Build Coastguard Worker const size_t const_entries_size_in_bytes =
359*61046927SAndroid Build Coastguard Worker pvr_pds_get_max_vertex_program_const_map_size_in_bytes(
360*61046927SAndroid Build Coastguard Worker &device->pdevice->dev_info,
361*61046927SAndroid Build Coastguard Worker device->vk.enabled_features.robustBufferAccess);
362*61046927SAndroid Build Coastguard Worker struct pvr_pds_upload *const program = &program_out->program;
363*61046927SAndroid Build Coastguard Worker struct pvr_pds_info *const info = &program_out->info;
364*61046927SAndroid Build Coastguard Worker struct pvr_const_map_entry *new_entries;
365*61046927SAndroid Build Coastguard Worker ASSERTED uint32_t code_size_in_dwords;
366*61046927SAndroid Build Coastguard Worker size_t staging_buffer_size;
367*61046927SAndroid Build Coastguard Worker uint32_t *staging_buffer;
368*61046927SAndroid Build Coastguard Worker VkResult result;
369*61046927SAndroid Build Coastguard Worker
370*61046927SAndroid Build Coastguard Worker memset(info, 0, sizeof(*info));
371*61046927SAndroid Build Coastguard Worker
372*61046927SAndroid Build Coastguard Worker info->entries = vk_alloc2(&device->vk.alloc,
373*61046927SAndroid Build Coastguard Worker allocator,
374*61046927SAndroid Build Coastguard Worker const_entries_size_in_bytes,
375*61046927SAndroid Build Coastguard Worker 8,
376*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
377*61046927SAndroid Build Coastguard Worker if (!info->entries) {
378*61046927SAndroid Build Coastguard Worker result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
379*61046927SAndroid Build Coastguard Worker goto err_out;
380*61046927SAndroid Build Coastguard Worker }
381*61046927SAndroid Build Coastguard Worker
382*61046927SAndroid Build Coastguard Worker info->entries_size_in_bytes = const_entries_size_in_bytes;
383*61046927SAndroid Build Coastguard Worker
384*61046927SAndroid Build Coastguard Worker pvr_pds_generate_vertex_primary_program(
385*61046927SAndroid Build Coastguard Worker input,
386*61046927SAndroid Build Coastguard Worker NULL,
387*61046927SAndroid Build Coastguard Worker info,
388*61046927SAndroid Build Coastguard Worker device->vk.enabled_features.robustBufferAccess,
389*61046927SAndroid Build Coastguard Worker &device->pdevice->dev_info);
390*61046927SAndroid Build Coastguard Worker
391*61046927SAndroid Build Coastguard Worker code_size_in_dwords = info->code_size_in_dwords;
392*61046927SAndroid Build Coastguard Worker staging_buffer_size = PVR_DW_TO_BYTES(info->code_size_in_dwords);
393*61046927SAndroid Build Coastguard Worker
394*61046927SAndroid Build Coastguard Worker staging_buffer = vk_alloc2(&device->vk.alloc,
395*61046927SAndroid Build Coastguard Worker allocator,
396*61046927SAndroid Build Coastguard Worker staging_buffer_size,
397*61046927SAndroid Build Coastguard Worker 8,
398*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
399*61046927SAndroid Build Coastguard Worker if (!staging_buffer) {
400*61046927SAndroid Build Coastguard Worker result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
401*61046927SAndroid Build Coastguard Worker goto err_free_entries;
402*61046927SAndroid Build Coastguard Worker }
403*61046927SAndroid Build Coastguard Worker
404*61046927SAndroid Build Coastguard Worker /* This also fills in info->entries. */
405*61046927SAndroid Build Coastguard Worker pvr_pds_generate_vertex_primary_program(
406*61046927SAndroid Build Coastguard Worker input,
407*61046927SAndroid Build Coastguard Worker staging_buffer,
408*61046927SAndroid Build Coastguard Worker info,
409*61046927SAndroid Build Coastguard Worker device->vk.enabled_features.robustBufferAccess,
410*61046927SAndroid Build Coastguard Worker &device->pdevice->dev_info);
411*61046927SAndroid Build Coastguard Worker
412*61046927SAndroid Build Coastguard Worker assert(info->code_size_in_dwords <= code_size_in_dwords);
413*61046927SAndroid Build Coastguard Worker
414*61046927SAndroid Build Coastguard Worker /* FIXME: Add a vk_realloc2() ? */
415*61046927SAndroid Build Coastguard Worker new_entries = vk_realloc((!allocator) ? &device->vk.alloc : allocator,
416*61046927SAndroid Build Coastguard Worker info->entries,
417*61046927SAndroid Build Coastguard Worker info->entries_written_size_in_bytes,
418*61046927SAndroid Build Coastguard Worker 8,
419*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
420*61046927SAndroid Build Coastguard Worker if (!new_entries) {
421*61046927SAndroid Build Coastguard Worker result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
422*61046927SAndroid Build Coastguard Worker goto err_free_staging_buffer;
423*61046927SAndroid Build Coastguard Worker }
424*61046927SAndroid Build Coastguard Worker
425*61046927SAndroid Build Coastguard Worker info->entries = new_entries;
426*61046927SAndroid Build Coastguard Worker info->entries_size_in_bytes = info->entries_written_size_in_bytes;
427*61046927SAndroid Build Coastguard Worker
428*61046927SAndroid Build Coastguard Worker /* FIXME: Figure out the define for alignment of 16. */
429*61046927SAndroid Build Coastguard Worker result = pvr_gpu_upload_pds(device,
430*61046927SAndroid Build Coastguard Worker NULL,
431*61046927SAndroid Build Coastguard Worker 0,
432*61046927SAndroid Build Coastguard Worker 0,
433*61046927SAndroid Build Coastguard Worker staging_buffer,
434*61046927SAndroid Build Coastguard Worker info->code_size_in_dwords,
435*61046927SAndroid Build Coastguard Worker 16,
436*61046927SAndroid Build Coastguard Worker 16,
437*61046927SAndroid Build Coastguard Worker program);
438*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
439*61046927SAndroid Build Coastguard Worker goto err_free_staging_buffer;
440*61046927SAndroid Build Coastguard Worker
441*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, staging_buffer);
442*61046927SAndroid Build Coastguard Worker
443*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
444*61046927SAndroid Build Coastguard Worker
445*61046927SAndroid Build Coastguard Worker err_free_staging_buffer:
446*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, staging_buffer);
447*61046927SAndroid Build Coastguard Worker
448*61046927SAndroid Build Coastguard Worker err_free_entries:
449*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, info->entries);
450*61046927SAndroid Build Coastguard Worker
451*61046927SAndroid Build Coastguard Worker err_out:
452*61046927SAndroid Build Coastguard Worker return result;
453*61046927SAndroid Build Coastguard Worker }
454*61046927SAndroid Build Coastguard Worker
pvr_pds_vertex_attrib_program_destroy(struct pvr_device * const device,const struct VkAllocationCallbacks * const allocator,struct pvr_pds_attrib_program * const program)455*61046927SAndroid Build Coastguard Worker static inline void pvr_pds_vertex_attrib_program_destroy(
456*61046927SAndroid Build Coastguard Worker struct pvr_device *const device,
457*61046927SAndroid Build Coastguard Worker const struct VkAllocationCallbacks *const allocator,
458*61046927SAndroid Build Coastguard Worker struct pvr_pds_attrib_program *const program)
459*61046927SAndroid Build Coastguard Worker {
460*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(program->program.pvr_bo);
461*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, program->info.entries);
462*61046927SAndroid Build Coastguard Worker }
463*61046927SAndroid Build Coastguard Worker
464*61046927SAndroid Build Coastguard Worker /* This is a const pointer to an array of pvr_pds_attrib_program structs.
465*61046927SAndroid Build Coastguard Worker * The array being pointed to is of PVR_PDS_VERTEX_ATTRIB_PROGRAM_COUNT size.
466*61046927SAndroid Build Coastguard Worker */
467*61046927SAndroid Build Coastguard Worker typedef struct pvr_pds_attrib_program (*const pvr_pds_attrib_programs_array_ptr)
468*61046927SAndroid Build Coastguard Worker [PVR_PDS_VERTEX_ATTRIB_PROGRAM_COUNT];
469*61046927SAndroid Build Coastguard Worker
470*61046927SAndroid Build Coastguard Worker /* Indicates that the special variable is unused and has not been allocated a
471*61046927SAndroid Build Coastguard Worker * register.
472*61046927SAndroid Build Coastguard Worker */
473*61046927SAndroid Build Coastguard Worker #define PVR_VERTEX_SPECIAL_VAR_UNUSED (-1)
474*61046927SAndroid Build Coastguard Worker
475*61046927SAndroid Build Coastguard Worker /* Each special variable gets allocated its own vtxin reg if used. */
476*61046927SAndroid Build Coastguard Worker struct pvr_vertex_special_vars {
477*61046927SAndroid Build Coastguard Worker /* VertexIndex built-in. */
478*61046927SAndroid Build Coastguard Worker int16_t vertex_id_offset;
479*61046927SAndroid Build Coastguard Worker /* InstanceIndex built-in. */
480*61046927SAndroid Build Coastguard Worker int16_t instance_id_offset;
481*61046927SAndroid Build Coastguard Worker };
482*61046927SAndroid Build Coastguard Worker
483*61046927SAndroid Build Coastguard Worker /* Generate and uploads a PDS program for DMAing vertex attribs into USC vertex
484*61046927SAndroid Build Coastguard Worker * inputs. This will bake the code segment and create a template of the data
485*61046927SAndroid Build Coastguard Worker * segment for the command buffer to fill in.
486*61046927SAndroid Build Coastguard Worker */
487*61046927SAndroid Build Coastguard Worker /* If allocator == NULL, the internal one will be used.
488*61046927SAndroid Build Coastguard Worker *
489*61046927SAndroid Build Coastguard Worker * programs_out_ptr is a pointer to the array where the outputs will be placed.
490*61046927SAndroid Build Coastguard Worker */
pvr_pds_vertex_attrib_programs_create_and_upload(struct pvr_device * device,const VkAllocationCallbacks * const allocator,const VkPipelineVertexInputStateCreateInfo * const vertex_input_state,uint32_t usc_temp_count,const struct rogue_vs_build_data * vs_data,const struct pvr_pds_vertex_dma dma_descriptions[static const PVR_MAX_VERTEX_ATTRIB_DMAS],uint32_t dma_count,const struct pvr_vertex_special_vars * special_vars_layout,pvr_pds_attrib_programs_array_ptr programs_out_ptr)491*61046927SAndroid Build Coastguard Worker static VkResult pvr_pds_vertex_attrib_programs_create_and_upload(
492*61046927SAndroid Build Coastguard Worker struct pvr_device *device,
493*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *const allocator,
494*61046927SAndroid Build Coastguard Worker const VkPipelineVertexInputStateCreateInfo *const vertex_input_state,
495*61046927SAndroid Build Coastguard Worker uint32_t usc_temp_count,
496*61046927SAndroid Build Coastguard Worker const struct rogue_vs_build_data *vs_data,
497*61046927SAndroid Build Coastguard Worker
498*61046927SAndroid Build Coastguard Worker /* Needed for the new path. */
499*61046927SAndroid Build Coastguard Worker /* TODO: Remove some of the above once the compiler is hooked up. */
500*61046927SAndroid Build Coastguard Worker const struct pvr_pds_vertex_dma
501*61046927SAndroid Build Coastguard Worker dma_descriptions[static const PVR_MAX_VERTEX_ATTRIB_DMAS],
502*61046927SAndroid Build Coastguard Worker uint32_t dma_count,
503*61046927SAndroid Build Coastguard Worker const struct pvr_vertex_special_vars *special_vars_layout,
504*61046927SAndroid Build Coastguard Worker
505*61046927SAndroid Build Coastguard Worker pvr_pds_attrib_programs_array_ptr programs_out_ptr)
506*61046927SAndroid Build Coastguard Worker {
507*61046927SAndroid Build Coastguard Worker struct pvr_pds_vertex_dma dma_descriptions_old[PVR_MAX_VERTEX_ATTRIB_DMAS];
508*61046927SAndroid Build Coastguard Worker
509*61046927SAndroid Build Coastguard Worker struct pvr_pds_attrib_program *const programs_out = *programs_out_ptr;
510*61046927SAndroid Build Coastguard Worker struct pvr_pds_vertex_primary_program_input input = { 0 };
511*61046927SAndroid Build Coastguard Worker VkResult result;
512*61046927SAndroid Build Coastguard Worker
513*61046927SAndroid Build Coastguard Worker const bool old_path = pvr_has_hard_coded_shaders(&device->pdevice->dev_info);
514*61046927SAndroid Build Coastguard Worker
515*61046927SAndroid Build Coastguard Worker if (old_path) {
516*61046927SAndroid Build Coastguard Worker pvr_pds_vertex_attrib_init_dma_descriptions(vertex_input_state,
517*61046927SAndroid Build Coastguard Worker vs_data,
518*61046927SAndroid Build Coastguard Worker &dma_descriptions_old,
519*61046927SAndroid Build Coastguard Worker &input.dma_count);
520*61046927SAndroid Build Coastguard Worker
521*61046927SAndroid Build Coastguard Worker input.dma_list = dma_descriptions_old;
522*61046927SAndroid Build Coastguard Worker } else {
523*61046927SAndroid Build Coastguard Worker input.dma_list = dma_descriptions;
524*61046927SAndroid Build Coastguard Worker input.dma_count = dma_count;
525*61046927SAndroid Build Coastguard Worker
526*61046927SAndroid Build Coastguard Worker if (special_vars_layout->vertex_id_offset !=
527*61046927SAndroid Build Coastguard Worker PVR_VERTEX_SPECIAL_VAR_UNUSED) {
528*61046927SAndroid Build Coastguard Worker /* Gets filled by the HW and copied into the appropriate reg. */
529*61046927SAndroid Build Coastguard Worker input.flags |= PVR_PDS_VERTEX_FLAGS_VERTEX_ID_REQUIRED;
530*61046927SAndroid Build Coastguard Worker input.vertex_id_register = special_vars_layout->vertex_id_offset;
531*61046927SAndroid Build Coastguard Worker }
532*61046927SAndroid Build Coastguard Worker
533*61046927SAndroid Build Coastguard Worker if (special_vars_layout->instance_id_offset !=
534*61046927SAndroid Build Coastguard Worker PVR_VERTEX_SPECIAL_VAR_UNUSED) {
535*61046927SAndroid Build Coastguard Worker /* Gets filled by the HW and copied into the appropriate reg. */
536*61046927SAndroid Build Coastguard Worker input.flags |= PVR_PDS_VERTEX_FLAGS_INSTANCE_ID_REQUIRED;
537*61046927SAndroid Build Coastguard Worker input.instance_id_register = special_vars_layout->instance_id_offset;
538*61046927SAndroid Build Coastguard Worker }
539*61046927SAndroid Build Coastguard Worker }
540*61046927SAndroid Build Coastguard Worker
541*61046927SAndroid Build Coastguard Worker pvr_pds_setup_doutu(&input.usc_task_control,
542*61046927SAndroid Build Coastguard Worker 0,
543*61046927SAndroid Build Coastguard Worker usc_temp_count,
544*61046927SAndroid Build Coastguard Worker PVRX(PDSINST_DOUTU_SAMPLE_RATE_INSTANCE),
545*61046927SAndroid Build Coastguard Worker false);
546*61046927SAndroid Build Coastguard Worker
547*61046927SAndroid Build Coastguard Worker /* Note: programs_out_ptr is a pointer to an array so this is fine. See the
548*61046927SAndroid Build Coastguard Worker * typedef.
549*61046927SAndroid Build Coastguard Worker */
550*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < ARRAY_SIZE(*programs_out_ptr); i++) {
551*61046927SAndroid Build Coastguard Worker uint32_t extra_flags;
552*61046927SAndroid Build Coastguard Worker
553*61046927SAndroid Build Coastguard Worker switch (i) {
554*61046927SAndroid Build Coastguard Worker case PVR_PDS_VERTEX_ATTRIB_PROGRAM_BASIC:
555*61046927SAndroid Build Coastguard Worker extra_flags = 0;
556*61046927SAndroid Build Coastguard Worker break;
557*61046927SAndroid Build Coastguard Worker
558*61046927SAndroid Build Coastguard Worker case PVR_PDS_VERTEX_ATTRIB_PROGRAM_BASE_INSTANCE:
559*61046927SAndroid Build Coastguard Worker extra_flags = PVR_PDS_VERTEX_FLAGS_BASE_INSTANCE_VARIANT;
560*61046927SAndroid Build Coastguard Worker break;
561*61046927SAndroid Build Coastguard Worker
562*61046927SAndroid Build Coastguard Worker case PVR_PDS_VERTEX_ATTRIB_PROGRAM_DRAW_INDIRECT:
563*61046927SAndroid Build Coastguard Worker extra_flags = PVR_PDS_VERTEX_FLAGS_DRAW_INDIRECT_VARIANT;
564*61046927SAndroid Build Coastguard Worker break;
565*61046927SAndroid Build Coastguard Worker
566*61046927SAndroid Build Coastguard Worker default:
567*61046927SAndroid Build Coastguard Worker unreachable("Invalid vertex attrib program type.");
568*61046927SAndroid Build Coastguard Worker }
569*61046927SAndroid Build Coastguard Worker
570*61046927SAndroid Build Coastguard Worker input.flags |= extra_flags;
571*61046927SAndroid Build Coastguard Worker
572*61046927SAndroid Build Coastguard Worker result =
573*61046927SAndroid Build Coastguard Worker pvr_pds_vertex_attrib_program_create_and_upload(device,
574*61046927SAndroid Build Coastguard Worker allocator,
575*61046927SAndroid Build Coastguard Worker &input,
576*61046927SAndroid Build Coastguard Worker &programs_out[i]);
577*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
578*61046927SAndroid Build Coastguard Worker for (uint32_t j = 0; j < i; j++) {
579*61046927SAndroid Build Coastguard Worker pvr_pds_vertex_attrib_program_destroy(device,
580*61046927SAndroid Build Coastguard Worker allocator,
581*61046927SAndroid Build Coastguard Worker &programs_out[j]);
582*61046927SAndroid Build Coastguard Worker }
583*61046927SAndroid Build Coastguard Worker
584*61046927SAndroid Build Coastguard Worker return result;
585*61046927SAndroid Build Coastguard Worker }
586*61046927SAndroid Build Coastguard Worker
587*61046927SAndroid Build Coastguard Worker input.flags &= ~extra_flags;
588*61046927SAndroid Build Coastguard Worker }
589*61046927SAndroid Build Coastguard Worker
590*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
591*61046927SAndroid Build Coastguard Worker }
592*61046927SAndroid Build Coastguard Worker
pvr_pds_get_max_descriptor_upload_const_map_size_in_bytes(void)593*61046927SAndroid Build Coastguard Worker size_t pvr_pds_get_max_descriptor_upload_const_map_size_in_bytes(void)
594*61046927SAndroid Build Coastguard Worker {
595*61046927SAndroid Build Coastguard Worker /* Maximum memory allocation needed for const map entries in
596*61046927SAndroid Build Coastguard Worker * pvr_pds_generate_descriptor_upload_program().
597*61046927SAndroid Build Coastguard Worker * It must be >= 688 bytes. This size is calculated as the sum of:
598*61046927SAndroid Build Coastguard Worker *
599*61046927SAndroid Build Coastguard Worker * 1. Max. number of descriptor sets (8) * (
600*61046927SAndroid Build Coastguard Worker * size of descriptor entry
601*61046927SAndroid Build Coastguard Worker * (pvr_const_map_entry_descriptor_set) +
602*61046927SAndroid Build Coastguard Worker * size of Common Store burst entry
603*61046927SAndroid Build Coastguard Worker * (pvr_const_map_entry_literal32))
604*61046927SAndroid Build Coastguard Worker *
605*61046927SAndroid Build Coastguard Worker * 2. Max. number of PDS program buffers (24) * (
606*61046927SAndroid Build Coastguard Worker * size of the largest buffer structure
607*61046927SAndroid Build Coastguard Worker * (pvr_const_map_entry_constant_buffer) +
608*61046927SAndroid Build Coastguard Worker * size of Common Store burst entry
609*61046927SAndroid Build Coastguard Worker * (pvr_const_map_entry_literal32)
610*61046927SAndroid Build Coastguard Worker *
611*61046927SAndroid Build Coastguard Worker * 3. Size of DOUTU entry (pvr_const_map_entry_doutu_address)
612*61046927SAndroid Build Coastguard Worker *
613*61046927SAndroid Build Coastguard Worker * 4. Max. number of PDS address literals (8) * (
614*61046927SAndroid Build Coastguard Worker * size of entry
615*61046927SAndroid Build Coastguard Worker * (pvr_const_map_entry_descriptor_set_addrs_table)
616*61046927SAndroid Build Coastguard Worker *
617*61046927SAndroid Build Coastguard Worker * 5. Max. number of address literals with single buffer entry to DOUTD
618*61046927SAndroid Build Coastguard Worker size of entry
619*61046927SAndroid Build Coastguard Worker (pvr_pds_const_map_entry_addr_literal_buffer) +
620*61046927SAndroid Build Coastguard Worker 8 * size of entry (pvr_pds_const_map_entry_addr_literal)
621*61046927SAndroid Build Coastguard Worker */
622*61046927SAndroid Build Coastguard Worker
623*61046927SAndroid Build Coastguard Worker /* FIXME: PVR_MAX_DESCRIPTOR_SETS is 4 and not 8. The comment above seems to
624*61046927SAndroid Build Coastguard Worker * say that it should be 8.
625*61046927SAndroid Build Coastguard Worker * Figure our a define for this or is the comment wrong?
626*61046927SAndroid Build Coastguard Worker */
627*61046927SAndroid Build Coastguard Worker return (8 * (sizeof(struct pvr_const_map_entry_descriptor_set) +
628*61046927SAndroid Build Coastguard Worker sizeof(struct pvr_const_map_entry_literal32)) +
629*61046927SAndroid Build Coastguard Worker PVR_PDS_MAX_BUFFERS *
630*61046927SAndroid Build Coastguard Worker (sizeof(struct pvr_const_map_entry_constant_buffer) +
631*61046927SAndroid Build Coastguard Worker sizeof(struct pvr_const_map_entry_literal32)) +
632*61046927SAndroid Build Coastguard Worker sizeof(struct pvr_const_map_entry_doutu_address) +
633*61046927SAndroid Build Coastguard Worker sizeof(struct pvr_pds_const_map_entry_addr_literal_buffer) +
634*61046927SAndroid Build Coastguard Worker 8 * sizeof(struct pvr_pds_const_map_entry_addr_literal));
635*61046927SAndroid Build Coastguard Worker }
636*61046927SAndroid Build Coastguard Worker
637*61046927SAndroid Build Coastguard Worker /* This is a const pointer to an array of PVR_PDS_MAX_BUFFERS pvr_pds_buffer
638*61046927SAndroid Build Coastguard Worker * structs.
639*61046927SAndroid Build Coastguard Worker */
640*61046927SAndroid Build Coastguard Worker typedef struct pvr_pds_buffer (
641*61046927SAndroid Build Coastguard Worker *const pvr_pds_descriptor_program_buffer_array_ptr)[PVR_PDS_MAX_BUFFERS];
642*61046927SAndroid Build Coastguard Worker
643*61046927SAndroid Build Coastguard Worker /**
644*61046927SAndroid Build Coastguard Worker * \brief Setup buffers for the PDS descriptor program.
645*61046927SAndroid Build Coastguard Worker *
646*61046927SAndroid Build Coastguard Worker * Sets up buffers required by the PDS gen api based on compiler info.
647*61046927SAndroid Build Coastguard Worker *
648*61046927SAndroid Build Coastguard Worker * For compile time static constants that need DMAing it uploads them and
649*61046927SAndroid Build Coastguard Worker * returns the upload in \r static_consts_pvr_bo_out .
650*61046927SAndroid Build Coastguard Worker */
pvr_pds_descriptor_program_setup_buffers(struct pvr_device * device,bool robust_buffer_access,const struct rogue_compile_time_consts_data * compile_time_consts_data,const struct rogue_ubo_data * ubo_data,pvr_pds_descriptor_program_buffer_array_ptr buffers_out_ptr,uint32_t * const buffer_count_out,struct pvr_suballoc_bo ** const static_consts_pvr_bo_out)651*61046927SAndroid Build Coastguard Worker static VkResult pvr_pds_descriptor_program_setup_buffers(
652*61046927SAndroid Build Coastguard Worker struct pvr_device *device,
653*61046927SAndroid Build Coastguard Worker bool robust_buffer_access,
654*61046927SAndroid Build Coastguard Worker const struct rogue_compile_time_consts_data *compile_time_consts_data,
655*61046927SAndroid Build Coastguard Worker const struct rogue_ubo_data *ubo_data,
656*61046927SAndroid Build Coastguard Worker pvr_pds_descriptor_program_buffer_array_ptr buffers_out_ptr,
657*61046927SAndroid Build Coastguard Worker uint32_t *const buffer_count_out,
658*61046927SAndroid Build Coastguard Worker struct pvr_suballoc_bo **const static_consts_pvr_bo_out)
659*61046927SAndroid Build Coastguard Worker {
660*61046927SAndroid Build Coastguard Worker struct pvr_pds_buffer *const buffers = *buffers_out_ptr;
661*61046927SAndroid Build Coastguard Worker uint32_t buffer_count = 0;
662*61046927SAndroid Build Coastguard Worker
663*61046927SAndroid Build Coastguard Worker for (size_t i = 0; i < ubo_data->num_ubo_entries; i++) {
664*61046927SAndroid Build Coastguard Worker struct pvr_pds_buffer *current_buffer = &buffers[buffer_count];
665*61046927SAndroid Build Coastguard Worker
666*61046927SAndroid Build Coastguard Worker /* This is fine since buffers_out_ptr is a pointer to an array. */
667*61046927SAndroid Build Coastguard Worker assert(buffer_count < ARRAY_SIZE(*buffers_out_ptr));
668*61046927SAndroid Build Coastguard Worker
669*61046927SAndroid Build Coastguard Worker current_buffer->type = PVR_BUFFER_TYPE_UBO;
670*61046927SAndroid Build Coastguard Worker current_buffer->size_in_dwords = ubo_data->size[i];
671*61046927SAndroid Build Coastguard Worker current_buffer->destination = ubo_data->dest[i];
672*61046927SAndroid Build Coastguard Worker
673*61046927SAndroid Build Coastguard Worker current_buffer->buffer_id = buffer_count;
674*61046927SAndroid Build Coastguard Worker current_buffer->desc_set = ubo_data->desc_set[i];
675*61046927SAndroid Build Coastguard Worker current_buffer->binding = ubo_data->binding[i];
676*61046927SAndroid Build Coastguard Worker /* TODO: Is this always the case?
677*61046927SAndroid Build Coastguard Worker * E.g. can multiple UBOs have the same base buffer?
678*61046927SAndroid Build Coastguard Worker */
679*61046927SAndroid Build Coastguard Worker current_buffer->source_offset = 0;
680*61046927SAndroid Build Coastguard Worker
681*61046927SAndroid Build Coastguard Worker buffer_count++;
682*61046927SAndroid Build Coastguard Worker }
683*61046927SAndroid Build Coastguard Worker
684*61046927SAndroid Build Coastguard Worker if (compile_time_consts_data->static_consts.num > 0) {
685*61046927SAndroid Build Coastguard Worker VkResult result;
686*61046927SAndroid Build Coastguard Worker
687*61046927SAndroid Build Coastguard Worker assert(compile_time_consts_data->static_consts.num <=
688*61046927SAndroid Build Coastguard Worker ARRAY_SIZE(compile_time_consts_data->static_consts.value));
689*61046927SAndroid Build Coastguard Worker
690*61046927SAndroid Build Coastguard Worker /* This is fine since buffers_out_ptr is a pointer to an array. */
691*61046927SAndroid Build Coastguard Worker assert(buffer_count < ARRAY_SIZE(*buffers_out_ptr));
692*61046927SAndroid Build Coastguard Worker
693*61046927SAndroid Build Coastguard Worker /* TODO: Is it possible to have multiple static consts buffer where the
694*61046927SAndroid Build Coastguard Worker * destination is not adjoining? If so we need to handle that.
695*61046927SAndroid Build Coastguard Worker * Currently we're only setting up a single buffer.
696*61046927SAndroid Build Coastguard Worker */
697*61046927SAndroid Build Coastguard Worker buffers[buffer_count++] = (struct pvr_pds_buffer){
698*61046927SAndroid Build Coastguard Worker .type = PVR_BUFFER_TYPE_COMPILE_TIME,
699*61046927SAndroid Build Coastguard Worker .size_in_dwords = compile_time_consts_data->static_consts.num,
700*61046927SAndroid Build Coastguard Worker .destination = compile_time_consts_data->static_consts.dest,
701*61046927SAndroid Build Coastguard Worker };
702*61046927SAndroid Build Coastguard Worker
703*61046927SAndroid Build Coastguard Worker result = pvr_gpu_upload(device,
704*61046927SAndroid Build Coastguard Worker device->heaps.general_heap,
705*61046927SAndroid Build Coastguard Worker compile_time_consts_data->static_consts.value,
706*61046927SAndroid Build Coastguard Worker compile_time_consts_data->static_consts.num *
707*61046927SAndroid Build Coastguard Worker ROGUE_REG_SIZE_BYTES,
708*61046927SAndroid Build Coastguard Worker ROGUE_REG_SIZE_BYTES,
709*61046927SAndroid Build Coastguard Worker static_consts_pvr_bo_out);
710*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
711*61046927SAndroid Build Coastguard Worker return result;
712*61046927SAndroid Build Coastguard Worker } else {
713*61046927SAndroid Build Coastguard Worker *static_consts_pvr_bo_out = NULL;
714*61046927SAndroid Build Coastguard Worker }
715*61046927SAndroid Build Coastguard Worker
716*61046927SAndroid Build Coastguard Worker *buffer_count_out = buffer_count;
717*61046927SAndroid Build Coastguard Worker
718*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
719*61046927SAndroid Build Coastguard Worker }
720*61046927SAndroid Build Coastguard Worker
pvr_pds_descriptor_program_create_and_upload(struct pvr_device * const device,const VkAllocationCallbacks * const allocator,const struct rogue_compile_time_consts_data * const compile_time_consts_data,const struct rogue_ubo_data * const ubo_data,const struct pvr_explicit_constant_usage * const explicit_const_usage,const struct pvr_pipeline_layout * const layout,enum pvr_stage_allocation stage,const struct pvr_sh_reg_layout * sh_reg_layout,struct pvr_stage_allocation_descriptor_state * const descriptor_state)721*61046927SAndroid Build Coastguard Worker static VkResult pvr_pds_descriptor_program_create_and_upload(
722*61046927SAndroid Build Coastguard Worker struct pvr_device *const device,
723*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *const allocator,
724*61046927SAndroid Build Coastguard Worker const struct rogue_compile_time_consts_data *const compile_time_consts_data,
725*61046927SAndroid Build Coastguard Worker const struct rogue_ubo_data *const ubo_data,
726*61046927SAndroid Build Coastguard Worker const struct pvr_explicit_constant_usage *const explicit_const_usage,
727*61046927SAndroid Build Coastguard Worker const struct pvr_pipeline_layout *const layout,
728*61046927SAndroid Build Coastguard Worker enum pvr_stage_allocation stage,
729*61046927SAndroid Build Coastguard Worker const struct pvr_sh_reg_layout *sh_reg_layout,
730*61046927SAndroid Build Coastguard Worker struct pvr_stage_allocation_descriptor_state *const descriptor_state)
731*61046927SAndroid Build Coastguard Worker {
732*61046927SAndroid Build Coastguard Worker const size_t const_entries_size_in_bytes =
733*61046927SAndroid Build Coastguard Worker pvr_pds_get_max_descriptor_upload_const_map_size_in_bytes();
734*61046927SAndroid Build Coastguard Worker struct pvr_pds_info *const pds_info = &descriptor_state->pds_info;
735*61046927SAndroid Build Coastguard Worker struct pvr_pds_descriptor_program_input program = { 0 };
736*61046927SAndroid Build Coastguard Worker struct pvr_const_map_entry *new_entries;
737*61046927SAndroid Build Coastguard Worker ASSERTED uint32_t code_size_in_dwords;
738*61046927SAndroid Build Coastguard Worker uint32_t staging_buffer_size;
739*61046927SAndroid Build Coastguard Worker uint32_t *staging_buffer;
740*61046927SAndroid Build Coastguard Worker VkResult result;
741*61046927SAndroid Build Coastguard Worker
742*61046927SAndroid Build Coastguard Worker const bool old_path = pvr_has_hard_coded_shaders(&device->pdevice->dev_info);
743*61046927SAndroid Build Coastguard Worker
744*61046927SAndroid Build Coastguard Worker assert(stage != PVR_STAGE_ALLOCATION_COUNT);
745*61046927SAndroid Build Coastguard Worker
746*61046927SAndroid Build Coastguard Worker *pds_info = (struct pvr_pds_info){ 0 };
747*61046927SAndroid Build Coastguard Worker
748*61046927SAndroid Build Coastguard Worker if (old_path) {
749*61046927SAndroid Build Coastguard Worker result = pvr_pds_descriptor_program_setup_buffers(
750*61046927SAndroid Build Coastguard Worker device,
751*61046927SAndroid Build Coastguard Worker device->vk.enabled_features.robustBufferAccess,
752*61046927SAndroid Build Coastguard Worker compile_time_consts_data,
753*61046927SAndroid Build Coastguard Worker ubo_data,
754*61046927SAndroid Build Coastguard Worker &program.buffers,
755*61046927SAndroid Build Coastguard Worker &program.buffer_count,
756*61046927SAndroid Build Coastguard Worker &descriptor_state->static_consts);
757*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
758*61046927SAndroid Build Coastguard Worker return result;
759*61046927SAndroid Build Coastguard Worker
760*61046927SAndroid Build Coastguard Worker if (layout->per_stage_reg_info[stage].primary_dynamic_size_in_dwords)
761*61046927SAndroid Build Coastguard Worker assert(!"Unimplemented");
762*61046927SAndroid Build Coastguard Worker
763*61046927SAndroid Build Coastguard Worker for (uint32_t set_num = 0; set_num < layout->set_count; set_num++) {
764*61046927SAndroid Build Coastguard Worker const struct pvr_descriptor_set_layout_mem_layout *const reg_layout =
765*61046927SAndroid Build Coastguard Worker &layout->register_layout_in_dwords_per_stage[stage][set_num];
766*61046927SAndroid Build Coastguard Worker const uint32_t start_offset = explicit_const_usage->start_offset;
767*61046927SAndroid Build Coastguard Worker
768*61046927SAndroid Build Coastguard Worker /* TODO: Use compiler usage info to optimize this? */
769*61046927SAndroid Build Coastguard Worker
770*61046927SAndroid Build Coastguard Worker /* Only dma primaries if they are actually required. */
771*61046927SAndroid Build Coastguard Worker if (reg_layout->primary_size) {
772*61046927SAndroid Build Coastguard Worker program.descriptor_sets[program.descriptor_set_count++] =
773*61046927SAndroid Build Coastguard Worker (struct pvr_pds_descriptor_set){
774*61046927SAndroid Build Coastguard Worker .descriptor_set = set_num,
775*61046927SAndroid Build Coastguard Worker .size_in_dwords = reg_layout->primary_size,
776*61046927SAndroid Build Coastguard Worker .destination = reg_layout->primary_offset + start_offset,
777*61046927SAndroid Build Coastguard Worker .primary = true,
778*61046927SAndroid Build Coastguard Worker };
779*61046927SAndroid Build Coastguard Worker }
780*61046927SAndroid Build Coastguard Worker
781*61046927SAndroid Build Coastguard Worker /* Only dma secondaries if they are actually required. */
782*61046927SAndroid Build Coastguard Worker if (!reg_layout->secondary_size)
783*61046927SAndroid Build Coastguard Worker continue;
784*61046927SAndroid Build Coastguard Worker
785*61046927SAndroid Build Coastguard Worker program.descriptor_sets[program.descriptor_set_count++] =
786*61046927SAndroid Build Coastguard Worker (struct pvr_pds_descriptor_set){
787*61046927SAndroid Build Coastguard Worker .descriptor_set = set_num,
788*61046927SAndroid Build Coastguard Worker .size_in_dwords = reg_layout->secondary_size,
789*61046927SAndroid Build Coastguard Worker .destination = reg_layout->secondary_offset + start_offset,
790*61046927SAndroid Build Coastguard Worker };
791*61046927SAndroid Build Coastguard Worker }
792*61046927SAndroid Build Coastguard Worker } else {
793*61046927SAndroid Build Coastguard Worker uint32_t addr_literals = 0;
794*61046927SAndroid Build Coastguard Worker
795*61046927SAndroid Build Coastguard Worker if (sh_reg_layout->descriptor_set_addrs_table.present) {
796*61046927SAndroid Build Coastguard Worker program.addr_literals[addr_literals] = (struct pvr_pds_addr_literal){
797*61046927SAndroid Build Coastguard Worker .type = PVR_PDS_ADDR_LITERAL_DESC_SET_ADDRS_TABLE,
798*61046927SAndroid Build Coastguard Worker .destination = sh_reg_layout->descriptor_set_addrs_table.offset,
799*61046927SAndroid Build Coastguard Worker };
800*61046927SAndroid Build Coastguard Worker addr_literals++;
801*61046927SAndroid Build Coastguard Worker }
802*61046927SAndroid Build Coastguard Worker
803*61046927SAndroid Build Coastguard Worker if (sh_reg_layout->push_consts.present) {
804*61046927SAndroid Build Coastguard Worker program.addr_literals[addr_literals] = (struct pvr_pds_addr_literal){
805*61046927SAndroid Build Coastguard Worker .type = PVR_PDS_ADDR_LITERAL_PUSH_CONSTS,
806*61046927SAndroid Build Coastguard Worker .destination = sh_reg_layout->push_consts.offset,
807*61046927SAndroid Build Coastguard Worker };
808*61046927SAndroid Build Coastguard Worker addr_literals++;
809*61046927SAndroid Build Coastguard Worker }
810*61046927SAndroid Build Coastguard Worker
811*61046927SAndroid Build Coastguard Worker if (sh_reg_layout->blend_consts.present) {
812*61046927SAndroid Build Coastguard Worker program.addr_literals[addr_literals] = (struct pvr_pds_addr_literal){
813*61046927SAndroid Build Coastguard Worker .type = PVR_PDS_ADDR_LITERAL_BLEND_CONSTANTS,
814*61046927SAndroid Build Coastguard Worker .destination = sh_reg_layout->blend_consts.offset,
815*61046927SAndroid Build Coastguard Worker };
816*61046927SAndroid Build Coastguard Worker addr_literals++;
817*61046927SAndroid Build Coastguard Worker }
818*61046927SAndroid Build Coastguard Worker
819*61046927SAndroid Build Coastguard Worker program.addr_literal_count = addr_literals;
820*61046927SAndroid Build Coastguard Worker }
821*61046927SAndroid Build Coastguard Worker
822*61046927SAndroid Build Coastguard Worker pds_info->entries = vk_alloc2(&device->vk.alloc,
823*61046927SAndroid Build Coastguard Worker allocator,
824*61046927SAndroid Build Coastguard Worker const_entries_size_in_bytes,
825*61046927SAndroid Build Coastguard Worker 8,
826*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
827*61046927SAndroid Build Coastguard Worker if (!pds_info->entries) {
828*61046927SAndroid Build Coastguard Worker result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
829*61046927SAndroid Build Coastguard Worker goto err_free_static_consts;
830*61046927SAndroid Build Coastguard Worker }
831*61046927SAndroid Build Coastguard Worker
832*61046927SAndroid Build Coastguard Worker pds_info->entries_size_in_bytes = const_entries_size_in_bytes;
833*61046927SAndroid Build Coastguard Worker
834*61046927SAndroid Build Coastguard Worker pvr_pds_generate_descriptor_upload_program(&program, NULL, pds_info);
835*61046927SAndroid Build Coastguard Worker
836*61046927SAndroid Build Coastguard Worker code_size_in_dwords = pds_info->code_size_in_dwords;
837*61046927SAndroid Build Coastguard Worker staging_buffer_size = PVR_DW_TO_BYTES(pds_info->code_size_in_dwords);
838*61046927SAndroid Build Coastguard Worker
839*61046927SAndroid Build Coastguard Worker if (!staging_buffer_size) {
840*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, pds_info->entries);
841*61046927SAndroid Build Coastguard Worker
842*61046927SAndroid Build Coastguard Worker *descriptor_state = (struct pvr_stage_allocation_descriptor_state){ 0 };
843*61046927SAndroid Build Coastguard Worker
844*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
845*61046927SAndroid Build Coastguard Worker }
846*61046927SAndroid Build Coastguard Worker
847*61046927SAndroid Build Coastguard Worker staging_buffer = vk_alloc2(&device->vk.alloc,
848*61046927SAndroid Build Coastguard Worker allocator,
849*61046927SAndroid Build Coastguard Worker staging_buffer_size,
850*61046927SAndroid Build Coastguard Worker 8,
851*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
852*61046927SAndroid Build Coastguard Worker if (!staging_buffer) {
853*61046927SAndroid Build Coastguard Worker result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
854*61046927SAndroid Build Coastguard Worker goto err_free_entries;
855*61046927SAndroid Build Coastguard Worker }
856*61046927SAndroid Build Coastguard Worker
857*61046927SAndroid Build Coastguard Worker pvr_pds_generate_descriptor_upload_program(&program,
858*61046927SAndroid Build Coastguard Worker staging_buffer,
859*61046927SAndroid Build Coastguard Worker pds_info);
860*61046927SAndroid Build Coastguard Worker
861*61046927SAndroid Build Coastguard Worker assert(pds_info->code_size_in_dwords <= code_size_in_dwords);
862*61046927SAndroid Build Coastguard Worker
863*61046927SAndroid Build Coastguard Worker /* FIXME: use vk_realloc2() ? */
864*61046927SAndroid Build Coastguard Worker new_entries = vk_realloc((!allocator) ? &device->vk.alloc : allocator,
865*61046927SAndroid Build Coastguard Worker pds_info->entries,
866*61046927SAndroid Build Coastguard Worker pds_info->entries_written_size_in_bytes,
867*61046927SAndroid Build Coastguard Worker 8,
868*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
869*61046927SAndroid Build Coastguard Worker if (!new_entries) {
870*61046927SAndroid Build Coastguard Worker result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
871*61046927SAndroid Build Coastguard Worker goto err_free_staging_buffer;
872*61046927SAndroid Build Coastguard Worker }
873*61046927SAndroid Build Coastguard Worker
874*61046927SAndroid Build Coastguard Worker pds_info->entries = new_entries;
875*61046927SAndroid Build Coastguard Worker pds_info->entries_size_in_bytes = pds_info->entries_written_size_in_bytes;
876*61046927SAndroid Build Coastguard Worker
877*61046927SAndroid Build Coastguard Worker /* FIXME: Figure out the define for alignment of 16. */
878*61046927SAndroid Build Coastguard Worker result = pvr_gpu_upload_pds(device,
879*61046927SAndroid Build Coastguard Worker NULL,
880*61046927SAndroid Build Coastguard Worker 0,
881*61046927SAndroid Build Coastguard Worker 0,
882*61046927SAndroid Build Coastguard Worker staging_buffer,
883*61046927SAndroid Build Coastguard Worker pds_info->code_size_in_dwords,
884*61046927SAndroid Build Coastguard Worker 16,
885*61046927SAndroid Build Coastguard Worker 16,
886*61046927SAndroid Build Coastguard Worker &descriptor_state->pds_code);
887*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
888*61046927SAndroid Build Coastguard Worker goto err_free_staging_buffer;
889*61046927SAndroid Build Coastguard Worker
890*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, staging_buffer);
891*61046927SAndroid Build Coastguard Worker
892*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
893*61046927SAndroid Build Coastguard Worker
894*61046927SAndroid Build Coastguard Worker err_free_staging_buffer:
895*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, staging_buffer);
896*61046927SAndroid Build Coastguard Worker
897*61046927SAndroid Build Coastguard Worker err_free_entries:
898*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, pds_info->entries);
899*61046927SAndroid Build Coastguard Worker
900*61046927SAndroid Build Coastguard Worker err_free_static_consts:
901*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(descriptor_state->static_consts);
902*61046927SAndroid Build Coastguard Worker
903*61046927SAndroid Build Coastguard Worker return result;
904*61046927SAndroid Build Coastguard Worker }
905*61046927SAndroid Build Coastguard Worker
pvr_pds_descriptor_program_destroy(struct pvr_device * const device,const struct VkAllocationCallbacks * const allocator,struct pvr_stage_allocation_descriptor_state * const descriptor_state)906*61046927SAndroid Build Coastguard Worker static void pvr_pds_descriptor_program_destroy(
907*61046927SAndroid Build Coastguard Worker struct pvr_device *const device,
908*61046927SAndroid Build Coastguard Worker const struct VkAllocationCallbacks *const allocator,
909*61046927SAndroid Build Coastguard Worker struct pvr_stage_allocation_descriptor_state *const descriptor_state)
910*61046927SAndroid Build Coastguard Worker {
911*61046927SAndroid Build Coastguard Worker if (!descriptor_state)
912*61046927SAndroid Build Coastguard Worker return;
913*61046927SAndroid Build Coastguard Worker
914*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(descriptor_state->pds_code.pvr_bo);
915*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, descriptor_state->pds_info.entries);
916*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(descriptor_state->static_consts);
917*61046927SAndroid Build Coastguard Worker }
918*61046927SAndroid Build Coastguard Worker
pvr_pds_compute_program_setup(const struct pvr_device_info * dev_info,const uint32_t local_input_regs[static const PVR_WORKGROUP_DIMENSIONS],const uint32_t work_group_input_regs[static const PVR_WORKGROUP_DIMENSIONS],uint32_t barrier_coefficient,bool add_base_workgroup,uint32_t usc_temps,pvr_dev_addr_t usc_shader_dev_addr,struct pvr_pds_compute_shader_program * const program)919*61046927SAndroid Build Coastguard Worker static void pvr_pds_compute_program_setup(
920*61046927SAndroid Build Coastguard Worker const struct pvr_device_info *dev_info,
921*61046927SAndroid Build Coastguard Worker const uint32_t local_input_regs[static const PVR_WORKGROUP_DIMENSIONS],
922*61046927SAndroid Build Coastguard Worker const uint32_t work_group_input_regs[static const PVR_WORKGROUP_DIMENSIONS],
923*61046927SAndroid Build Coastguard Worker uint32_t barrier_coefficient,
924*61046927SAndroid Build Coastguard Worker bool add_base_workgroup,
925*61046927SAndroid Build Coastguard Worker uint32_t usc_temps,
926*61046927SAndroid Build Coastguard Worker pvr_dev_addr_t usc_shader_dev_addr,
927*61046927SAndroid Build Coastguard Worker struct pvr_pds_compute_shader_program *const program)
928*61046927SAndroid Build Coastguard Worker {
929*61046927SAndroid Build Coastguard Worker pvr_pds_compute_shader_program_init(program);
930*61046927SAndroid Build Coastguard Worker program->local_input_regs[0] = local_input_regs[0];
931*61046927SAndroid Build Coastguard Worker program->local_input_regs[1] = local_input_regs[1];
932*61046927SAndroid Build Coastguard Worker program->local_input_regs[2] = local_input_regs[2];
933*61046927SAndroid Build Coastguard Worker program->work_group_input_regs[0] = work_group_input_regs[0];
934*61046927SAndroid Build Coastguard Worker program->work_group_input_regs[1] = work_group_input_regs[1];
935*61046927SAndroid Build Coastguard Worker program->work_group_input_regs[2] = work_group_input_regs[2];
936*61046927SAndroid Build Coastguard Worker program->barrier_coefficient = barrier_coefficient;
937*61046927SAndroid Build Coastguard Worker program->add_base_workgroup = add_base_workgroup;
938*61046927SAndroid Build Coastguard Worker program->flattened_work_groups = true;
939*61046927SAndroid Build Coastguard Worker program->kick_usc = true;
940*61046927SAndroid Build Coastguard Worker
941*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(ARRAY_SIZE(program->local_input_regs) ==
942*61046927SAndroid Build Coastguard Worker PVR_WORKGROUP_DIMENSIONS);
943*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(ARRAY_SIZE(program->work_group_input_regs) ==
944*61046927SAndroid Build Coastguard Worker PVR_WORKGROUP_DIMENSIONS);
945*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(ARRAY_SIZE(program->global_input_regs) ==
946*61046927SAndroid Build Coastguard Worker PVR_WORKGROUP_DIMENSIONS);
947*61046927SAndroid Build Coastguard Worker
948*61046927SAndroid Build Coastguard Worker pvr_pds_setup_doutu(&program->usc_task_control,
949*61046927SAndroid Build Coastguard Worker usc_shader_dev_addr.addr,
950*61046927SAndroid Build Coastguard Worker usc_temps,
951*61046927SAndroid Build Coastguard Worker PVRX(PDSINST_DOUTU_SAMPLE_RATE_INSTANCE),
952*61046927SAndroid Build Coastguard Worker false);
953*61046927SAndroid Build Coastguard Worker
954*61046927SAndroid Build Coastguard Worker pvr_pds_compute_shader(program, NULL, PDS_GENERATE_SIZES, dev_info);
955*61046927SAndroid Build Coastguard Worker }
956*61046927SAndroid Build Coastguard Worker
957*61046927SAndroid Build Coastguard Worker /* FIXME: See if pvr_device_init_compute_pds_program() and this could be merged.
958*61046927SAndroid Build Coastguard Worker */
pvr_pds_compute_program_create_and_upload(struct pvr_device * const device,const VkAllocationCallbacks * const allocator,const uint32_t local_input_regs[static const PVR_WORKGROUP_DIMENSIONS],const uint32_t work_group_input_regs[static const PVR_WORKGROUP_DIMENSIONS],uint32_t barrier_coefficient,uint32_t usc_temps,pvr_dev_addr_t usc_shader_dev_addr,struct pvr_pds_upload * const pds_upload_out,struct pvr_pds_info * const pds_info_out)959*61046927SAndroid Build Coastguard Worker static VkResult pvr_pds_compute_program_create_and_upload(
960*61046927SAndroid Build Coastguard Worker struct pvr_device *const device,
961*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *const allocator,
962*61046927SAndroid Build Coastguard Worker const uint32_t local_input_regs[static const PVR_WORKGROUP_DIMENSIONS],
963*61046927SAndroid Build Coastguard Worker const uint32_t work_group_input_regs[static const PVR_WORKGROUP_DIMENSIONS],
964*61046927SAndroid Build Coastguard Worker uint32_t barrier_coefficient,
965*61046927SAndroid Build Coastguard Worker uint32_t usc_temps,
966*61046927SAndroid Build Coastguard Worker pvr_dev_addr_t usc_shader_dev_addr,
967*61046927SAndroid Build Coastguard Worker struct pvr_pds_upload *const pds_upload_out,
968*61046927SAndroid Build Coastguard Worker struct pvr_pds_info *const pds_info_out)
969*61046927SAndroid Build Coastguard Worker {
970*61046927SAndroid Build Coastguard Worker struct pvr_device_info *dev_info = &device->pdevice->dev_info;
971*61046927SAndroid Build Coastguard Worker struct pvr_pds_compute_shader_program program;
972*61046927SAndroid Build Coastguard Worker uint32_t staging_buffer_size;
973*61046927SAndroid Build Coastguard Worker uint32_t *staging_buffer;
974*61046927SAndroid Build Coastguard Worker VkResult result;
975*61046927SAndroid Build Coastguard Worker
976*61046927SAndroid Build Coastguard Worker pvr_pds_compute_program_setup(dev_info,
977*61046927SAndroid Build Coastguard Worker local_input_regs,
978*61046927SAndroid Build Coastguard Worker work_group_input_regs,
979*61046927SAndroid Build Coastguard Worker barrier_coefficient,
980*61046927SAndroid Build Coastguard Worker false,
981*61046927SAndroid Build Coastguard Worker usc_temps,
982*61046927SAndroid Build Coastguard Worker usc_shader_dev_addr,
983*61046927SAndroid Build Coastguard Worker &program);
984*61046927SAndroid Build Coastguard Worker
985*61046927SAndroid Build Coastguard Worker /* FIXME: According to pvr_device_init_compute_pds_program() the code size
986*61046927SAndroid Build Coastguard Worker * is in bytes. Investigate this.
987*61046927SAndroid Build Coastguard Worker */
988*61046927SAndroid Build Coastguard Worker staging_buffer_size = PVR_DW_TO_BYTES(program.code_size + program.data_size);
989*61046927SAndroid Build Coastguard Worker
990*61046927SAndroid Build Coastguard Worker staging_buffer = vk_alloc2(&device->vk.alloc,
991*61046927SAndroid Build Coastguard Worker allocator,
992*61046927SAndroid Build Coastguard Worker staging_buffer_size,
993*61046927SAndroid Build Coastguard Worker 8,
994*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
995*61046927SAndroid Build Coastguard Worker if (!staging_buffer)
996*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
997*61046927SAndroid Build Coastguard Worker
998*61046927SAndroid Build Coastguard Worker /* FIXME: pvr_pds_compute_shader doesn't implement
999*61046927SAndroid Build Coastguard Worker * PDS_GENERATE_CODEDATA_SEGMENTS.
1000*61046927SAndroid Build Coastguard Worker */
1001*61046927SAndroid Build Coastguard Worker pvr_pds_compute_shader(&program,
1002*61046927SAndroid Build Coastguard Worker &staging_buffer[0],
1003*61046927SAndroid Build Coastguard Worker PDS_GENERATE_CODE_SEGMENT,
1004*61046927SAndroid Build Coastguard Worker dev_info);
1005*61046927SAndroid Build Coastguard Worker
1006*61046927SAndroid Build Coastguard Worker pvr_pds_compute_shader(&program,
1007*61046927SAndroid Build Coastguard Worker &staging_buffer[program.code_size],
1008*61046927SAndroid Build Coastguard Worker PDS_GENERATE_DATA_SEGMENT,
1009*61046927SAndroid Build Coastguard Worker dev_info);
1010*61046927SAndroid Build Coastguard Worker
1011*61046927SAndroid Build Coastguard Worker /* FIXME: Figure out the define for alignment of 16. */
1012*61046927SAndroid Build Coastguard Worker result = pvr_gpu_upload_pds(device,
1013*61046927SAndroid Build Coastguard Worker &staging_buffer[program.code_size],
1014*61046927SAndroid Build Coastguard Worker program.data_size,
1015*61046927SAndroid Build Coastguard Worker 16,
1016*61046927SAndroid Build Coastguard Worker &staging_buffer[0],
1017*61046927SAndroid Build Coastguard Worker program.code_size,
1018*61046927SAndroid Build Coastguard Worker 16,
1019*61046927SAndroid Build Coastguard Worker 16,
1020*61046927SAndroid Build Coastguard Worker pds_upload_out);
1021*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
1022*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, staging_buffer);
1023*61046927SAndroid Build Coastguard Worker return result;
1024*61046927SAndroid Build Coastguard Worker }
1025*61046927SAndroid Build Coastguard Worker
1026*61046927SAndroid Build Coastguard Worker *pds_info_out = (struct pvr_pds_info){
1027*61046927SAndroid Build Coastguard Worker .temps_required = program.highest_temp,
1028*61046927SAndroid Build Coastguard Worker .code_size_in_dwords = program.code_size,
1029*61046927SAndroid Build Coastguard Worker .data_size_in_dwords = program.data_size,
1030*61046927SAndroid Build Coastguard Worker };
1031*61046927SAndroid Build Coastguard Worker
1032*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, staging_buffer);
1033*61046927SAndroid Build Coastguard Worker
1034*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1035*61046927SAndroid Build Coastguard Worker };
1036*61046927SAndroid Build Coastguard Worker
pvr_pds_compute_program_destroy(struct pvr_device * const device,const struct VkAllocationCallbacks * const allocator,struct pvr_pds_upload * const pds_program,struct pvr_pds_info * const pds_info)1037*61046927SAndroid Build Coastguard Worker static void pvr_pds_compute_program_destroy(
1038*61046927SAndroid Build Coastguard Worker struct pvr_device *const device,
1039*61046927SAndroid Build Coastguard Worker const struct VkAllocationCallbacks *const allocator,
1040*61046927SAndroid Build Coastguard Worker struct pvr_pds_upload *const pds_program,
1041*61046927SAndroid Build Coastguard Worker struct pvr_pds_info *const pds_info)
1042*61046927SAndroid Build Coastguard Worker {
1043*61046927SAndroid Build Coastguard Worker /* We don't allocate an entries buffer so we don't need to free it */
1044*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(pds_program->pvr_bo);
1045*61046927SAndroid Build Coastguard Worker }
1046*61046927SAndroid Build Coastguard Worker
1047*61046927SAndroid Build Coastguard Worker /* This only uploads the code segment. The data segment will need to be patched
1048*61046927SAndroid Build Coastguard Worker * with the base workgroup before uploading.
1049*61046927SAndroid Build Coastguard Worker */
pvr_pds_compute_base_workgroup_variant_program_init(struct pvr_device * const device,const VkAllocationCallbacks * const allocator,const uint32_t local_input_regs[static const PVR_WORKGROUP_DIMENSIONS],const uint32_t work_group_input_regs[static const PVR_WORKGROUP_DIMENSIONS],uint32_t barrier_coefficient,uint32_t usc_temps,pvr_dev_addr_t usc_shader_dev_addr,struct pvr_pds_base_workgroup_program * program_out)1050*61046927SAndroid Build Coastguard Worker static VkResult pvr_pds_compute_base_workgroup_variant_program_init(
1051*61046927SAndroid Build Coastguard Worker struct pvr_device *const device,
1052*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *const allocator,
1053*61046927SAndroid Build Coastguard Worker const uint32_t local_input_regs[static const PVR_WORKGROUP_DIMENSIONS],
1054*61046927SAndroid Build Coastguard Worker const uint32_t work_group_input_regs[static const PVR_WORKGROUP_DIMENSIONS],
1055*61046927SAndroid Build Coastguard Worker uint32_t barrier_coefficient,
1056*61046927SAndroid Build Coastguard Worker uint32_t usc_temps,
1057*61046927SAndroid Build Coastguard Worker pvr_dev_addr_t usc_shader_dev_addr,
1058*61046927SAndroid Build Coastguard Worker struct pvr_pds_base_workgroup_program *program_out)
1059*61046927SAndroid Build Coastguard Worker {
1060*61046927SAndroid Build Coastguard Worker struct pvr_device_info *dev_info = &device->pdevice->dev_info;
1061*61046927SAndroid Build Coastguard Worker struct pvr_pds_compute_shader_program program;
1062*61046927SAndroid Build Coastguard Worker uint32_t buffer_size;
1063*61046927SAndroid Build Coastguard Worker uint32_t *buffer;
1064*61046927SAndroid Build Coastguard Worker VkResult result;
1065*61046927SAndroid Build Coastguard Worker
1066*61046927SAndroid Build Coastguard Worker pvr_pds_compute_program_setup(dev_info,
1067*61046927SAndroid Build Coastguard Worker local_input_regs,
1068*61046927SAndroid Build Coastguard Worker work_group_input_regs,
1069*61046927SAndroid Build Coastguard Worker barrier_coefficient,
1070*61046927SAndroid Build Coastguard Worker true,
1071*61046927SAndroid Build Coastguard Worker usc_temps,
1072*61046927SAndroid Build Coastguard Worker usc_shader_dev_addr,
1073*61046927SAndroid Build Coastguard Worker &program);
1074*61046927SAndroid Build Coastguard Worker
1075*61046927SAndroid Build Coastguard Worker /* FIXME: According to pvr_device_init_compute_pds_program() the code size
1076*61046927SAndroid Build Coastguard Worker * is in bytes. Investigate this.
1077*61046927SAndroid Build Coastguard Worker */
1078*61046927SAndroid Build Coastguard Worker buffer_size = PVR_DW_TO_BYTES(MAX2(program.code_size, program.data_size));
1079*61046927SAndroid Build Coastguard Worker
1080*61046927SAndroid Build Coastguard Worker buffer = vk_alloc2(&device->vk.alloc,
1081*61046927SAndroid Build Coastguard Worker allocator,
1082*61046927SAndroid Build Coastguard Worker buffer_size,
1083*61046927SAndroid Build Coastguard Worker 8,
1084*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1085*61046927SAndroid Build Coastguard Worker if (!buffer)
1086*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1087*61046927SAndroid Build Coastguard Worker
1088*61046927SAndroid Build Coastguard Worker pvr_pds_compute_shader(&program,
1089*61046927SAndroid Build Coastguard Worker &buffer[0],
1090*61046927SAndroid Build Coastguard Worker PDS_GENERATE_CODE_SEGMENT,
1091*61046927SAndroid Build Coastguard Worker dev_info);
1092*61046927SAndroid Build Coastguard Worker
1093*61046927SAndroid Build Coastguard Worker /* FIXME: Figure out the define for alignment of 16. */
1094*61046927SAndroid Build Coastguard Worker result = pvr_gpu_upload_pds(device,
1095*61046927SAndroid Build Coastguard Worker NULL,
1096*61046927SAndroid Build Coastguard Worker 0,
1097*61046927SAndroid Build Coastguard Worker 0,
1098*61046927SAndroid Build Coastguard Worker buffer,
1099*61046927SAndroid Build Coastguard Worker program.code_size,
1100*61046927SAndroid Build Coastguard Worker 16,
1101*61046927SAndroid Build Coastguard Worker 16,
1102*61046927SAndroid Build Coastguard Worker &program_out->code_upload);
1103*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
1104*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, buffer);
1105*61046927SAndroid Build Coastguard Worker return result;
1106*61046927SAndroid Build Coastguard Worker }
1107*61046927SAndroid Build Coastguard Worker
1108*61046927SAndroid Build Coastguard Worker pvr_pds_compute_shader(&program, buffer, PDS_GENERATE_DATA_SEGMENT, dev_info);
1109*61046927SAndroid Build Coastguard Worker
1110*61046927SAndroid Build Coastguard Worker program_out->data_section = buffer;
1111*61046927SAndroid Build Coastguard Worker
1112*61046927SAndroid Build Coastguard Worker /* We'll need to patch the base workgroup in the PDS data section before
1113*61046927SAndroid Build Coastguard Worker * dispatch so we save the offsets at which to patch. We only need to save
1114*61046927SAndroid Build Coastguard Worker * the offset for the first workgroup id since the workgroup ids are stored
1115*61046927SAndroid Build Coastguard Worker * contiguously in the data segment.
1116*61046927SAndroid Build Coastguard Worker */
1117*61046927SAndroid Build Coastguard Worker program_out->base_workgroup_data_patching_offset =
1118*61046927SAndroid Build Coastguard Worker program.base_workgroup_constant_offset_in_dwords[0];
1119*61046927SAndroid Build Coastguard Worker
1120*61046927SAndroid Build Coastguard Worker program_out->info = (struct pvr_pds_info){
1121*61046927SAndroid Build Coastguard Worker .temps_required = program.highest_temp,
1122*61046927SAndroid Build Coastguard Worker .code_size_in_dwords = program.code_size,
1123*61046927SAndroid Build Coastguard Worker .data_size_in_dwords = program.data_size,
1124*61046927SAndroid Build Coastguard Worker };
1125*61046927SAndroid Build Coastguard Worker
1126*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1127*61046927SAndroid Build Coastguard Worker }
1128*61046927SAndroid Build Coastguard Worker
pvr_pds_compute_base_workgroup_variant_program_finish(struct pvr_device * device,const VkAllocationCallbacks * const allocator,struct pvr_pds_base_workgroup_program * const state)1129*61046927SAndroid Build Coastguard Worker static void pvr_pds_compute_base_workgroup_variant_program_finish(
1130*61046927SAndroid Build Coastguard Worker struct pvr_device *device,
1131*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *const allocator,
1132*61046927SAndroid Build Coastguard Worker struct pvr_pds_base_workgroup_program *const state)
1133*61046927SAndroid Build Coastguard Worker {
1134*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(state->code_upload.pvr_bo);
1135*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, state->data_section);
1136*61046927SAndroid Build Coastguard Worker }
1137*61046927SAndroid Build Coastguard Worker
1138*61046927SAndroid Build Coastguard Worker /******************************************************************************
1139*61046927SAndroid Build Coastguard Worker Generic pipeline functions
1140*61046927SAndroid Build Coastguard Worker ******************************************************************************/
1141*61046927SAndroid Build Coastguard Worker
pvr_pipeline_init(struct pvr_device * device,enum pvr_pipeline_type type,struct pvr_pipeline * const pipeline)1142*61046927SAndroid Build Coastguard Worker static void pvr_pipeline_init(struct pvr_device *device,
1143*61046927SAndroid Build Coastguard Worker enum pvr_pipeline_type type,
1144*61046927SAndroid Build Coastguard Worker struct pvr_pipeline *const pipeline)
1145*61046927SAndroid Build Coastguard Worker {
1146*61046927SAndroid Build Coastguard Worker assert(!pipeline->layout);
1147*61046927SAndroid Build Coastguard Worker
1148*61046927SAndroid Build Coastguard Worker vk_object_base_init(&device->vk, &pipeline->base, VK_OBJECT_TYPE_PIPELINE);
1149*61046927SAndroid Build Coastguard Worker
1150*61046927SAndroid Build Coastguard Worker pipeline->type = type;
1151*61046927SAndroid Build Coastguard Worker }
1152*61046927SAndroid Build Coastguard Worker
pvr_pipeline_finish(struct pvr_pipeline * pipeline)1153*61046927SAndroid Build Coastguard Worker static void pvr_pipeline_finish(struct pvr_pipeline *pipeline)
1154*61046927SAndroid Build Coastguard Worker {
1155*61046927SAndroid Build Coastguard Worker vk_object_base_finish(&pipeline->base);
1156*61046927SAndroid Build Coastguard Worker }
1157*61046927SAndroid Build Coastguard Worker
1158*61046927SAndroid Build Coastguard Worker /* How many shared regs it takes to store a pvr_dev_addr_t.
1159*61046927SAndroid Build Coastguard Worker * Each shared reg is 32 bits.
1160*61046927SAndroid Build Coastguard Worker */
1161*61046927SAndroid Build Coastguard Worker #define PVR_DEV_ADDR_SIZE_IN_SH_REGS \
1162*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(sizeof(pvr_dev_addr_t), sizeof(uint32_t))
1163*61046927SAndroid Build Coastguard Worker
1164*61046927SAndroid Build Coastguard Worker /**
1165*61046927SAndroid Build Coastguard Worker * \brief Allocates shared registers.
1166*61046927SAndroid Build Coastguard Worker *
1167*61046927SAndroid Build Coastguard Worker * \return How many sh regs are required.
1168*61046927SAndroid Build Coastguard Worker */
1169*61046927SAndroid Build Coastguard Worker static uint32_t
pvr_pipeline_alloc_shareds(const struct pvr_device * device,const struct pvr_pipeline_layout * layout,enum pvr_stage_allocation stage,struct pvr_sh_reg_layout * const sh_reg_layout_out)1170*61046927SAndroid Build Coastguard Worker pvr_pipeline_alloc_shareds(const struct pvr_device *device,
1171*61046927SAndroid Build Coastguard Worker const struct pvr_pipeline_layout *layout,
1172*61046927SAndroid Build Coastguard Worker enum pvr_stage_allocation stage,
1173*61046927SAndroid Build Coastguard Worker struct pvr_sh_reg_layout *const sh_reg_layout_out)
1174*61046927SAndroid Build Coastguard Worker {
1175*61046927SAndroid Build Coastguard Worker ASSERTED const uint64_t reserved_shared_size =
1176*61046927SAndroid Build Coastguard Worker device->pdevice->dev_runtime_info.reserved_shared_size;
1177*61046927SAndroid Build Coastguard Worker ASSERTED const uint64_t max_coeff =
1178*61046927SAndroid Build Coastguard Worker device->pdevice->dev_runtime_info.max_coeffs;
1179*61046927SAndroid Build Coastguard Worker
1180*61046927SAndroid Build Coastguard Worker struct pvr_sh_reg_layout reg_layout = { 0 };
1181*61046927SAndroid Build Coastguard Worker uint32_t next_free_sh_reg = 0;
1182*61046927SAndroid Build Coastguard Worker
1183*61046927SAndroid Build Coastguard Worker reg_layout.descriptor_set_addrs_table.present =
1184*61046927SAndroid Build Coastguard Worker !!(layout->shader_stage_mask & BITFIELD_BIT(stage));
1185*61046927SAndroid Build Coastguard Worker
1186*61046927SAndroid Build Coastguard Worker if (reg_layout.descriptor_set_addrs_table.present) {
1187*61046927SAndroid Build Coastguard Worker reg_layout.descriptor_set_addrs_table.offset = next_free_sh_reg;
1188*61046927SAndroid Build Coastguard Worker next_free_sh_reg += PVR_DEV_ADDR_SIZE_IN_SH_REGS;
1189*61046927SAndroid Build Coastguard Worker }
1190*61046927SAndroid Build Coastguard Worker
1191*61046927SAndroid Build Coastguard Worker reg_layout.push_consts.present =
1192*61046927SAndroid Build Coastguard Worker !!(layout->push_constants_shader_stages & BITFIELD_BIT(stage));
1193*61046927SAndroid Build Coastguard Worker
1194*61046927SAndroid Build Coastguard Worker if (reg_layout.push_consts.present) {
1195*61046927SAndroid Build Coastguard Worker reg_layout.push_consts.offset = next_free_sh_reg;
1196*61046927SAndroid Build Coastguard Worker next_free_sh_reg += PVR_DEV_ADDR_SIZE_IN_SH_REGS;
1197*61046927SAndroid Build Coastguard Worker }
1198*61046927SAndroid Build Coastguard Worker
1199*61046927SAndroid Build Coastguard Worker *sh_reg_layout_out = reg_layout;
1200*61046927SAndroid Build Coastguard Worker
1201*61046927SAndroid Build Coastguard Worker /* FIXME: We might need to take more things into consideration.
1202*61046927SAndroid Build Coastguard Worker * See pvr_calc_fscommon_size_and_tiles_in_flight().
1203*61046927SAndroid Build Coastguard Worker */
1204*61046927SAndroid Build Coastguard Worker assert(next_free_sh_reg <= reserved_shared_size - max_coeff);
1205*61046927SAndroid Build Coastguard Worker
1206*61046927SAndroid Build Coastguard Worker return next_free_sh_reg;
1207*61046927SAndroid Build Coastguard Worker }
1208*61046927SAndroid Build Coastguard Worker
1209*61046927SAndroid Build Coastguard Worker /******************************************************************************
1210*61046927SAndroid Build Coastguard Worker Compute pipeline functions
1211*61046927SAndroid Build Coastguard Worker ******************************************************************************/
1212*61046927SAndroid Build Coastguard Worker
1213*61046927SAndroid Build Coastguard Worker /* Compiles and uploads shaders and PDS programs. */
pvr_compute_pipeline_compile(struct pvr_device * const device,struct vk_pipeline_cache * cache,const VkComputePipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * const allocator,struct pvr_compute_pipeline * const compute_pipeline)1214*61046927SAndroid Build Coastguard Worker static VkResult pvr_compute_pipeline_compile(
1215*61046927SAndroid Build Coastguard Worker struct pvr_device *const device,
1216*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
1217*61046927SAndroid Build Coastguard Worker const VkComputePipelineCreateInfo *pCreateInfo,
1218*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *const allocator,
1219*61046927SAndroid Build Coastguard Worker struct pvr_compute_pipeline *const compute_pipeline)
1220*61046927SAndroid Build Coastguard Worker {
1221*61046927SAndroid Build Coastguard Worker struct pvr_pipeline_layout *layout = compute_pipeline->base.layout;
1222*61046927SAndroid Build Coastguard Worker struct pvr_sh_reg_layout *sh_reg_layout =
1223*61046927SAndroid Build Coastguard Worker &layout->sh_reg_layout_per_stage[PVR_STAGE_ALLOCATION_COMPUTE];
1224*61046927SAndroid Build Coastguard Worker struct rogue_compile_time_consts_data compile_time_consts_data;
1225*61046927SAndroid Build Coastguard Worker uint32_t work_group_input_regs[PVR_WORKGROUP_DIMENSIONS];
1226*61046927SAndroid Build Coastguard Worker struct pvr_explicit_constant_usage explicit_const_usage;
1227*61046927SAndroid Build Coastguard Worker uint32_t local_input_regs[PVR_WORKGROUP_DIMENSIONS];
1228*61046927SAndroid Build Coastguard Worker struct rogue_ubo_data ubo_data;
1229*61046927SAndroid Build Coastguard Worker uint32_t barrier_coefficient;
1230*61046927SAndroid Build Coastguard Worker uint32_t usc_temps;
1231*61046927SAndroid Build Coastguard Worker VkResult result;
1232*61046927SAndroid Build Coastguard Worker
1233*61046927SAndroid Build Coastguard Worker if (pvr_has_hard_coded_shaders(&device->pdevice->dev_info)) {
1234*61046927SAndroid Build Coastguard Worker struct pvr_hard_code_compute_build_info build_info;
1235*61046927SAndroid Build Coastguard Worker
1236*61046927SAndroid Build Coastguard Worker result = pvr_hard_code_compute_pipeline(device,
1237*61046927SAndroid Build Coastguard Worker &compute_pipeline->shader_state,
1238*61046927SAndroid Build Coastguard Worker &build_info);
1239*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1240*61046927SAndroid Build Coastguard Worker return result;
1241*61046927SAndroid Build Coastguard Worker
1242*61046927SAndroid Build Coastguard Worker ubo_data = build_info.ubo_data;
1243*61046927SAndroid Build Coastguard Worker compile_time_consts_data = build_info.compile_time_consts_data;
1244*61046927SAndroid Build Coastguard Worker
1245*61046927SAndroid Build Coastguard Worker /* We make sure that the compiler's unused reg value is compatible with
1246*61046927SAndroid Build Coastguard Worker * the pds api.
1247*61046927SAndroid Build Coastguard Worker */
1248*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(ROGUE_REG_UNUSED == PVR_PDS_COMPUTE_INPUT_REG_UNUSED);
1249*61046927SAndroid Build Coastguard Worker
1250*61046927SAndroid Build Coastguard Worker barrier_coefficient = build_info.barrier_reg;
1251*61046927SAndroid Build Coastguard Worker
1252*61046927SAndroid Build Coastguard Worker /* TODO: Maybe change the pds api to use pointers so we avoid the copy. */
1253*61046927SAndroid Build Coastguard Worker local_input_regs[0] = build_info.local_invocation_regs[0];
1254*61046927SAndroid Build Coastguard Worker local_input_regs[1] = build_info.local_invocation_regs[1];
1255*61046927SAndroid Build Coastguard Worker /* This is not a mistake. We want to assign element 1 to 2. */
1256*61046927SAndroid Build Coastguard Worker local_input_regs[2] = build_info.local_invocation_regs[1];
1257*61046927SAndroid Build Coastguard Worker
1258*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(
1259*61046927SAndroid Build Coastguard Worker __same_type(work_group_input_regs, build_info.work_group_regs));
1260*61046927SAndroid Build Coastguard Worker typed_memcpy(work_group_input_regs,
1261*61046927SAndroid Build Coastguard Worker build_info.work_group_regs,
1262*61046927SAndroid Build Coastguard Worker PVR_WORKGROUP_DIMENSIONS);
1263*61046927SAndroid Build Coastguard Worker
1264*61046927SAndroid Build Coastguard Worker usc_temps = build_info.usc_temps;
1265*61046927SAndroid Build Coastguard Worker
1266*61046927SAndroid Build Coastguard Worker explicit_const_usage = build_info.explicit_conts_usage;
1267*61046927SAndroid Build Coastguard Worker
1268*61046927SAndroid Build Coastguard Worker } else {
1269*61046927SAndroid Build Coastguard Worker uint32_t sh_count;
1270*61046927SAndroid Build Coastguard Worker sh_count = pvr_pipeline_alloc_shareds(device,
1271*61046927SAndroid Build Coastguard Worker layout,
1272*61046927SAndroid Build Coastguard Worker PVR_STAGE_ALLOCATION_COMPUTE,
1273*61046927SAndroid Build Coastguard Worker sh_reg_layout);
1274*61046927SAndroid Build Coastguard Worker
1275*61046927SAndroid Build Coastguard Worker compute_pipeline->shader_state.const_shared_reg_count = sh_count;
1276*61046927SAndroid Build Coastguard Worker
1277*61046927SAndroid Build Coastguard Worker /* FIXME: Compile and upload the shader. */
1278*61046927SAndroid Build Coastguard Worker /* FIXME: Initialize the shader state and setup build info. */
1279*61046927SAndroid Build Coastguard Worker abort();
1280*61046927SAndroid Build Coastguard Worker };
1281*61046927SAndroid Build Coastguard Worker
1282*61046927SAndroid Build Coastguard Worker result = pvr_pds_descriptor_program_create_and_upload(
1283*61046927SAndroid Build Coastguard Worker device,
1284*61046927SAndroid Build Coastguard Worker allocator,
1285*61046927SAndroid Build Coastguard Worker &compile_time_consts_data,
1286*61046927SAndroid Build Coastguard Worker &ubo_data,
1287*61046927SAndroid Build Coastguard Worker &explicit_const_usage,
1288*61046927SAndroid Build Coastguard Worker layout,
1289*61046927SAndroid Build Coastguard Worker PVR_STAGE_ALLOCATION_COMPUTE,
1290*61046927SAndroid Build Coastguard Worker sh_reg_layout,
1291*61046927SAndroid Build Coastguard Worker &compute_pipeline->descriptor_state);
1292*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1293*61046927SAndroid Build Coastguard Worker goto err_free_shader;
1294*61046927SAndroid Build Coastguard Worker
1295*61046927SAndroid Build Coastguard Worker result = pvr_pds_compute_program_create_and_upload(
1296*61046927SAndroid Build Coastguard Worker device,
1297*61046927SAndroid Build Coastguard Worker allocator,
1298*61046927SAndroid Build Coastguard Worker local_input_regs,
1299*61046927SAndroid Build Coastguard Worker work_group_input_regs,
1300*61046927SAndroid Build Coastguard Worker barrier_coefficient,
1301*61046927SAndroid Build Coastguard Worker usc_temps,
1302*61046927SAndroid Build Coastguard Worker compute_pipeline->shader_state.bo->dev_addr,
1303*61046927SAndroid Build Coastguard Worker &compute_pipeline->primary_program,
1304*61046927SAndroid Build Coastguard Worker &compute_pipeline->primary_program_info);
1305*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1306*61046927SAndroid Build Coastguard Worker goto err_free_descriptor_program;
1307*61046927SAndroid Build Coastguard Worker
1308*61046927SAndroid Build Coastguard Worker /* If the workgroup ID is required, then we require the base workgroup
1309*61046927SAndroid Build Coastguard Worker * variant of the PDS compute program as well.
1310*61046927SAndroid Build Coastguard Worker */
1311*61046927SAndroid Build Coastguard Worker compute_pipeline->flags.base_workgroup =
1312*61046927SAndroid Build Coastguard Worker work_group_input_regs[0] != PVR_PDS_COMPUTE_INPUT_REG_UNUSED ||
1313*61046927SAndroid Build Coastguard Worker work_group_input_regs[1] != PVR_PDS_COMPUTE_INPUT_REG_UNUSED ||
1314*61046927SAndroid Build Coastguard Worker work_group_input_regs[2] != PVR_PDS_COMPUTE_INPUT_REG_UNUSED;
1315*61046927SAndroid Build Coastguard Worker
1316*61046927SAndroid Build Coastguard Worker if (compute_pipeline->flags.base_workgroup) {
1317*61046927SAndroid Build Coastguard Worker result = pvr_pds_compute_base_workgroup_variant_program_init(
1318*61046927SAndroid Build Coastguard Worker device,
1319*61046927SAndroid Build Coastguard Worker allocator,
1320*61046927SAndroid Build Coastguard Worker local_input_regs,
1321*61046927SAndroid Build Coastguard Worker work_group_input_regs,
1322*61046927SAndroid Build Coastguard Worker barrier_coefficient,
1323*61046927SAndroid Build Coastguard Worker usc_temps,
1324*61046927SAndroid Build Coastguard Worker compute_pipeline->shader_state.bo->dev_addr,
1325*61046927SAndroid Build Coastguard Worker &compute_pipeline->primary_base_workgroup_variant_program);
1326*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1327*61046927SAndroid Build Coastguard Worker goto err_destroy_compute_program;
1328*61046927SAndroid Build Coastguard Worker }
1329*61046927SAndroid Build Coastguard Worker
1330*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1331*61046927SAndroid Build Coastguard Worker
1332*61046927SAndroid Build Coastguard Worker err_destroy_compute_program:
1333*61046927SAndroid Build Coastguard Worker pvr_pds_compute_program_destroy(device,
1334*61046927SAndroid Build Coastguard Worker allocator,
1335*61046927SAndroid Build Coastguard Worker &compute_pipeline->primary_program,
1336*61046927SAndroid Build Coastguard Worker &compute_pipeline->primary_program_info);
1337*61046927SAndroid Build Coastguard Worker
1338*61046927SAndroid Build Coastguard Worker err_free_descriptor_program:
1339*61046927SAndroid Build Coastguard Worker pvr_pds_descriptor_program_destroy(device,
1340*61046927SAndroid Build Coastguard Worker allocator,
1341*61046927SAndroid Build Coastguard Worker &compute_pipeline->descriptor_state);
1342*61046927SAndroid Build Coastguard Worker
1343*61046927SAndroid Build Coastguard Worker err_free_shader:
1344*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(compute_pipeline->shader_state.bo);
1345*61046927SAndroid Build Coastguard Worker
1346*61046927SAndroid Build Coastguard Worker return result;
1347*61046927SAndroid Build Coastguard Worker }
1348*61046927SAndroid Build Coastguard Worker
1349*61046927SAndroid Build Coastguard Worker static VkResult
pvr_compute_pipeline_init(struct pvr_device * device,struct vk_pipeline_cache * cache,const VkComputePipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * allocator,struct pvr_compute_pipeline * compute_pipeline)1350*61046927SAndroid Build Coastguard Worker pvr_compute_pipeline_init(struct pvr_device *device,
1351*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
1352*61046927SAndroid Build Coastguard Worker const VkComputePipelineCreateInfo *pCreateInfo,
1353*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *allocator,
1354*61046927SAndroid Build Coastguard Worker struct pvr_compute_pipeline *compute_pipeline)
1355*61046927SAndroid Build Coastguard Worker {
1356*61046927SAndroid Build Coastguard Worker VkResult result;
1357*61046927SAndroid Build Coastguard Worker
1358*61046927SAndroid Build Coastguard Worker pvr_pipeline_init(device,
1359*61046927SAndroid Build Coastguard Worker PVR_PIPELINE_TYPE_COMPUTE,
1360*61046927SAndroid Build Coastguard Worker &compute_pipeline->base);
1361*61046927SAndroid Build Coastguard Worker
1362*61046927SAndroid Build Coastguard Worker compute_pipeline->base.layout =
1363*61046927SAndroid Build Coastguard Worker pvr_pipeline_layout_from_handle(pCreateInfo->layout);
1364*61046927SAndroid Build Coastguard Worker
1365*61046927SAndroid Build Coastguard Worker result = pvr_compute_pipeline_compile(device,
1366*61046927SAndroid Build Coastguard Worker cache,
1367*61046927SAndroid Build Coastguard Worker pCreateInfo,
1368*61046927SAndroid Build Coastguard Worker allocator,
1369*61046927SAndroid Build Coastguard Worker compute_pipeline);
1370*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
1371*61046927SAndroid Build Coastguard Worker pvr_pipeline_finish(&compute_pipeline->base);
1372*61046927SAndroid Build Coastguard Worker return result;
1373*61046927SAndroid Build Coastguard Worker }
1374*61046927SAndroid Build Coastguard Worker
1375*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1376*61046927SAndroid Build Coastguard Worker }
1377*61046927SAndroid Build Coastguard Worker
1378*61046927SAndroid Build Coastguard Worker static VkResult
pvr_compute_pipeline_create(struct pvr_device * device,struct vk_pipeline_cache * cache,const VkComputePipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * allocator,VkPipeline * const pipeline_out)1379*61046927SAndroid Build Coastguard Worker pvr_compute_pipeline_create(struct pvr_device *device,
1380*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
1381*61046927SAndroid Build Coastguard Worker const VkComputePipelineCreateInfo *pCreateInfo,
1382*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *allocator,
1383*61046927SAndroid Build Coastguard Worker VkPipeline *const pipeline_out)
1384*61046927SAndroid Build Coastguard Worker {
1385*61046927SAndroid Build Coastguard Worker struct pvr_compute_pipeline *compute_pipeline;
1386*61046927SAndroid Build Coastguard Worker VkResult result;
1387*61046927SAndroid Build Coastguard Worker
1388*61046927SAndroid Build Coastguard Worker compute_pipeline = vk_zalloc2(&device->vk.alloc,
1389*61046927SAndroid Build Coastguard Worker allocator,
1390*61046927SAndroid Build Coastguard Worker sizeof(*compute_pipeline),
1391*61046927SAndroid Build Coastguard Worker 8,
1392*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1393*61046927SAndroid Build Coastguard Worker if (!compute_pipeline)
1394*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1395*61046927SAndroid Build Coastguard Worker
1396*61046927SAndroid Build Coastguard Worker /* Compiles and uploads shaders and PDS programs. */
1397*61046927SAndroid Build Coastguard Worker result = pvr_compute_pipeline_init(device,
1398*61046927SAndroid Build Coastguard Worker cache,
1399*61046927SAndroid Build Coastguard Worker pCreateInfo,
1400*61046927SAndroid Build Coastguard Worker allocator,
1401*61046927SAndroid Build Coastguard Worker compute_pipeline);
1402*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
1403*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, compute_pipeline);
1404*61046927SAndroid Build Coastguard Worker return result;
1405*61046927SAndroid Build Coastguard Worker }
1406*61046927SAndroid Build Coastguard Worker
1407*61046927SAndroid Build Coastguard Worker *pipeline_out = pvr_pipeline_to_handle(&compute_pipeline->base);
1408*61046927SAndroid Build Coastguard Worker
1409*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1410*61046927SAndroid Build Coastguard Worker }
1411*61046927SAndroid Build Coastguard Worker
pvr_compute_pipeline_destroy(struct pvr_device * const device,const VkAllocationCallbacks * const allocator,struct pvr_compute_pipeline * const compute_pipeline)1412*61046927SAndroid Build Coastguard Worker static void pvr_compute_pipeline_destroy(
1413*61046927SAndroid Build Coastguard Worker struct pvr_device *const device,
1414*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *const allocator,
1415*61046927SAndroid Build Coastguard Worker struct pvr_compute_pipeline *const compute_pipeline)
1416*61046927SAndroid Build Coastguard Worker {
1417*61046927SAndroid Build Coastguard Worker if (compute_pipeline->flags.base_workgroup) {
1418*61046927SAndroid Build Coastguard Worker pvr_pds_compute_base_workgroup_variant_program_finish(
1419*61046927SAndroid Build Coastguard Worker device,
1420*61046927SAndroid Build Coastguard Worker allocator,
1421*61046927SAndroid Build Coastguard Worker &compute_pipeline->primary_base_workgroup_variant_program);
1422*61046927SAndroid Build Coastguard Worker }
1423*61046927SAndroid Build Coastguard Worker
1424*61046927SAndroid Build Coastguard Worker pvr_pds_compute_program_destroy(device,
1425*61046927SAndroid Build Coastguard Worker allocator,
1426*61046927SAndroid Build Coastguard Worker &compute_pipeline->primary_program,
1427*61046927SAndroid Build Coastguard Worker &compute_pipeline->primary_program_info);
1428*61046927SAndroid Build Coastguard Worker pvr_pds_descriptor_program_destroy(device,
1429*61046927SAndroid Build Coastguard Worker allocator,
1430*61046927SAndroid Build Coastguard Worker &compute_pipeline->descriptor_state);
1431*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(compute_pipeline->shader_state.bo);
1432*61046927SAndroid Build Coastguard Worker
1433*61046927SAndroid Build Coastguard Worker pvr_pipeline_finish(&compute_pipeline->base);
1434*61046927SAndroid Build Coastguard Worker
1435*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, compute_pipeline);
1436*61046927SAndroid Build Coastguard Worker }
1437*61046927SAndroid Build Coastguard Worker
1438*61046927SAndroid Build Coastguard Worker VkResult
pvr_CreateComputePipelines(VkDevice _device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)1439*61046927SAndroid Build Coastguard Worker pvr_CreateComputePipelines(VkDevice _device,
1440*61046927SAndroid Build Coastguard Worker VkPipelineCache pipelineCache,
1441*61046927SAndroid Build Coastguard Worker uint32_t createInfoCount,
1442*61046927SAndroid Build Coastguard Worker const VkComputePipelineCreateInfo *pCreateInfos,
1443*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
1444*61046927SAndroid Build Coastguard Worker VkPipeline *pPipelines)
1445*61046927SAndroid Build Coastguard Worker {
1446*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(vk_pipeline_cache, cache, pipelineCache);
1447*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_device, device, _device);
1448*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
1449*61046927SAndroid Build Coastguard Worker
1450*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < createInfoCount; i++) {
1451*61046927SAndroid Build Coastguard Worker const VkResult local_result =
1452*61046927SAndroid Build Coastguard Worker pvr_compute_pipeline_create(device,
1453*61046927SAndroid Build Coastguard Worker cache,
1454*61046927SAndroid Build Coastguard Worker &pCreateInfos[i],
1455*61046927SAndroid Build Coastguard Worker pAllocator,
1456*61046927SAndroid Build Coastguard Worker &pPipelines[i]);
1457*61046927SAndroid Build Coastguard Worker if (local_result != VK_SUCCESS) {
1458*61046927SAndroid Build Coastguard Worker result = local_result;
1459*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
1460*61046927SAndroid Build Coastguard Worker }
1461*61046927SAndroid Build Coastguard Worker }
1462*61046927SAndroid Build Coastguard Worker
1463*61046927SAndroid Build Coastguard Worker return result;
1464*61046927SAndroid Build Coastguard Worker }
1465*61046927SAndroid Build Coastguard Worker
1466*61046927SAndroid Build Coastguard Worker /******************************************************************************
1467*61046927SAndroid Build Coastguard Worker Graphics pipeline functions
1468*61046927SAndroid Build Coastguard Worker ******************************************************************************/
1469*61046927SAndroid Build Coastguard Worker
1470*61046927SAndroid Build Coastguard Worker static void
pvr_graphics_pipeline_destroy(struct pvr_device * const device,const VkAllocationCallbacks * const allocator,struct pvr_graphics_pipeline * const gfx_pipeline)1471*61046927SAndroid Build Coastguard Worker pvr_graphics_pipeline_destroy(struct pvr_device *const device,
1472*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *const allocator,
1473*61046927SAndroid Build Coastguard Worker struct pvr_graphics_pipeline *const gfx_pipeline)
1474*61046927SAndroid Build Coastguard Worker {
1475*61046927SAndroid Build Coastguard Worker const uint32_t num_vertex_attrib_programs =
1476*61046927SAndroid Build Coastguard Worker ARRAY_SIZE(gfx_pipeline->shader_state.vertex.pds_attrib_programs);
1477*61046927SAndroid Build Coastguard Worker
1478*61046927SAndroid Build Coastguard Worker pvr_pds_descriptor_program_destroy(
1479*61046927SAndroid Build Coastguard Worker device,
1480*61046927SAndroid Build Coastguard Worker allocator,
1481*61046927SAndroid Build Coastguard Worker &gfx_pipeline->shader_state.fragment.descriptor_state);
1482*61046927SAndroid Build Coastguard Worker
1483*61046927SAndroid Build Coastguard Worker pvr_pds_descriptor_program_destroy(
1484*61046927SAndroid Build Coastguard Worker device,
1485*61046927SAndroid Build Coastguard Worker allocator,
1486*61046927SAndroid Build Coastguard Worker &gfx_pipeline->shader_state.vertex.descriptor_state);
1487*61046927SAndroid Build Coastguard Worker
1488*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < num_vertex_attrib_programs; i++) {
1489*61046927SAndroid Build Coastguard Worker struct pvr_pds_attrib_program *const attrib_program =
1490*61046927SAndroid Build Coastguard Worker &gfx_pipeline->shader_state.vertex.pds_attrib_programs[i];
1491*61046927SAndroid Build Coastguard Worker
1492*61046927SAndroid Build Coastguard Worker pvr_pds_vertex_attrib_program_destroy(device, allocator, attrib_program);
1493*61046927SAndroid Build Coastguard Worker }
1494*61046927SAndroid Build Coastguard Worker
1495*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(
1496*61046927SAndroid Build Coastguard Worker gfx_pipeline->shader_state.fragment.pds_fragment_program.pvr_bo);
1497*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(
1498*61046927SAndroid Build Coastguard Worker gfx_pipeline->shader_state.fragment.pds_coeff_program.pvr_bo);
1499*61046927SAndroid Build Coastguard Worker
1500*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(gfx_pipeline->shader_state.fragment.bo);
1501*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(gfx_pipeline->shader_state.vertex.bo);
1502*61046927SAndroid Build Coastguard Worker
1503*61046927SAndroid Build Coastguard Worker pvr_pipeline_finish(&gfx_pipeline->base);
1504*61046927SAndroid Build Coastguard Worker
1505*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, gfx_pipeline);
1506*61046927SAndroid Build Coastguard Worker }
1507*61046927SAndroid Build Coastguard Worker
1508*61046927SAndroid Build Coastguard Worker static void
pvr_vertex_state_init(struct pvr_graphics_pipeline * gfx_pipeline,const struct rogue_common_build_data * common_data,uint32_t vtxin_regs_used,const struct rogue_vs_build_data * vs_data)1509*61046927SAndroid Build Coastguard Worker pvr_vertex_state_init(struct pvr_graphics_pipeline *gfx_pipeline,
1510*61046927SAndroid Build Coastguard Worker const struct rogue_common_build_data *common_data,
1511*61046927SAndroid Build Coastguard Worker uint32_t vtxin_regs_used,
1512*61046927SAndroid Build Coastguard Worker const struct rogue_vs_build_data *vs_data)
1513*61046927SAndroid Build Coastguard Worker {
1514*61046927SAndroid Build Coastguard Worker struct pvr_vertex_shader_state *vertex_state =
1515*61046927SAndroid Build Coastguard Worker &gfx_pipeline->shader_state.vertex;
1516*61046927SAndroid Build Coastguard Worker
1517*61046927SAndroid Build Coastguard Worker /* TODO: Hard coding these for now. These should be populated based on the
1518*61046927SAndroid Build Coastguard Worker * information returned by the compiler.
1519*61046927SAndroid Build Coastguard Worker */
1520*61046927SAndroid Build Coastguard Worker vertex_state->stage_state.const_shared_reg_count = common_data->shareds;
1521*61046927SAndroid Build Coastguard Worker vertex_state->stage_state.const_shared_reg_offset = 0;
1522*61046927SAndroid Build Coastguard Worker vertex_state->stage_state.coefficient_size = common_data->coeffs;
1523*61046927SAndroid Build Coastguard Worker vertex_state->stage_state.uses_atomic_ops = false;
1524*61046927SAndroid Build Coastguard Worker vertex_state->stage_state.uses_texture_rw = false;
1525*61046927SAndroid Build Coastguard Worker vertex_state->stage_state.uses_barrier = false;
1526*61046927SAndroid Build Coastguard Worker vertex_state->stage_state.has_side_effects = false;
1527*61046927SAndroid Build Coastguard Worker vertex_state->stage_state.empty_program = false;
1528*61046927SAndroid Build Coastguard Worker
1529*61046927SAndroid Build Coastguard Worker /* This ends up unused since we'll use the temp_usage for the PDS program we
1530*61046927SAndroid Build Coastguard Worker * end up selecting, and the descriptor PDS program doesn't use any temps.
1531*61046927SAndroid Build Coastguard Worker * Let's set it to ~0 in case it ever gets used.
1532*61046927SAndroid Build Coastguard Worker */
1533*61046927SAndroid Build Coastguard Worker vertex_state->stage_state.pds_temps_count = ~0;
1534*61046927SAndroid Build Coastguard Worker
1535*61046927SAndroid Build Coastguard Worker vertex_state->vertex_input_size = vtxin_regs_used;
1536*61046927SAndroid Build Coastguard Worker vertex_state->vertex_output_size =
1537*61046927SAndroid Build Coastguard Worker vs_data->num_vertex_outputs * ROGUE_REG_SIZE_BYTES;
1538*61046927SAndroid Build Coastguard Worker vertex_state->user_clip_planes_mask = 0;
1539*61046927SAndroid Build Coastguard Worker vertex_state->entry_offset = 0;
1540*61046927SAndroid Build Coastguard Worker
1541*61046927SAndroid Build Coastguard Worker /* TODO: The number of varyings should be checked against the fragment
1542*61046927SAndroid Build Coastguard Worker * shader inputs and assigned in the place where that happens.
1543*61046927SAndroid Build Coastguard Worker * There will also be an opportunity to cull unused fs inputs/vs outputs.
1544*61046927SAndroid Build Coastguard Worker */
1545*61046927SAndroid Build Coastguard Worker pvr_csb_pack (&gfx_pipeline->shader_state.vertex.varying[0],
1546*61046927SAndroid Build Coastguard Worker TA_STATE_VARYING0,
1547*61046927SAndroid Build Coastguard Worker varying0) {
1548*61046927SAndroid Build Coastguard Worker varying0.f32_linear = vs_data->num_varyings;
1549*61046927SAndroid Build Coastguard Worker varying0.f32_flat = 0;
1550*61046927SAndroid Build Coastguard Worker varying0.f32_npc = 0;
1551*61046927SAndroid Build Coastguard Worker }
1552*61046927SAndroid Build Coastguard Worker
1553*61046927SAndroid Build Coastguard Worker pvr_csb_pack (&gfx_pipeline->shader_state.vertex.varying[1],
1554*61046927SAndroid Build Coastguard Worker TA_STATE_VARYING1,
1555*61046927SAndroid Build Coastguard Worker varying1) {
1556*61046927SAndroid Build Coastguard Worker varying1.f16_linear = 0;
1557*61046927SAndroid Build Coastguard Worker varying1.f16_flat = 0;
1558*61046927SAndroid Build Coastguard Worker varying1.f16_npc = 0;
1559*61046927SAndroid Build Coastguard Worker }
1560*61046927SAndroid Build Coastguard Worker }
1561*61046927SAndroid Build Coastguard Worker
1562*61046927SAndroid Build Coastguard Worker static void
pvr_fragment_state_init(struct pvr_graphics_pipeline * gfx_pipeline,const struct rogue_common_build_data * common_data)1563*61046927SAndroid Build Coastguard Worker pvr_fragment_state_init(struct pvr_graphics_pipeline *gfx_pipeline,
1564*61046927SAndroid Build Coastguard Worker const struct rogue_common_build_data *common_data)
1565*61046927SAndroid Build Coastguard Worker {
1566*61046927SAndroid Build Coastguard Worker struct pvr_fragment_shader_state *fragment_state =
1567*61046927SAndroid Build Coastguard Worker &gfx_pipeline->shader_state.fragment;
1568*61046927SAndroid Build Coastguard Worker
1569*61046927SAndroid Build Coastguard Worker /* TODO: Hard coding these for now. These should be populated based on the
1570*61046927SAndroid Build Coastguard Worker * information returned by the compiler.
1571*61046927SAndroid Build Coastguard Worker */
1572*61046927SAndroid Build Coastguard Worker fragment_state->stage_state.const_shared_reg_count = 0;
1573*61046927SAndroid Build Coastguard Worker fragment_state->stage_state.const_shared_reg_offset = 0;
1574*61046927SAndroid Build Coastguard Worker fragment_state->stage_state.coefficient_size = common_data->coeffs;
1575*61046927SAndroid Build Coastguard Worker fragment_state->stage_state.uses_atomic_ops = false;
1576*61046927SAndroid Build Coastguard Worker fragment_state->stage_state.uses_texture_rw = false;
1577*61046927SAndroid Build Coastguard Worker fragment_state->stage_state.uses_barrier = false;
1578*61046927SAndroid Build Coastguard Worker fragment_state->stage_state.has_side_effects = false;
1579*61046927SAndroid Build Coastguard Worker fragment_state->stage_state.empty_program = false;
1580*61046927SAndroid Build Coastguard Worker
1581*61046927SAndroid Build Coastguard Worker fragment_state->pass_type = PVRX(TA_PASSTYPE_OPAQUE);
1582*61046927SAndroid Build Coastguard Worker fragment_state->entry_offset = 0;
1583*61046927SAndroid Build Coastguard Worker
1584*61046927SAndroid Build Coastguard Worker /* We can't initialize it yet since we still need to generate the PDS
1585*61046927SAndroid Build Coastguard Worker * programs so set it to `~0` to make sure that we set this up later on.
1586*61046927SAndroid Build Coastguard Worker */
1587*61046927SAndroid Build Coastguard Worker fragment_state->stage_state.pds_temps_count = ~0;
1588*61046927SAndroid Build Coastguard Worker }
1589*61046927SAndroid Build Coastguard Worker
pvr_blend_factor_requires_consts(VkBlendFactor factor)1590*61046927SAndroid Build Coastguard Worker static bool pvr_blend_factor_requires_consts(VkBlendFactor factor)
1591*61046927SAndroid Build Coastguard Worker {
1592*61046927SAndroid Build Coastguard Worker switch (factor) {
1593*61046927SAndroid Build Coastguard Worker case VK_BLEND_FACTOR_CONSTANT_COLOR:
1594*61046927SAndroid Build Coastguard Worker case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR:
1595*61046927SAndroid Build Coastguard Worker case VK_BLEND_FACTOR_CONSTANT_ALPHA:
1596*61046927SAndroid Build Coastguard Worker case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA:
1597*61046927SAndroid Build Coastguard Worker return true;
1598*61046927SAndroid Build Coastguard Worker
1599*61046927SAndroid Build Coastguard Worker default:
1600*61046927SAndroid Build Coastguard Worker return false;
1601*61046927SAndroid Build Coastguard Worker }
1602*61046927SAndroid Build Coastguard Worker }
1603*61046927SAndroid Build Coastguard Worker
1604*61046927SAndroid Build Coastguard Worker /**
1605*61046927SAndroid Build Coastguard Worker * \brief Indicates whether dynamic blend constants are needed.
1606*61046927SAndroid Build Coastguard Worker *
1607*61046927SAndroid Build Coastguard Worker * If the user has specified the blend constants to be dynamic, they might not
1608*61046927SAndroid Build Coastguard Worker * necessarily be using them. This function makes sure that they are being used
1609*61046927SAndroid Build Coastguard Worker * in order to determine whether we need to upload them later on for the shader
1610*61046927SAndroid Build Coastguard Worker * to access them.
1611*61046927SAndroid Build Coastguard Worker */
pvr_graphics_pipeline_requires_dynamic_blend_consts(const struct pvr_graphics_pipeline * gfx_pipeline)1612*61046927SAndroid Build Coastguard Worker static bool pvr_graphics_pipeline_requires_dynamic_blend_consts(
1613*61046927SAndroid Build Coastguard Worker const struct pvr_graphics_pipeline *gfx_pipeline)
1614*61046927SAndroid Build Coastguard Worker {
1615*61046927SAndroid Build Coastguard Worker const struct vk_dynamic_graphics_state *const state =
1616*61046927SAndroid Build Coastguard Worker &gfx_pipeline->dynamic_state;
1617*61046927SAndroid Build Coastguard Worker
1618*61046927SAndroid Build Coastguard Worker if (BITSET_TEST(state->set, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS))
1619*61046927SAndroid Build Coastguard Worker return false;
1620*61046927SAndroid Build Coastguard Worker
1621*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < state->cb.attachment_count; i++) {
1622*61046927SAndroid Build Coastguard Worker const struct vk_color_blend_attachment_state *attachment =
1623*61046927SAndroid Build Coastguard Worker &state->cb.attachments[i];
1624*61046927SAndroid Build Coastguard Worker
1625*61046927SAndroid Build Coastguard Worker const bool has_color_write =
1626*61046927SAndroid Build Coastguard Worker attachment->write_mask &
1627*61046927SAndroid Build Coastguard Worker (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
1628*61046927SAndroid Build Coastguard Worker VK_COLOR_COMPONENT_B_BIT);
1629*61046927SAndroid Build Coastguard Worker const bool has_alpha_write = attachment->write_mask &
1630*61046927SAndroid Build Coastguard Worker VK_COLOR_COMPONENT_A_BIT;
1631*61046927SAndroid Build Coastguard Worker
1632*61046927SAndroid Build Coastguard Worker if (!attachment->blend_enable || attachment->write_mask == 0)
1633*61046927SAndroid Build Coastguard Worker continue;
1634*61046927SAndroid Build Coastguard Worker
1635*61046927SAndroid Build Coastguard Worker if (has_color_write) {
1636*61046927SAndroid Build Coastguard Worker const uint8_t src_color_blend_factor =
1637*61046927SAndroid Build Coastguard Worker attachment->src_color_blend_factor;
1638*61046927SAndroid Build Coastguard Worker const uint8_t dst_color_blend_factor =
1639*61046927SAndroid Build Coastguard Worker attachment->dst_color_blend_factor;
1640*61046927SAndroid Build Coastguard Worker
1641*61046927SAndroid Build Coastguard Worker if (pvr_blend_factor_requires_consts(src_color_blend_factor) ||
1642*61046927SAndroid Build Coastguard Worker pvr_blend_factor_requires_consts(dst_color_blend_factor)) {
1643*61046927SAndroid Build Coastguard Worker return true;
1644*61046927SAndroid Build Coastguard Worker }
1645*61046927SAndroid Build Coastguard Worker }
1646*61046927SAndroid Build Coastguard Worker
1647*61046927SAndroid Build Coastguard Worker if (has_alpha_write) {
1648*61046927SAndroid Build Coastguard Worker const uint8_t src_alpha_blend_factor =
1649*61046927SAndroid Build Coastguard Worker attachment->src_alpha_blend_factor;
1650*61046927SAndroid Build Coastguard Worker const uint8_t dst_alpha_blend_factor =
1651*61046927SAndroid Build Coastguard Worker attachment->dst_alpha_blend_factor;
1652*61046927SAndroid Build Coastguard Worker
1653*61046927SAndroid Build Coastguard Worker if (pvr_blend_factor_requires_consts(src_alpha_blend_factor) ||
1654*61046927SAndroid Build Coastguard Worker pvr_blend_factor_requires_consts(dst_alpha_blend_factor)) {
1655*61046927SAndroid Build Coastguard Worker return true;
1656*61046927SAndroid Build Coastguard Worker }
1657*61046927SAndroid Build Coastguard Worker }
1658*61046927SAndroid Build Coastguard Worker }
1659*61046927SAndroid Build Coastguard Worker
1660*61046927SAndroid Build Coastguard Worker return false;
1661*61046927SAndroid Build Coastguard Worker }
1662*61046927SAndroid Build Coastguard Worker
pvr_graphics_pipeline_alloc_shareds(const struct pvr_device * device,const struct pvr_graphics_pipeline * gfx_pipeline,enum pvr_stage_allocation stage,struct pvr_sh_reg_layout * const sh_reg_layout_out)1663*61046927SAndroid Build Coastguard Worker static uint32_t pvr_graphics_pipeline_alloc_shareds(
1664*61046927SAndroid Build Coastguard Worker const struct pvr_device *device,
1665*61046927SAndroid Build Coastguard Worker const struct pvr_graphics_pipeline *gfx_pipeline,
1666*61046927SAndroid Build Coastguard Worker enum pvr_stage_allocation stage,
1667*61046927SAndroid Build Coastguard Worker struct pvr_sh_reg_layout *const sh_reg_layout_out)
1668*61046927SAndroid Build Coastguard Worker {
1669*61046927SAndroid Build Coastguard Worker ASSERTED const uint64_t reserved_shared_size =
1670*61046927SAndroid Build Coastguard Worker device->pdevice->dev_runtime_info.reserved_shared_size;
1671*61046927SAndroid Build Coastguard Worker ASSERTED const uint64_t max_coeff =
1672*61046927SAndroid Build Coastguard Worker device->pdevice->dev_runtime_info.max_coeffs;
1673*61046927SAndroid Build Coastguard Worker
1674*61046927SAndroid Build Coastguard Worker const struct pvr_pipeline_layout *layout = gfx_pipeline->base.layout;
1675*61046927SAndroid Build Coastguard Worker struct pvr_sh_reg_layout reg_layout = { 0 };
1676*61046927SAndroid Build Coastguard Worker uint32_t next_free_sh_reg = 0;
1677*61046927SAndroid Build Coastguard Worker
1678*61046927SAndroid Build Coastguard Worker next_free_sh_reg =
1679*61046927SAndroid Build Coastguard Worker pvr_pipeline_alloc_shareds(device, layout, stage, ®_layout);
1680*61046927SAndroid Build Coastguard Worker
1681*61046927SAndroid Build Coastguard Worker reg_layout.blend_consts.present =
1682*61046927SAndroid Build Coastguard Worker (stage == PVR_STAGE_ALLOCATION_FRAGMENT &&
1683*61046927SAndroid Build Coastguard Worker pvr_graphics_pipeline_requires_dynamic_blend_consts(gfx_pipeline));
1684*61046927SAndroid Build Coastguard Worker if (reg_layout.blend_consts.present) {
1685*61046927SAndroid Build Coastguard Worker reg_layout.blend_consts.offset = next_free_sh_reg;
1686*61046927SAndroid Build Coastguard Worker next_free_sh_reg += PVR_DEV_ADDR_SIZE_IN_SH_REGS;
1687*61046927SAndroid Build Coastguard Worker }
1688*61046927SAndroid Build Coastguard Worker
1689*61046927SAndroid Build Coastguard Worker *sh_reg_layout_out = reg_layout;
1690*61046927SAndroid Build Coastguard Worker
1691*61046927SAndroid Build Coastguard Worker /* FIXME: We might need to take more things into consideration.
1692*61046927SAndroid Build Coastguard Worker * See pvr_calc_fscommon_size_and_tiles_in_flight().
1693*61046927SAndroid Build Coastguard Worker */
1694*61046927SAndroid Build Coastguard Worker assert(next_free_sh_reg <= reserved_shared_size - max_coeff);
1695*61046927SAndroid Build Coastguard Worker
1696*61046927SAndroid Build Coastguard Worker return next_free_sh_reg;
1697*61046927SAndroid Build Coastguard Worker }
1698*61046927SAndroid Build Coastguard Worker
1699*61046927SAndroid Build Coastguard Worker #undef PVR_DEV_ADDR_SIZE_IN_SH_REGS
1700*61046927SAndroid Build Coastguard Worker
pvr_graphics_pipeline_alloc_vertex_inputs(const VkPipelineVertexInputStateCreateInfo * const vs_data,rogue_vertex_inputs * const vertex_input_layout_out,unsigned * num_vertex_input_regs_out,pvr_pds_attrib_dma_descriptions_array_ptr dma_descriptions_out_ptr,uint32_t * const dma_count_out)1701*61046927SAndroid Build Coastguard Worker static void pvr_graphics_pipeline_alloc_vertex_inputs(
1702*61046927SAndroid Build Coastguard Worker const VkPipelineVertexInputStateCreateInfo *const vs_data,
1703*61046927SAndroid Build Coastguard Worker rogue_vertex_inputs *const vertex_input_layout_out,
1704*61046927SAndroid Build Coastguard Worker unsigned *num_vertex_input_regs_out,
1705*61046927SAndroid Build Coastguard Worker pvr_pds_attrib_dma_descriptions_array_ptr dma_descriptions_out_ptr,
1706*61046927SAndroid Build Coastguard Worker uint32_t *const dma_count_out)
1707*61046927SAndroid Build Coastguard Worker {
1708*61046927SAndroid Build Coastguard Worker const VkVertexInputBindingDescription
1709*61046927SAndroid Build Coastguard Worker *sorted_bindings[PVR_MAX_VERTEX_INPUT_BINDINGS] = { 0 };
1710*61046927SAndroid Build Coastguard Worker const VkVertexInputAttributeDescription
1711*61046927SAndroid Build Coastguard Worker *sorted_attributes[PVR_MAX_VERTEX_INPUT_BINDINGS] = { 0 };
1712*61046927SAndroid Build Coastguard Worker
1713*61046927SAndroid Build Coastguard Worker rogue_vertex_inputs build_data = {
1714*61046927SAndroid Build Coastguard Worker .num_input_vars = vs_data->vertexAttributeDescriptionCount,
1715*61046927SAndroid Build Coastguard Worker };
1716*61046927SAndroid Build Coastguard Worker uint32_t next_reg_offset = 0;
1717*61046927SAndroid Build Coastguard Worker
1718*61046927SAndroid Build Coastguard Worker struct pvr_pds_vertex_dma *const dma_descriptions =
1719*61046927SAndroid Build Coastguard Worker *dma_descriptions_out_ptr;
1720*61046927SAndroid Build Coastguard Worker uint32_t dma_count = 0;
1721*61046927SAndroid Build Coastguard Worker
1722*61046927SAndroid Build Coastguard Worker /* Vertex attributes map to the `layout(location = x)` annotation in the
1723*61046927SAndroid Build Coastguard Worker * shader where `x` is the attribute's location.
1724*61046927SAndroid Build Coastguard Worker * Vertex bindings have NO relation to the shader. They have nothing to do
1725*61046927SAndroid Build Coastguard Worker * with the `layout(set = x, binding = y)` notation. They instead indicate
1726*61046927SAndroid Build Coastguard Worker * where the data for a collection of vertex attributes comes from. The
1727*61046927SAndroid Build Coastguard Worker * application binds a VkBuffer with vkCmdBindVertexBuffers() to a specific
1728*61046927SAndroid Build Coastguard Worker * binding number and based on that we'll know which buffer to DMA the data
1729*61046927SAndroid Build Coastguard Worker * from, to fill in the collection of vertex attributes.
1730*61046927SAndroid Build Coastguard Worker */
1731*61046927SAndroid Build Coastguard Worker
1732*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < vs_data->vertexBindingDescriptionCount; i++) {
1733*61046927SAndroid Build Coastguard Worker const VkVertexInputBindingDescription *binding_desc =
1734*61046927SAndroid Build Coastguard Worker &vs_data->pVertexBindingDescriptions[i];
1735*61046927SAndroid Build Coastguard Worker
1736*61046927SAndroid Build Coastguard Worker sorted_bindings[binding_desc->binding] = binding_desc;
1737*61046927SAndroid Build Coastguard Worker }
1738*61046927SAndroid Build Coastguard Worker
1739*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < vs_data->vertexAttributeDescriptionCount; i++) {
1740*61046927SAndroid Build Coastguard Worker const VkVertexInputAttributeDescription *attribute_desc =
1741*61046927SAndroid Build Coastguard Worker &vs_data->pVertexAttributeDescriptions[i];
1742*61046927SAndroid Build Coastguard Worker
1743*61046927SAndroid Build Coastguard Worker sorted_attributes[attribute_desc->location] = attribute_desc;
1744*61046927SAndroid Build Coastguard Worker }
1745*61046927SAndroid Build Coastguard Worker
1746*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0, j = 0; i < ARRAY_SIZE(sorted_attributes); i++) {
1747*61046927SAndroid Build Coastguard Worker if (sorted_attributes[i])
1748*61046927SAndroid Build Coastguard Worker sorted_attributes[j++] = sorted_attributes[i];
1749*61046927SAndroid Build Coastguard Worker }
1750*61046927SAndroid Build Coastguard Worker
1751*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < vs_data->vertexAttributeDescriptionCount; i++) {
1752*61046927SAndroid Build Coastguard Worker const VkVertexInputAttributeDescription *attribute = sorted_attributes[i];
1753*61046927SAndroid Build Coastguard Worker const VkVertexInputBindingDescription *binding =
1754*61046927SAndroid Build Coastguard Worker sorted_bindings[attribute->binding];
1755*61046927SAndroid Build Coastguard Worker const struct util_format_description *fmt_description =
1756*61046927SAndroid Build Coastguard Worker vk_format_description(attribute->format);
1757*61046927SAndroid Build Coastguard Worker struct pvr_pds_vertex_dma *dma_desc = &dma_descriptions[dma_count];
1758*61046927SAndroid Build Coastguard Worker unsigned vtxin_reg_offset;
1759*61046927SAndroid Build Coastguard Worker
1760*61046927SAndroid Build Coastguard Worker /* Reg allocation. */
1761*61046927SAndroid Build Coastguard Worker
1762*61046927SAndroid Build Coastguard Worker vtxin_reg_offset = next_reg_offset;
1763*61046927SAndroid Build Coastguard Worker build_data.base[i] = vtxin_reg_offset;
1764*61046927SAndroid Build Coastguard Worker
1765*61046927SAndroid Build Coastguard Worker if (fmt_description->colorspace != UTIL_FORMAT_COLORSPACE_RGB ||
1766*61046927SAndroid Build Coastguard Worker fmt_description->layout != UTIL_FORMAT_LAYOUT_PLAIN ||
1767*61046927SAndroid Build Coastguard Worker fmt_description->block.bits % 32 != 0 || !fmt_description->is_array) {
1768*61046927SAndroid Build Coastguard Worker /* For now we only support formats with 32 bit components since we
1769*61046927SAndroid Build Coastguard Worker * don't need to pack/unpack them.
1770*61046927SAndroid Build Coastguard Worker */
1771*61046927SAndroid Build Coastguard Worker /* TODO: Support any other format with VERTEX_BUFFER_BIT set that
1772*61046927SAndroid Build Coastguard Worker * doesn't have 32 bit components if we're advertising any.
1773*61046927SAndroid Build Coastguard Worker */
1774*61046927SAndroid Build Coastguard Worker assert(false);
1775*61046927SAndroid Build Coastguard Worker }
1776*61046927SAndroid Build Coastguard Worker
1777*61046927SAndroid Build Coastguard Worker /* TODO: Check if this is fine with the compiler. Does it want the amount
1778*61046927SAndroid Build Coastguard Worker * of components or does it want a size in dwords to figure out how many
1779*61046927SAndroid Build Coastguard Worker * vtxin regs are covered. For formats with 32 bit components the
1780*61046927SAndroid Build Coastguard Worker * distinction doesn't change anything.
1781*61046927SAndroid Build Coastguard Worker */
1782*61046927SAndroid Build Coastguard Worker build_data.components[i] =
1783*61046927SAndroid Build Coastguard Worker util_format_get_nr_components(fmt_description->format);
1784*61046927SAndroid Build Coastguard Worker
1785*61046927SAndroid Build Coastguard Worker next_reg_offset += build_data.components[i];
1786*61046927SAndroid Build Coastguard Worker
1787*61046927SAndroid Build Coastguard Worker /* DMA setup. */
1788*61046927SAndroid Build Coastguard Worker
1789*61046927SAndroid Build Coastguard Worker /* The PDS program sets up DDMADs to DMA attributes into vtxin regs.
1790*61046927SAndroid Build Coastguard Worker *
1791*61046927SAndroid Build Coastguard Worker * DDMAD -> Multiply, add, and DOUTD (i.e. DMA from that address).
1792*61046927SAndroid Build Coastguard Worker * DMA source addr = src0 * src1 + src2
1793*61046927SAndroid Build Coastguard Worker * DMA params = src3
1794*61046927SAndroid Build Coastguard Worker *
1795*61046927SAndroid Build Coastguard Worker * In the PDS program we setup src0 with the binding's stride and src1
1796*61046927SAndroid Build Coastguard Worker * with either the instance id or vertex id (both of which get filled by
1797*61046927SAndroid Build Coastguard Worker * the hardware). We setup src2 later on once we know which VkBuffer to
1798*61046927SAndroid Build Coastguard Worker * DMA the data from so it's saved for later when we patch the data
1799*61046927SAndroid Build Coastguard Worker * section.
1800*61046927SAndroid Build Coastguard Worker */
1801*61046927SAndroid Build Coastguard Worker
1802*61046927SAndroid Build Coastguard Worker /* TODO: Right now we're setting up a DMA per attribute. In a case where
1803*61046927SAndroid Build Coastguard Worker * there are multiple attributes packed into a single binding with
1804*61046927SAndroid Build Coastguard Worker * adjacent locations we'd still be DMAing them separately. This is not
1805*61046927SAndroid Build Coastguard Worker * great so the DMA setup should be smarter and could do with some
1806*61046927SAndroid Build Coastguard Worker * optimization.
1807*61046927SAndroid Build Coastguard Worker */
1808*61046927SAndroid Build Coastguard Worker
1809*61046927SAndroid Build Coastguard Worker *dma_desc = (struct pvr_pds_vertex_dma){ 0 };
1810*61046927SAndroid Build Coastguard Worker
1811*61046927SAndroid Build Coastguard Worker /* In relation to the Vulkan spec. 22.4. Vertex Input Address Calculation
1812*61046927SAndroid Build Coastguard Worker * this corresponds to `attribDesc.offset`.
1813*61046927SAndroid Build Coastguard Worker * The PDS program doesn't do anything with it but just save it in the
1814*61046927SAndroid Build Coastguard Worker * PDS program entry.
1815*61046927SAndroid Build Coastguard Worker */
1816*61046927SAndroid Build Coastguard Worker dma_desc->offset = attribute->offset;
1817*61046927SAndroid Build Coastguard Worker
1818*61046927SAndroid Build Coastguard Worker /* In relation to the Vulkan spec. 22.4. Vertex Input Address Calculation
1819*61046927SAndroid Build Coastguard Worker * this corresponds to `bindingDesc.stride`.
1820*61046927SAndroid Build Coastguard Worker * The PDS program will calculate the `effectiveVertexOffset` with this
1821*61046927SAndroid Build Coastguard Worker * and add it to the address provided in the patched data segment.
1822*61046927SAndroid Build Coastguard Worker */
1823*61046927SAndroid Build Coastguard Worker dma_desc->stride = binding->stride;
1824*61046927SAndroid Build Coastguard Worker
1825*61046927SAndroid Build Coastguard Worker if (binding->inputRate == VK_VERTEX_INPUT_RATE_INSTANCE)
1826*61046927SAndroid Build Coastguard Worker dma_desc->flags = PVR_PDS_VERTEX_DMA_FLAGS_INSTANCE_RATE;
1827*61046927SAndroid Build Coastguard Worker else
1828*61046927SAndroid Build Coastguard Worker dma_desc->flags = 0;
1829*61046927SAndroid Build Coastguard Worker
1830*61046927SAndroid Build Coastguard Worker /* Size to DMA per vertex attribute. Used to setup src3 in the DDMAD. */
1831*61046927SAndroid Build Coastguard Worker assert(fmt_description->block.bits != 0); /* Likely an unsupported fmt. */
1832*61046927SAndroid Build Coastguard Worker dma_desc->size_in_dwords = fmt_description->block.bits / 32;
1833*61046927SAndroid Build Coastguard Worker
1834*61046927SAndroid Build Coastguard Worker /* Vtxin reg offset to start DMAing into. */
1835*61046927SAndroid Build Coastguard Worker dma_desc->destination = vtxin_reg_offset;
1836*61046927SAndroid Build Coastguard Worker
1837*61046927SAndroid Build Coastguard Worker /* Will be used by the driver to figure out buffer address to patch in the
1838*61046927SAndroid Build Coastguard Worker * data section. I.e. which binding we should DMA from.
1839*61046927SAndroid Build Coastguard Worker */
1840*61046927SAndroid Build Coastguard Worker dma_desc->binding_index = attribute->binding;
1841*61046927SAndroid Build Coastguard Worker
1842*61046927SAndroid Build Coastguard Worker /* We don't currently support VK_EXT_vertex_attribute_divisor so no
1843*61046927SAndroid Build Coastguard Worker * repeating of instance-rate vertex attributes needed. We should always
1844*61046927SAndroid Build Coastguard Worker * move on to the next vertex attribute.
1845*61046927SAndroid Build Coastguard Worker */
1846*61046927SAndroid Build Coastguard Worker dma_desc->divisor = 1;
1847*61046927SAndroid Build Coastguard Worker
1848*61046927SAndroid Build Coastguard Worker /* Will be used to generate PDS code that takes care of robust buffer
1849*61046927SAndroid Build Coastguard Worker * access, and later on by the driver to write the correct robustness
1850*61046927SAndroid Build Coastguard Worker * buffer address to DMA the fallback values from.
1851*61046927SAndroid Build Coastguard Worker */
1852*61046927SAndroid Build Coastguard Worker dma_desc->robustness_buffer_offset =
1853*61046927SAndroid Build Coastguard Worker pvr_get_robustness_buffer_format_offset(attribute->format);
1854*61046927SAndroid Build Coastguard Worker
1855*61046927SAndroid Build Coastguard Worker /* Used by later on by the driver to figure out if the buffer is being
1856*61046927SAndroid Build Coastguard Worker * accessed out of bounds, for robust buffer access.
1857*61046927SAndroid Build Coastguard Worker */
1858*61046927SAndroid Build Coastguard Worker dma_desc->component_size_in_bytes =
1859*61046927SAndroid Build Coastguard Worker fmt_description->block.bits / fmt_description->nr_channels / 8;
1860*61046927SAndroid Build Coastguard Worker
1861*61046927SAndroid Build Coastguard Worker dma_count++;
1862*61046927SAndroid Build Coastguard Worker };
1863*61046927SAndroid Build Coastguard Worker
1864*61046927SAndroid Build Coastguard Worker *vertex_input_layout_out = build_data;
1865*61046927SAndroid Build Coastguard Worker *num_vertex_input_regs_out = next_reg_offset;
1866*61046927SAndroid Build Coastguard Worker *dma_count_out = dma_count;
1867*61046927SAndroid Build Coastguard Worker }
1868*61046927SAndroid Build Coastguard Worker
pvr_graphics_pipeline_alloc_vertex_special_vars(unsigned * num_vertex_input_regs,struct pvr_vertex_special_vars * special_vars_layout_out)1869*61046927SAndroid Build Coastguard Worker static void pvr_graphics_pipeline_alloc_vertex_special_vars(
1870*61046927SAndroid Build Coastguard Worker unsigned *num_vertex_input_regs,
1871*61046927SAndroid Build Coastguard Worker struct pvr_vertex_special_vars *special_vars_layout_out)
1872*61046927SAndroid Build Coastguard Worker {
1873*61046927SAndroid Build Coastguard Worker unsigned next_free_reg = *num_vertex_input_regs;
1874*61046927SAndroid Build Coastguard Worker struct pvr_vertex_special_vars layout;
1875*61046927SAndroid Build Coastguard Worker
1876*61046927SAndroid Build Coastguard Worker /* We don't support VK_KHR_shader_draw_parameters or Vulkan 1.1 so no
1877*61046927SAndroid Build Coastguard Worker * BaseInstance, BaseVertex, DrawIndex.
1878*61046927SAndroid Build Coastguard Worker */
1879*61046927SAndroid Build Coastguard Worker
1880*61046927SAndroid Build Coastguard Worker /* TODO: The shader might not necessarily be using this so we'd just be
1881*61046927SAndroid Build Coastguard Worker * wasting regs. Get the info from the compiler about whether or not the
1882*61046927SAndroid Build Coastguard Worker * shader uses them and allocate them accordingly. For now we'll set them up
1883*61046927SAndroid Build Coastguard Worker * regardless.
1884*61046927SAndroid Build Coastguard Worker */
1885*61046927SAndroid Build Coastguard Worker
1886*61046927SAndroid Build Coastguard Worker layout.vertex_id_offset = (int16_t)next_free_reg;
1887*61046927SAndroid Build Coastguard Worker next_free_reg++;
1888*61046927SAndroid Build Coastguard Worker
1889*61046927SAndroid Build Coastguard Worker layout.instance_id_offset = (int16_t)next_free_reg;
1890*61046927SAndroid Build Coastguard Worker next_free_reg++;
1891*61046927SAndroid Build Coastguard Worker
1892*61046927SAndroid Build Coastguard Worker *num_vertex_input_regs = next_free_reg;
1893*61046927SAndroid Build Coastguard Worker *special_vars_layout_out = layout;
1894*61046927SAndroid Build Coastguard Worker }
1895*61046927SAndroid Build Coastguard Worker
1896*61046927SAndroid Build Coastguard Worker /* Compiles and uploads shaders and PDS programs. */
1897*61046927SAndroid Build Coastguard Worker static VkResult
pvr_graphics_pipeline_compile(struct pvr_device * const device,struct vk_pipeline_cache * cache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * const allocator,struct pvr_graphics_pipeline * const gfx_pipeline)1898*61046927SAndroid Build Coastguard Worker pvr_graphics_pipeline_compile(struct pvr_device *const device,
1899*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
1900*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo,
1901*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *const allocator,
1902*61046927SAndroid Build Coastguard Worker struct pvr_graphics_pipeline *const gfx_pipeline)
1903*61046927SAndroid Build Coastguard Worker {
1904*61046927SAndroid Build Coastguard Worker /* FIXME: Remove this hard coding. */
1905*61046927SAndroid Build Coastguard Worker struct pvr_explicit_constant_usage vert_explicit_const_usage = {
1906*61046927SAndroid Build Coastguard Worker .start_offset = 16,
1907*61046927SAndroid Build Coastguard Worker };
1908*61046927SAndroid Build Coastguard Worker struct pvr_explicit_constant_usage frag_explicit_const_usage = {
1909*61046927SAndroid Build Coastguard Worker .start_offset = 0,
1910*61046927SAndroid Build Coastguard Worker };
1911*61046927SAndroid Build Coastguard Worker static uint32_t hard_code_pipeline_n = 0;
1912*61046927SAndroid Build Coastguard Worker
1913*61046927SAndroid Build Coastguard Worker struct pvr_pipeline_layout *layout = gfx_pipeline->base.layout;
1914*61046927SAndroid Build Coastguard Worker struct pvr_sh_reg_layout *sh_reg_layout_vert =
1915*61046927SAndroid Build Coastguard Worker &layout->sh_reg_layout_per_stage[PVR_STAGE_ALLOCATION_VERTEX_GEOMETRY];
1916*61046927SAndroid Build Coastguard Worker struct pvr_sh_reg_layout *sh_reg_layout_frag =
1917*61046927SAndroid Build Coastguard Worker &layout->sh_reg_layout_per_stage[PVR_STAGE_ALLOCATION_FRAGMENT];
1918*61046927SAndroid Build Coastguard Worker const VkPipelineVertexInputStateCreateInfo *const vertex_input_state =
1919*61046927SAndroid Build Coastguard Worker pCreateInfo->pVertexInputState;
1920*61046927SAndroid Build Coastguard Worker const uint32_t cache_line_size =
1921*61046927SAndroid Build Coastguard Worker rogue_get_slc_cache_line_size(&device->pdevice->dev_info);
1922*61046927SAndroid Build Coastguard Worker struct rogue_compiler *compiler = device->pdevice->compiler;
1923*61046927SAndroid Build Coastguard Worker struct rogue_build_ctx *ctx;
1924*61046927SAndroid Build Coastguard Worker VkResult result;
1925*61046927SAndroid Build Coastguard Worker
1926*61046927SAndroid Build Coastguard Worker const bool old_path = pvr_has_hard_coded_shaders(&device->pdevice->dev_info);
1927*61046927SAndroid Build Coastguard Worker
1928*61046927SAndroid Build Coastguard Worker /* Vars needed for the new path. */
1929*61046927SAndroid Build Coastguard Worker struct pvr_pds_vertex_dma vtx_dma_descriptions[PVR_MAX_VERTEX_ATTRIB_DMAS];
1930*61046927SAndroid Build Coastguard Worker uint32_t vtx_dma_count = 0;
1931*61046927SAndroid Build Coastguard Worker rogue_vertex_inputs *vertex_input_layout;
1932*61046927SAndroid Build Coastguard Worker unsigned *vertex_input_reg_count;
1933*61046927SAndroid Build Coastguard Worker
1934*61046927SAndroid Build Coastguard Worker /* TODO: The compiler should be making use of this to determine where
1935*61046927SAndroid Build Coastguard Worker * specific special variables are located in the vtxin reg set.
1936*61046927SAndroid Build Coastguard Worker */
1937*61046927SAndroid Build Coastguard Worker struct pvr_vertex_special_vars special_vars_layout = { 0 };
1938*61046927SAndroid Build Coastguard Worker
1939*61046927SAndroid Build Coastguard Worker uint32_t sh_count[PVR_STAGE_ALLOCATION_COUNT] = { 0 };
1940*61046927SAndroid Build Coastguard Worker
1941*61046927SAndroid Build Coastguard Worker /* Setup shared build context. */
1942*61046927SAndroid Build Coastguard Worker ctx = rogue_build_context_create(compiler, layout);
1943*61046927SAndroid Build Coastguard Worker if (!ctx)
1944*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1945*61046927SAndroid Build Coastguard Worker
1946*61046927SAndroid Build Coastguard Worker vertex_input_layout = &ctx->stage_data.vs.inputs;
1947*61046927SAndroid Build Coastguard Worker vertex_input_reg_count = &ctx->stage_data.vs.num_vertex_input_regs;
1948*61046927SAndroid Build Coastguard Worker
1949*61046927SAndroid Build Coastguard Worker if (!old_path) {
1950*61046927SAndroid Build Coastguard Worker pvr_graphics_pipeline_alloc_vertex_inputs(vertex_input_state,
1951*61046927SAndroid Build Coastguard Worker vertex_input_layout,
1952*61046927SAndroid Build Coastguard Worker vertex_input_reg_count,
1953*61046927SAndroid Build Coastguard Worker &vtx_dma_descriptions,
1954*61046927SAndroid Build Coastguard Worker &vtx_dma_count);
1955*61046927SAndroid Build Coastguard Worker
1956*61046927SAndroid Build Coastguard Worker pvr_graphics_pipeline_alloc_vertex_special_vars(vertex_input_reg_count,
1957*61046927SAndroid Build Coastguard Worker &special_vars_layout);
1958*61046927SAndroid Build Coastguard Worker
1959*61046927SAndroid Build Coastguard Worker for (enum pvr_stage_allocation pvr_stage =
1960*61046927SAndroid Build Coastguard Worker PVR_STAGE_ALLOCATION_VERTEX_GEOMETRY;
1961*61046927SAndroid Build Coastguard Worker pvr_stage < PVR_STAGE_ALLOCATION_COMPUTE;
1962*61046927SAndroid Build Coastguard Worker ++pvr_stage)
1963*61046927SAndroid Build Coastguard Worker sh_count[pvr_stage] = pvr_pipeline_alloc_shareds(
1964*61046927SAndroid Build Coastguard Worker device,
1965*61046927SAndroid Build Coastguard Worker layout,
1966*61046927SAndroid Build Coastguard Worker pvr_stage,
1967*61046927SAndroid Build Coastguard Worker &layout->sh_reg_layout_per_stage[pvr_stage]);
1968*61046927SAndroid Build Coastguard Worker }
1969*61046927SAndroid Build Coastguard Worker
1970*61046927SAndroid Build Coastguard Worker /* NIR middle-end translation. */
1971*61046927SAndroid Build Coastguard Worker for (gl_shader_stage stage = MESA_SHADER_FRAGMENT; stage > MESA_SHADER_NONE;
1972*61046927SAndroid Build Coastguard Worker stage--) {
1973*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo *create_info;
1974*61046927SAndroid Build Coastguard Worker size_t stage_index = gfx_pipeline->stage_indices[stage];
1975*61046927SAndroid Build Coastguard Worker
1976*61046927SAndroid Build Coastguard Worker if (pvr_has_hard_coded_shaders(&device->pdevice->dev_info)) {
1977*61046927SAndroid Build Coastguard Worker if (pvr_hard_code_graphics_get_flags(&device->pdevice->dev_info) &
1978*61046927SAndroid Build Coastguard Worker BITFIELD_BIT(stage)) {
1979*61046927SAndroid Build Coastguard Worker continue;
1980*61046927SAndroid Build Coastguard Worker }
1981*61046927SAndroid Build Coastguard Worker }
1982*61046927SAndroid Build Coastguard Worker
1983*61046927SAndroid Build Coastguard Worker /* Skip unused/inactive stages. */
1984*61046927SAndroid Build Coastguard Worker if (stage_index == ~0)
1985*61046927SAndroid Build Coastguard Worker continue;
1986*61046927SAndroid Build Coastguard Worker
1987*61046927SAndroid Build Coastguard Worker create_info = &pCreateInfo->pStages[stage_index];
1988*61046927SAndroid Build Coastguard Worker
1989*61046927SAndroid Build Coastguard Worker /* SPIR-V to NIR. */
1990*61046927SAndroid Build Coastguard Worker ctx->nir[stage] = pvr_spirv_to_nir(ctx, stage, create_info);
1991*61046927SAndroid Build Coastguard Worker if (!ctx->nir[stage]) {
1992*61046927SAndroid Build Coastguard Worker ralloc_free(ctx);
1993*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1994*61046927SAndroid Build Coastguard Worker }
1995*61046927SAndroid Build Coastguard Worker }
1996*61046927SAndroid Build Coastguard Worker
1997*61046927SAndroid Build Coastguard Worker /* Pre-back-end analysis and optimization, driver data extraction. */
1998*61046927SAndroid Build Coastguard Worker /* TODO: Analyze and cull unused I/O between stages. */
1999*61046927SAndroid Build Coastguard Worker /* TODO: Allocate UBOs between stages;
2000*61046927SAndroid Build Coastguard Worker * pipeline->layout->set_{count,layout}.
2001*61046927SAndroid Build Coastguard Worker */
2002*61046927SAndroid Build Coastguard Worker
2003*61046927SAndroid Build Coastguard Worker /* Back-end translation. */
2004*61046927SAndroid Build Coastguard Worker for (gl_shader_stage stage = MESA_SHADER_FRAGMENT; stage > MESA_SHADER_NONE;
2005*61046927SAndroid Build Coastguard Worker stage--) {
2006*61046927SAndroid Build Coastguard Worker if (pvr_has_hard_coded_shaders(&device->pdevice->dev_info) &&
2007*61046927SAndroid Build Coastguard Worker pvr_hard_code_graphics_get_flags(&device->pdevice->dev_info) &
2008*61046927SAndroid Build Coastguard Worker BITFIELD_BIT(stage)) {
2009*61046927SAndroid Build Coastguard Worker const struct pvr_device_info *const dev_info =
2010*61046927SAndroid Build Coastguard Worker &device->pdevice->dev_info;
2011*61046927SAndroid Build Coastguard Worker struct pvr_explicit_constant_usage *explicit_const_usage;
2012*61046927SAndroid Build Coastguard Worker
2013*61046927SAndroid Build Coastguard Worker switch (stage) {
2014*61046927SAndroid Build Coastguard Worker case MESA_SHADER_VERTEX:
2015*61046927SAndroid Build Coastguard Worker explicit_const_usage = &vert_explicit_const_usage;
2016*61046927SAndroid Build Coastguard Worker break;
2017*61046927SAndroid Build Coastguard Worker
2018*61046927SAndroid Build Coastguard Worker case MESA_SHADER_FRAGMENT:
2019*61046927SAndroid Build Coastguard Worker explicit_const_usage = &frag_explicit_const_usage;
2020*61046927SAndroid Build Coastguard Worker break;
2021*61046927SAndroid Build Coastguard Worker
2022*61046927SAndroid Build Coastguard Worker default:
2023*61046927SAndroid Build Coastguard Worker unreachable("Unsupported stage.");
2024*61046927SAndroid Build Coastguard Worker }
2025*61046927SAndroid Build Coastguard Worker
2026*61046927SAndroid Build Coastguard Worker pvr_hard_code_graphics_shader(dev_info,
2027*61046927SAndroid Build Coastguard Worker hard_code_pipeline_n,
2028*61046927SAndroid Build Coastguard Worker stage,
2029*61046927SAndroid Build Coastguard Worker &ctx->binary[stage]);
2030*61046927SAndroid Build Coastguard Worker
2031*61046927SAndroid Build Coastguard Worker pvr_hard_code_graphics_get_build_info(dev_info,
2032*61046927SAndroid Build Coastguard Worker hard_code_pipeline_n,
2033*61046927SAndroid Build Coastguard Worker stage,
2034*61046927SAndroid Build Coastguard Worker &ctx->common_data[stage],
2035*61046927SAndroid Build Coastguard Worker &ctx->stage_data,
2036*61046927SAndroid Build Coastguard Worker explicit_const_usage);
2037*61046927SAndroid Build Coastguard Worker
2038*61046927SAndroid Build Coastguard Worker continue;
2039*61046927SAndroid Build Coastguard Worker }
2040*61046927SAndroid Build Coastguard Worker
2041*61046927SAndroid Build Coastguard Worker if (!ctx->nir[stage])
2042*61046927SAndroid Build Coastguard Worker continue;
2043*61046927SAndroid Build Coastguard Worker
2044*61046927SAndroid Build Coastguard Worker ctx->rogue[stage] = pvr_nir_to_rogue(ctx, ctx->nir[stage]);
2045*61046927SAndroid Build Coastguard Worker if (!ctx->rogue[stage]) {
2046*61046927SAndroid Build Coastguard Worker ralloc_free(ctx);
2047*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2048*61046927SAndroid Build Coastguard Worker }
2049*61046927SAndroid Build Coastguard Worker
2050*61046927SAndroid Build Coastguard Worker pvr_rogue_to_binary(ctx, ctx->rogue[stage], &ctx->binary[stage]);
2051*61046927SAndroid Build Coastguard Worker if (!ctx->binary[stage].size) {
2052*61046927SAndroid Build Coastguard Worker ralloc_free(ctx);
2053*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2054*61046927SAndroid Build Coastguard Worker }
2055*61046927SAndroid Build Coastguard Worker }
2056*61046927SAndroid Build Coastguard Worker
2057*61046927SAndroid Build Coastguard Worker if (pvr_has_hard_coded_shaders(&device->pdevice->dev_info) &&
2058*61046927SAndroid Build Coastguard Worker pvr_hard_code_graphics_get_flags(&device->pdevice->dev_info) &
2059*61046927SAndroid Build Coastguard Worker BITFIELD_BIT(MESA_SHADER_VERTEX)) {
2060*61046927SAndroid Build Coastguard Worker pvr_hard_code_graphics_vertex_state(&device->pdevice->dev_info,
2061*61046927SAndroid Build Coastguard Worker hard_code_pipeline_n,
2062*61046927SAndroid Build Coastguard Worker &gfx_pipeline->shader_state.vertex);
2063*61046927SAndroid Build Coastguard Worker } else {
2064*61046927SAndroid Build Coastguard Worker pvr_vertex_state_init(gfx_pipeline,
2065*61046927SAndroid Build Coastguard Worker &ctx->common_data[MESA_SHADER_VERTEX],
2066*61046927SAndroid Build Coastguard Worker *vertex_input_reg_count,
2067*61046927SAndroid Build Coastguard Worker &ctx->stage_data.vs);
2068*61046927SAndroid Build Coastguard Worker
2069*61046927SAndroid Build Coastguard Worker if (!old_path) {
2070*61046927SAndroid Build Coastguard Worker struct pvr_vertex_shader_state *vertex_state =
2071*61046927SAndroid Build Coastguard Worker &gfx_pipeline->shader_state.vertex;
2072*61046927SAndroid Build Coastguard Worker
2073*61046927SAndroid Build Coastguard Worker /* FIXME: For now we just overwrite it but the compiler shouldn't be
2074*61046927SAndroid Build Coastguard Worker * returning the sh count since the driver is in charge of allocating
2075*61046927SAndroid Build Coastguard Worker * them.
2076*61046927SAndroid Build Coastguard Worker */
2077*61046927SAndroid Build Coastguard Worker vertex_state->stage_state.const_shared_reg_count =
2078*61046927SAndroid Build Coastguard Worker sh_count[PVR_STAGE_ALLOCATION_VERTEX_GEOMETRY];
2079*61046927SAndroid Build Coastguard Worker
2080*61046927SAndroid Build Coastguard Worker gfx_pipeline->shader_state.vertex.vertex_input_size =
2081*61046927SAndroid Build Coastguard Worker ctx->stage_data.vs.num_vertex_input_regs;
2082*61046927SAndroid Build Coastguard Worker }
2083*61046927SAndroid Build Coastguard Worker }
2084*61046927SAndroid Build Coastguard Worker
2085*61046927SAndroid Build Coastguard Worker result =
2086*61046927SAndroid Build Coastguard Worker pvr_gpu_upload_usc(device,
2087*61046927SAndroid Build Coastguard Worker util_dynarray_begin(&ctx->binary[MESA_SHADER_VERTEX]),
2088*61046927SAndroid Build Coastguard Worker ctx->binary[MESA_SHADER_VERTEX].size,
2089*61046927SAndroid Build Coastguard Worker cache_line_size,
2090*61046927SAndroid Build Coastguard Worker &gfx_pipeline->shader_state.vertex.bo);
2091*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2092*61046927SAndroid Build Coastguard Worker goto err_free_build_context;
2093*61046927SAndroid Build Coastguard Worker
2094*61046927SAndroid Build Coastguard Worker if (ctx->nir[MESA_SHADER_FRAGMENT]) {
2095*61046927SAndroid Build Coastguard Worker struct pvr_fragment_shader_state *fragment_state =
2096*61046927SAndroid Build Coastguard Worker &gfx_pipeline->shader_state.fragment;
2097*61046927SAndroid Build Coastguard Worker
2098*61046927SAndroid Build Coastguard Worker if (pvr_has_hard_coded_shaders(&device->pdevice->dev_info) &&
2099*61046927SAndroid Build Coastguard Worker pvr_hard_code_graphics_get_flags(&device->pdevice->dev_info) &
2100*61046927SAndroid Build Coastguard Worker BITFIELD_BIT(MESA_SHADER_FRAGMENT)) {
2101*61046927SAndroid Build Coastguard Worker pvr_hard_code_graphics_fragment_state(
2102*61046927SAndroid Build Coastguard Worker &device->pdevice->dev_info,
2103*61046927SAndroid Build Coastguard Worker hard_code_pipeline_n,
2104*61046927SAndroid Build Coastguard Worker &gfx_pipeline->shader_state.fragment);
2105*61046927SAndroid Build Coastguard Worker } else {
2106*61046927SAndroid Build Coastguard Worker pvr_fragment_state_init(gfx_pipeline,
2107*61046927SAndroid Build Coastguard Worker &ctx->common_data[MESA_SHADER_FRAGMENT]);
2108*61046927SAndroid Build Coastguard Worker
2109*61046927SAndroid Build Coastguard Worker if (!old_path) {
2110*61046927SAndroid Build Coastguard Worker /* FIXME: For now we just overwrite it but the compiler shouldn't be
2111*61046927SAndroid Build Coastguard Worker * returning the sh count since the driver is in charge of
2112*61046927SAndroid Build Coastguard Worker * allocating them.
2113*61046927SAndroid Build Coastguard Worker */
2114*61046927SAndroid Build Coastguard Worker fragment_state->stage_state.const_shared_reg_count =
2115*61046927SAndroid Build Coastguard Worker sh_count[PVR_STAGE_ALLOCATION_FRAGMENT];
2116*61046927SAndroid Build Coastguard Worker }
2117*61046927SAndroid Build Coastguard Worker }
2118*61046927SAndroid Build Coastguard Worker
2119*61046927SAndroid Build Coastguard Worker result = pvr_gpu_upload_usc(
2120*61046927SAndroid Build Coastguard Worker device,
2121*61046927SAndroid Build Coastguard Worker util_dynarray_begin(&ctx->binary[MESA_SHADER_FRAGMENT]),
2122*61046927SAndroid Build Coastguard Worker ctx->binary[MESA_SHADER_FRAGMENT].size,
2123*61046927SAndroid Build Coastguard Worker cache_line_size,
2124*61046927SAndroid Build Coastguard Worker &gfx_pipeline->shader_state.fragment.bo);
2125*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2126*61046927SAndroid Build Coastguard Worker goto err_free_vertex_bo;
2127*61046927SAndroid Build Coastguard Worker
2128*61046927SAndroid Build Coastguard Worker /* TODO: powervr has an optimization where it attempts to recompile
2129*61046927SAndroid Build Coastguard Worker * shaders. See PipelineCompileNoISPFeedbackFragmentStage. Unimplemented
2130*61046927SAndroid Build Coastguard Worker * since in our case the optimization doesn't happen.
2131*61046927SAndroid Build Coastguard Worker */
2132*61046927SAndroid Build Coastguard Worker
2133*61046927SAndroid Build Coastguard Worker result = pvr_pds_coeff_program_create_and_upload(
2134*61046927SAndroid Build Coastguard Worker device,
2135*61046927SAndroid Build Coastguard Worker allocator,
2136*61046927SAndroid Build Coastguard Worker ctx->stage_data.fs.iterator_args.fpu_iterators,
2137*61046927SAndroid Build Coastguard Worker ctx->stage_data.fs.iterator_args.num_fpu_iterators,
2138*61046927SAndroid Build Coastguard Worker ctx->stage_data.fs.iterator_args.destination,
2139*61046927SAndroid Build Coastguard Worker &fragment_state->pds_coeff_program,
2140*61046927SAndroid Build Coastguard Worker &fragment_state->stage_state.pds_temps_count);
2141*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2142*61046927SAndroid Build Coastguard Worker goto err_free_fragment_bo;
2143*61046927SAndroid Build Coastguard Worker
2144*61046927SAndroid Build Coastguard Worker result = pvr_pds_fragment_program_create_and_upload(
2145*61046927SAndroid Build Coastguard Worker device,
2146*61046927SAndroid Build Coastguard Worker allocator,
2147*61046927SAndroid Build Coastguard Worker gfx_pipeline->shader_state.fragment.bo,
2148*61046927SAndroid Build Coastguard Worker ctx->common_data[MESA_SHADER_FRAGMENT].temps,
2149*61046927SAndroid Build Coastguard Worker ctx->stage_data.fs.msaa_mode,
2150*61046927SAndroid Build Coastguard Worker ctx->stage_data.fs.phas,
2151*61046927SAndroid Build Coastguard Worker &fragment_state->pds_fragment_program);
2152*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2153*61046927SAndroid Build Coastguard Worker goto err_free_coeff_program;
2154*61046927SAndroid Build Coastguard Worker
2155*61046927SAndroid Build Coastguard Worker /* FIXME: For now we pass in the same explicit_const_usage since it
2156*61046927SAndroid Build Coastguard Worker * contains all invalid entries. Fix this by hooking it up to the
2157*61046927SAndroid Build Coastguard Worker * compiler.
2158*61046927SAndroid Build Coastguard Worker */
2159*61046927SAndroid Build Coastguard Worker result = pvr_pds_descriptor_program_create_and_upload(
2160*61046927SAndroid Build Coastguard Worker device,
2161*61046927SAndroid Build Coastguard Worker allocator,
2162*61046927SAndroid Build Coastguard Worker &ctx->common_data[MESA_SHADER_FRAGMENT].compile_time_consts_data,
2163*61046927SAndroid Build Coastguard Worker &ctx->common_data[MESA_SHADER_FRAGMENT].ubo_data,
2164*61046927SAndroid Build Coastguard Worker &frag_explicit_const_usage,
2165*61046927SAndroid Build Coastguard Worker layout,
2166*61046927SAndroid Build Coastguard Worker PVR_STAGE_ALLOCATION_FRAGMENT,
2167*61046927SAndroid Build Coastguard Worker sh_reg_layout_frag,
2168*61046927SAndroid Build Coastguard Worker &fragment_state->descriptor_state);
2169*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2170*61046927SAndroid Build Coastguard Worker goto err_free_frag_program;
2171*61046927SAndroid Build Coastguard Worker
2172*61046927SAndroid Build Coastguard Worker /* If not, we need to MAX2() and set
2173*61046927SAndroid Build Coastguard Worker * `fragment_state->stage_state.pds_temps_count` appropriately.
2174*61046927SAndroid Build Coastguard Worker */
2175*61046927SAndroid Build Coastguard Worker assert(fragment_state->descriptor_state.pds_info.temps_required == 0);
2176*61046927SAndroid Build Coastguard Worker }
2177*61046927SAndroid Build Coastguard Worker
2178*61046927SAndroid Build Coastguard Worker result = pvr_pds_vertex_attrib_programs_create_and_upload(
2179*61046927SAndroid Build Coastguard Worker device,
2180*61046927SAndroid Build Coastguard Worker allocator,
2181*61046927SAndroid Build Coastguard Worker vertex_input_state,
2182*61046927SAndroid Build Coastguard Worker ctx->common_data[MESA_SHADER_VERTEX].temps,
2183*61046927SAndroid Build Coastguard Worker &ctx->stage_data.vs,
2184*61046927SAndroid Build Coastguard Worker vtx_dma_descriptions,
2185*61046927SAndroid Build Coastguard Worker vtx_dma_count,
2186*61046927SAndroid Build Coastguard Worker &special_vars_layout,
2187*61046927SAndroid Build Coastguard Worker &gfx_pipeline->shader_state.vertex.pds_attrib_programs);
2188*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2189*61046927SAndroid Build Coastguard Worker goto err_free_frag_descriptor_program;
2190*61046927SAndroid Build Coastguard Worker
2191*61046927SAndroid Build Coastguard Worker result = pvr_pds_descriptor_program_create_and_upload(
2192*61046927SAndroid Build Coastguard Worker device,
2193*61046927SAndroid Build Coastguard Worker allocator,
2194*61046927SAndroid Build Coastguard Worker &ctx->common_data[MESA_SHADER_VERTEX].compile_time_consts_data,
2195*61046927SAndroid Build Coastguard Worker &ctx->common_data[MESA_SHADER_VERTEX].ubo_data,
2196*61046927SAndroid Build Coastguard Worker &vert_explicit_const_usage,
2197*61046927SAndroid Build Coastguard Worker layout,
2198*61046927SAndroid Build Coastguard Worker PVR_STAGE_ALLOCATION_VERTEX_GEOMETRY,
2199*61046927SAndroid Build Coastguard Worker sh_reg_layout_vert,
2200*61046927SAndroid Build Coastguard Worker &gfx_pipeline->shader_state.vertex.descriptor_state);
2201*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2202*61046927SAndroid Build Coastguard Worker goto err_free_vertex_attrib_program;
2203*61046927SAndroid Build Coastguard Worker
2204*61046927SAndroid Build Coastguard Worker /* FIXME: When the temp_buffer_total_size is non-zero we need to allocate a
2205*61046927SAndroid Build Coastguard Worker * scratch buffer for both vertex and fragment stage.
2206*61046927SAndroid Build Coastguard Worker * Figure out the best place to do this.
2207*61046927SAndroid Build Coastguard Worker */
2208*61046927SAndroid Build Coastguard Worker /* assert(pvr_pds_descriptor_program_variables.temp_buff_total_size == 0); */
2209*61046927SAndroid Build Coastguard Worker /* TODO: Implement spilling with the above. */
2210*61046927SAndroid Build Coastguard Worker
2211*61046927SAndroid Build Coastguard Worker ralloc_free(ctx);
2212*61046927SAndroid Build Coastguard Worker
2213*61046927SAndroid Build Coastguard Worker hard_code_pipeline_n++;
2214*61046927SAndroid Build Coastguard Worker
2215*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
2216*61046927SAndroid Build Coastguard Worker
2217*61046927SAndroid Build Coastguard Worker err_free_vertex_attrib_program:
2218*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0;
2219*61046927SAndroid Build Coastguard Worker i < ARRAY_SIZE(gfx_pipeline->shader_state.vertex.pds_attrib_programs);
2220*61046927SAndroid Build Coastguard Worker i++) {
2221*61046927SAndroid Build Coastguard Worker struct pvr_pds_attrib_program *const attrib_program =
2222*61046927SAndroid Build Coastguard Worker &gfx_pipeline->shader_state.vertex.pds_attrib_programs[i];
2223*61046927SAndroid Build Coastguard Worker
2224*61046927SAndroid Build Coastguard Worker pvr_pds_vertex_attrib_program_destroy(device, allocator, attrib_program);
2225*61046927SAndroid Build Coastguard Worker }
2226*61046927SAndroid Build Coastguard Worker err_free_frag_descriptor_program:
2227*61046927SAndroid Build Coastguard Worker pvr_pds_descriptor_program_destroy(
2228*61046927SAndroid Build Coastguard Worker device,
2229*61046927SAndroid Build Coastguard Worker allocator,
2230*61046927SAndroid Build Coastguard Worker &gfx_pipeline->shader_state.fragment.descriptor_state);
2231*61046927SAndroid Build Coastguard Worker err_free_frag_program:
2232*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(
2233*61046927SAndroid Build Coastguard Worker gfx_pipeline->shader_state.fragment.pds_fragment_program.pvr_bo);
2234*61046927SAndroid Build Coastguard Worker err_free_coeff_program:
2235*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(
2236*61046927SAndroid Build Coastguard Worker gfx_pipeline->shader_state.fragment.pds_coeff_program.pvr_bo);
2237*61046927SAndroid Build Coastguard Worker err_free_fragment_bo:
2238*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(gfx_pipeline->shader_state.fragment.bo);
2239*61046927SAndroid Build Coastguard Worker err_free_vertex_bo:
2240*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(gfx_pipeline->shader_state.vertex.bo);
2241*61046927SAndroid Build Coastguard Worker err_free_build_context:
2242*61046927SAndroid Build Coastguard Worker ralloc_free(ctx);
2243*61046927SAndroid Build Coastguard Worker return result;
2244*61046927SAndroid Build Coastguard Worker }
2245*61046927SAndroid Build Coastguard Worker
2246*61046927SAndroid Build Coastguard Worker static struct vk_render_pass_state
pvr_create_renderpass_state(const VkGraphicsPipelineCreateInfo * const info)2247*61046927SAndroid Build Coastguard Worker pvr_create_renderpass_state(const VkGraphicsPipelineCreateInfo *const info)
2248*61046927SAndroid Build Coastguard Worker {
2249*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_render_pass, pass, info->renderPass);
2250*61046927SAndroid Build Coastguard Worker const struct pvr_render_subpass *const subpass =
2251*61046927SAndroid Build Coastguard Worker &pass->subpasses[info->subpass];
2252*61046927SAndroid Build Coastguard Worker
2253*61046927SAndroid Build Coastguard Worker enum vk_rp_attachment_flags attachments = 0;
2254*61046927SAndroid Build Coastguard Worker
2255*61046927SAndroid Build Coastguard Worker assert(info->subpass < pass->subpass_count);
2256*61046927SAndroid Build Coastguard Worker
2257*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < subpass->color_count; i++) {
2258*61046927SAndroid Build Coastguard Worker if (pass->attachments[subpass->color_attachments[i]].aspects)
2259*61046927SAndroid Build Coastguard Worker attachments |= MESA_VK_RP_ATTACHMENT_COLOR_0_BIT << i;
2260*61046927SAndroid Build Coastguard Worker }
2261*61046927SAndroid Build Coastguard Worker
2262*61046927SAndroid Build Coastguard Worker if (subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED) {
2263*61046927SAndroid Build Coastguard Worker VkImageAspectFlags ds_aspects =
2264*61046927SAndroid Build Coastguard Worker pass->attachments[subpass->depth_stencil_attachment].aspects;
2265*61046927SAndroid Build Coastguard Worker if (ds_aspects & VK_IMAGE_ASPECT_DEPTH_BIT)
2266*61046927SAndroid Build Coastguard Worker attachments |= MESA_VK_RP_ATTACHMENT_DEPTH_BIT;
2267*61046927SAndroid Build Coastguard Worker if (ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT)
2268*61046927SAndroid Build Coastguard Worker attachments |= MESA_VK_RP_ATTACHMENT_STENCIL_BIT;
2269*61046927SAndroid Build Coastguard Worker }
2270*61046927SAndroid Build Coastguard Worker
2271*61046927SAndroid Build Coastguard Worker return (struct vk_render_pass_state){
2272*61046927SAndroid Build Coastguard Worker .attachments = attachments,
2273*61046927SAndroid Build Coastguard Worker
2274*61046927SAndroid Build Coastguard Worker /* TODO: This is only needed for VK_KHR_create_renderpass2 (or core 1.2),
2275*61046927SAndroid Build Coastguard Worker * which is not currently supported.
2276*61046927SAndroid Build Coastguard Worker */
2277*61046927SAndroid Build Coastguard Worker .view_mask = 0,
2278*61046927SAndroid Build Coastguard Worker };
2279*61046927SAndroid Build Coastguard Worker }
2280*61046927SAndroid Build Coastguard Worker
2281*61046927SAndroid Build Coastguard Worker static VkResult
pvr_graphics_pipeline_init(struct pvr_device * device,struct vk_pipeline_cache * cache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * allocator,struct pvr_graphics_pipeline * gfx_pipeline)2282*61046927SAndroid Build Coastguard Worker pvr_graphics_pipeline_init(struct pvr_device *device,
2283*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
2284*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo,
2285*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *allocator,
2286*61046927SAndroid Build Coastguard Worker struct pvr_graphics_pipeline *gfx_pipeline)
2287*61046927SAndroid Build Coastguard Worker {
2288*61046927SAndroid Build Coastguard Worker struct vk_dynamic_graphics_state *const dynamic_state =
2289*61046927SAndroid Build Coastguard Worker &gfx_pipeline->dynamic_state;
2290*61046927SAndroid Build Coastguard Worker const struct vk_render_pass_state rp_state =
2291*61046927SAndroid Build Coastguard Worker pvr_create_renderpass_state(pCreateInfo);
2292*61046927SAndroid Build Coastguard Worker
2293*61046927SAndroid Build Coastguard Worker struct vk_graphics_pipeline_all_state all_state;
2294*61046927SAndroid Build Coastguard Worker struct vk_graphics_pipeline_state state = { 0 };
2295*61046927SAndroid Build Coastguard Worker
2296*61046927SAndroid Build Coastguard Worker VkResult result;
2297*61046927SAndroid Build Coastguard Worker
2298*61046927SAndroid Build Coastguard Worker pvr_pipeline_init(device, PVR_PIPELINE_TYPE_GRAPHICS, &gfx_pipeline->base);
2299*61046927SAndroid Build Coastguard Worker
2300*61046927SAndroid Build Coastguard Worker result = vk_graphics_pipeline_state_fill(&device->vk,
2301*61046927SAndroid Build Coastguard Worker &state,
2302*61046927SAndroid Build Coastguard Worker pCreateInfo,
2303*61046927SAndroid Build Coastguard Worker &rp_state,
2304*61046927SAndroid Build Coastguard Worker 0,
2305*61046927SAndroid Build Coastguard Worker &all_state,
2306*61046927SAndroid Build Coastguard Worker NULL,
2307*61046927SAndroid Build Coastguard Worker 0,
2308*61046927SAndroid Build Coastguard Worker NULL);
2309*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2310*61046927SAndroid Build Coastguard Worker goto err_pipeline_finish;
2311*61046927SAndroid Build Coastguard Worker
2312*61046927SAndroid Build Coastguard Worker vk_dynamic_graphics_state_init(dynamic_state);
2313*61046927SAndroid Build Coastguard Worker
2314*61046927SAndroid Build Coastguard Worker /* Load static state into base dynamic state holder. */
2315*61046927SAndroid Build Coastguard Worker vk_dynamic_graphics_state_fill(dynamic_state, &state);
2316*61046927SAndroid Build Coastguard Worker
2317*61046927SAndroid Build Coastguard Worker /* The value of ms.rasterization_samples is undefined when
2318*61046927SAndroid Build Coastguard Worker * rasterizer_discard_enable is set, but we need a specific value.
2319*61046927SAndroid Build Coastguard Worker * Fill that in here.
2320*61046927SAndroid Build Coastguard Worker */
2321*61046927SAndroid Build Coastguard Worker if (state.rs->rasterizer_discard_enable)
2322*61046927SAndroid Build Coastguard Worker dynamic_state->ms.rasterization_samples = VK_SAMPLE_COUNT_1_BIT;
2323*61046927SAndroid Build Coastguard Worker
2324*61046927SAndroid Build Coastguard Worker memset(gfx_pipeline->stage_indices, ~0, sizeof(gfx_pipeline->stage_indices));
2325*61046927SAndroid Build Coastguard Worker
2326*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
2327*61046927SAndroid Build Coastguard Worker VkShaderStageFlagBits vk_stage = pCreateInfo->pStages[i].stage;
2328*61046927SAndroid Build Coastguard Worker gl_shader_stage gl_stage = vk_to_mesa_shader_stage(vk_stage);
2329*61046927SAndroid Build Coastguard Worker /* From the Vulkan 1.2.192 spec for VkPipelineShaderStageCreateInfo:
2330*61046927SAndroid Build Coastguard Worker *
2331*61046927SAndroid Build Coastguard Worker * "stage must not be VK_SHADER_STAGE_ALL_GRAPHICS,
2332*61046927SAndroid Build Coastguard Worker * or VK_SHADER_STAGE_ALL."
2333*61046927SAndroid Build Coastguard Worker *
2334*61046927SAndroid Build Coastguard Worker * So we don't handle that.
2335*61046927SAndroid Build Coastguard Worker *
2336*61046927SAndroid Build Coastguard Worker * We also don't handle VK_SHADER_STAGE_TESSELLATION_* and
2337*61046927SAndroid Build Coastguard Worker * VK_SHADER_STAGE_GEOMETRY_BIT stages as 'tessellationShader' and
2338*61046927SAndroid Build Coastguard Worker * 'geometryShader' are set to false in the VkPhysicalDeviceFeatures
2339*61046927SAndroid Build Coastguard Worker * structure returned by the driver.
2340*61046927SAndroid Build Coastguard Worker */
2341*61046927SAndroid Build Coastguard Worker switch (pCreateInfo->pStages[i].stage) {
2342*61046927SAndroid Build Coastguard Worker case VK_SHADER_STAGE_VERTEX_BIT:
2343*61046927SAndroid Build Coastguard Worker case VK_SHADER_STAGE_FRAGMENT_BIT:
2344*61046927SAndroid Build Coastguard Worker gfx_pipeline->stage_indices[gl_stage] = i;
2345*61046927SAndroid Build Coastguard Worker break;
2346*61046927SAndroid Build Coastguard Worker default:
2347*61046927SAndroid Build Coastguard Worker unreachable("Unsupported stage.");
2348*61046927SAndroid Build Coastguard Worker }
2349*61046927SAndroid Build Coastguard Worker }
2350*61046927SAndroid Build Coastguard Worker
2351*61046927SAndroid Build Coastguard Worker gfx_pipeline->base.layout =
2352*61046927SAndroid Build Coastguard Worker pvr_pipeline_layout_from_handle(pCreateInfo->layout);
2353*61046927SAndroid Build Coastguard Worker
2354*61046927SAndroid Build Coastguard Worker /* Compiles and uploads shaders and PDS programs. */
2355*61046927SAndroid Build Coastguard Worker result = pvr_graphics_pipeline_compile(device,
2356*61046927SAndroid Build Coastguard Worker cache,
2357*61046927SAndroid Build Coastguard Worker pCreateInfo,
2358*61046927SAndroid Build Coastguard Worker allocator,
2359*61046927SAndroid Build Coastguard Worker gfx_pipeline);
2360*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2361*61046927SAndroid Build Coastguard Worker goto err_pipeline_finish;
2362*61046927SAndroid Build Coastguard Worker
2363*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
2364*61046927SAndroid Build Coastguard Worker
2365*61046927SAndroid Build Coastguard Worker err_pipeline_finish:
2366*61046927SAndroid Build Coastguard Worker pvr_pipeline_finish(&gfx_pipeline->base);
2367*61046927SAndroid Build Coastguard Worker
2368*61046927SAndroid Build Coastguard Worker return result;
2369*61046927SAndroid Build Coastguard Worker }
2370*61046927SAndroid Build Coastguard Worker
2371*61046927SAndroid Build Coastguard Worker /* If allocator == NULL, the internal one will be used. */
2372*61046927SAndroid Build Coastguard Worker static VkResult
pvr_graphics_pipeline_create(struct pvr_device * device,struct vk_pipeline_cache * cache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * allocator,VkPipeline * const pipeline_out)2373*61046927SAndroid Build Coastguard Worker pvr_graphics_pipeline_create(struct pvr_device *device,
2374*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
2375*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo,
2376*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *allocator,
2377*61046927SAndroid Build Coastguard Worker VkPipeline *const pipeline_out)
2378*61046927SAndroid Build Coastguard Worker {
2379*61046927SAndroid Build Coastguard Worker struct pvr_graphics_pipeline *gfx_pipeline;
2380*61046927SAndroid Build Coastguard Worker VkResult result;
2381*61046927SAndroid Build Coastguard Worker
2382*61046927SAndroid Build Coastguard Worker gfx_pipeline = vk_zalloc2(&device->vk.alloc,
2383*61046927SAndroid Build Coastguard Worker allocator,
2384*61046927SAndroid Build Coastguard Worker sizeof(*gfx_pipeline),
2385*61046927SAndroid Build Coastguard Worker 8,
2386*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
2387*61046927SAndroid Build Coastguard Worker if (!gfx_pipeline)
2388*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2389*61046927SAndroid Build Coastguard Worker
2390*61046927SAndroid Build Coastguard Worker /* Compiles and uploads shaders and PDS programs too. */
2391*61046927SAndroid Build Coastguard Worker result = pvr_graphics_pipeline_init(device,
2392*61046927SAndroid Build Coastguard Worker cache,
2393*61046927SAndroid Build Coastguard Worker pCreateInfo,
2394*61046927SAndroid Build Coastguard Worker allocator,
2395*61046927SAndroid Build Coastguard Worker gfx_pipeline);
2396*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
2397*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, gfx_pipeline);
2398*61046927SAndroid Build Coastguard Worker return result;
2399*61046927SAndroid Build Coastguard Worker }
2400*61046927SAndroid Build Coastguard Worker
2401*61046927SAndroid Build Coastguard Worker *pipeline_out = pvr_pipeline_to_handle(&gfx_pipeline->base);
2402*61046927SAndroid Build Coastguard Worker
2403*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
2404*61046927SAndroid Build Coastguard Worker }
2405*61046927SAndroid Build Coastguard Worker
2406*61046927SAndroid Build Coastguard Worker VkResult
pvr_CreateGraphicsPipelines(VkDevice _device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)2407*61046927SAndroid Build Coastguard Worker pvr_CreateGraphicsPipelines(VkDevice _device,
2408*61046927SAndroid Build Coastguard Worker VkPipelineCache pipelineCache,
2409*61046927SAndroid Build Coastguard Worker uint32_t createInfoCount,
2410*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfos,
2411*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
2412*61046927SAndroid Build Coastguard Worker VkPipeline *pPipelines)
2413*61046927SAndroid Build Coastguard Worker {
2414*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(vk_pipeline_cache, cache, pipelineCache);
2415*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_device, device, _device);
2416*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
2417*61046927SAndroid Build Coastguard Worker
2418*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < createInfoCount; i++) {
2419*61046927SAndroid Build Coastguard Worker const VkResult local_result =
2420*61046927SAndroid Build Coastguard Worker pvr_graphics_pipeline_create(device,
2421*61046927SAndroid Build Coastguard Worker cache,
2422*61046927SAndroid Build Coastguard Worker &pCreateInfos[i],
2423*61046927SAndroid Build Coastguard Worker pAllocator,
2424*61046927SAndroid Build Coastguard Worker &pPipelines[i]);
2425*61046927SAndroid Build Coastguard Worker if (local_result != VK_SUCCESS) {
2426*61046927SAndroid Build Coastguard Worker result = local_result;
2427*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
2428*61046927SAndroid Build Coastguard Worker }
2429*61046927SAndroid Build Coastguard Worker }
2430*61046927SAndroid Build Coastguard Worker
2431*61046927SAndroid Build Coastguard Worker return result;
2432*61046927SAndroid Build Coastguard Worker }
2433*61046927SAndroid Build Coastguard Worker
2434*61046927SAndroid Build Coastguard Worker /*****************************************************************************
2435*61046927SAndroid Build Coastguard Worker Other functions
2436*61046927SAndroid Build Coastguard Worker *****************************************************************************/
2437*61046927SAndroid Build Coastguard Worker
pvr_DestroyPipeline(VkDevice _device,VkPipeline _pipeline,const VkAllocationCallbacks * pAllocator)2438*61046927SAndroid Build Coastguard Worker void pvr_DestroyPipeline(VkDevice _device,
2439*61046927SAndroid Build Coastguard Worker VkPipeline _pipeline,
2440*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator)
2441*61046927SAndroid Build Coastguard Worker {
2442*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_pipeline, pipeline, _pipeline);
2443*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_device, device, _device);
2444*61046927SAndroid Build Coastguard Worker
2445*61046927SAndroid Build Coastguard Worker if (!pipeline)
2446*61046927SAndroid Build Coastguard Worker return;
2447*61046927SAndroid Build Coastguard Worker
2448*61046927SAndroid Build Coastguard Worker switch (pipeline->type) {
2449*61046927SAndroid Build Coastguard Worker case PVR_PIPELINE_TYPE_GRAPHICS: {
2450*61046927SAndroid Build Coastguard Worker struct pvr_graphics_pipeline *const gfx_pipeline =
2451*61046927SAndroid Build Coastguard Worker to_pvr_graphics_pipeline(pipeline);
2452*61046927SAndroid Build Coastguard Worker
2453*61046927SAndroid Build Coastguard Worker pvr_graphics_pipeline_destroy(device, pAllocator, gfx_pipeline);
2454*61046927SAndroid Build Coastguard Worker break;
2455*61046927SAndroid Build Coastguard Worker }
2456*61046927SAndroid Build Coastguard Worker
2457*61046927SAndroid Build Coastguard Worker case PVR_PIPELINE_TYPE_COMPUTE: {
2458*61046927SAndroid Build Coastguard Worker struct pvr_compute_pipeline *const compute_pipeline =
2459*61046927SAndroid Build Coastguard Worker to_pvr_compute_pipeline(pipeline);
2460*61046927SAndroid Build Coastguard Worker
2461*61046927SAndroid Build Coastguard Worker pvr_compute_pipeline_destroy(device, pAllocator, compute_pipeline);
2462*61046927SAndroid Build Coastguard Worker break;
2463*61046927SAndroid Build Coastguard Worker }
2464*61046927SAndroid Build Coastguard Worker
2465*61046927SAndroid Build Coastguard Worker default:
2466*61046927SAndroid Build Coastguard Worker unreachable("Unknown pipeline type.");
2467*61046927SAndroid Build Coastguard Worker }
2468*61046927SAndroid Build Coastguard Worker }
2469