1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2023 Imagination Technologies Ltd.
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a copy
5*61046927SAndroid Build Coastguard Worker * of this software and associated documentation files (the "Software"), to deal
6*61046927SAndroid Build Coastguard Worker * in the Software without restriction, including without limitation the rights
7*61046927SAndroid Build Coastguard Worker * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8*61046927SAndroid Build Coastguard Worker * copies of the Software, and to permit persons to whom the Software is
9*61046927SAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18*61046927SAndroid Build Coastguard Worker * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20*61046927SAndroid Build Coastguard Worker * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21*61046927SAndroid Build Coastguard Worker * SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include <stdint.h>
25*61046927SAndroid Build Coastguard Worker #include <stddef.h>
26*61046927SAndroid Build Coastguard Worker #include <string.h>
27*61046927SAndroid Build Coastguard Worker #include <vulkan/vulkan_core.h>
28*61046927SAndroid Build Coastguard Worker
29*61046927SAndroid Build Coastguard Worker #include "c11/threads.h"
30*61046927SAndroid Build Coastguard Worker #include "hwdef/rogue_hw_utils.h"
31*61046927SAndroid Build Coastguard Worker #include "pvr_bo.h"
32*61046927SAndroid Build Coastguard Worker #include "pvr_csb.h"
33*61046927SAndroid Build Coastguard Worker #include "pvr_csb_enum_helpers.h"
34*61046927SAndroid Build Coastguard Worker #include "pvr_device_info.h"
35*61046927SAndroid Build Coastguard Worker #include "pvr_formats.h"
36*61046927SAndroid Build Coastguard Worker #include "pvr_hw_pass.h"
37*61046927SAndroid Build Coastguard Worker #include "pvr_job_common.h"
38*61046927SAndroid Build Coastguard Worker #include "pvr_pds.h"
39*61046927SAndroid Build Coastguard Worker #include "pvr_private.h"
40*61046927SAndroid Build Coastguard Worker #include "pvr_shader_factory.h"
41*61046927SAndroid Build Coastguard Worker #include "pvr_spm.h"
42*61046927SAndroid Build Coastguard Worker #include "pvr_static_shaders.h"
43*61046927SAndroid Build Coastguard Worker #include "pvr_tex_state.h"
44*61046927SAndroid Build Coastguard Worker #include "pvr_types.h"
45*61046927SAndroid Build Coastguard Worker #include "pvr_uscgen.h"
46*61046927SAndroid Build Coastguard Worker #include "util/bitscan.h"
47*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
48*61046927SAndroid Build Coastguard Worker #include "util/simple_mtx.h"
49*61046927SAndroid Build Coastguard Worker #include "util/u_atomic.h"
50*61046927SAndroid Build Coastguard Worker #include "vk_alloc.h"
51*61046927SAndroid Build Coastguard Worker #include "vk_log.h"
52*61046927SAndroid Build Coastguard Worker
53*61046927SAndroid Build Coastguard Worker struct pvr_spm_scratch_buffer {
54*61046927SAndroid Build Coastguard Worker uint32_t ref_count;
55*61046927SAndroid Build Coastguard Worker struct pvr_bo *bo;
56*61046927SAndroid Build Coastguard Worker uint64_t size;
57*61046927SAndroid Build Coastguard Worker };
58*61046927SAndroid Build Coastguard Worker
pvr_spm_init_scratch_buffer_store(struct pvr_device * device)59*61046927SAndroid Build Coastguard Worker void pvr_spm_init_scratch_buffer_store(struct pvr_device *device)
60*61046927SAndroid Build Coastguard Worker {
61*61046927SAndroid Build Coastguard Worker struct pvr_spm_scratch_buffer_store *store =
62*61046927SAndroid Build Coastguard Worker &device->spm_scratch_buffer_store;
63*61046927SAndroid Build Coastguard Worker
64*61046927SAndroid Build Coastguard Worker simple_mtx_init(&store->mtx, mtx_plain);
65*61046927SAndroid Build Coastguard Worker store->head_ref = NULL;
66*61046927SAndroid Build Coastguard Worker }
67*61046927SAndroid Build Coastguard Worker
pvr_spm_finish_scratch_buffer_store(struct pvr_device * device)68*61046927SAndroid Build Coastguard Worker void pvr_spm_finish_scratch_buffer_store(struct pvr_device *device)
69*61046927SAndroid Build Coastguard Worker {
70*61046927SAndroid Build Coastguard Worker struct pvr_spm_scratch_buffer_store *store =
71*61046927SAndroid Build Coastguard Worker &device->spm_scratch_buffer_store;
72*61046927SAndroid Build Coastguard Worker
73*61046927SAndroid Build Coastguard Worker /* Either a framebuffer was never created so no scratch buffer was ever
74*61046927SAndroid Build Coastguard Worker * created or all framebuffers have been freed so only the store's reference
75*61046927SAndroid Build Coastguard Worker * remains.
76*61046927SAndroid Build Coastguard Worker */
77*61046927SAndroid Build Coastguard Worker assert(!store->head_ref || p_atomic_read(&store->head_ref->ref_count) == 1);
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard Worker simple_mtx_destroy(&store->mtx);
80*61046927SAndroid Build Coastguard Worker
81*61046927SAndroid Build Coastguard Worker if (store->head_ref) {
82*61046927SAndroid Build Coastguard Worker pvr_bo_free(device, store->head_ref->bo);
83*61046927SAndroid Build Coastguard Worker vk_free(&device->vk.alloc, store->head_ref);
84*61046927SAndroid Build Coastguard Worker }
85*61046927SAndroid Build Coastguard Worker }
86*61046927SAndroid Build Coastguard Worker
87*61046927SAndroid Build Coastguard Worker uint64_t
pvr_spm_scratch_buffer_calc_required_size(const struct pvr_render_pass * pass,uint32_t framebuffer_width,uint32_t framebuffer_height)88*61046927SAndroid Build Coastguard Worker pvr_spm_scratch_buffer_calc_required_size(const struct pvr_render_pass *pass,
89*61046927SAndroid Build Coastguard Worker uint32_t framebuffer_width,
90*61046927SAndroid Build Coastguard Worker uint32_t framebuffer_height)
91*61046927SAndroid Build Coastguard Worker {
92*61046927SAndroid Build Coastguard Worker uint64_t dwords_per_pixel;
93*61046927SAndroid Build Coastguard Worker uint64_t buffer_size;
94*61046927SAndroid Build Coastguard Worker
95*61046927SAndroid Build Coastguard Worker /* If we're allocating an SPM scratch buffer we'll have a minimum of 1 output
96*61046927SAndroid Build Coastguard Worker * reg and/or tile_buffer.
97*61046927SAndroid Build Coastguard Worker */
98*61046927SAndroid Build Coastguard Worker uint32_t nr_tile_buffers = 1;
99*61046927SAndroid Build Coastguard Worker uint32_t nr_output_regs = 1;
100*61046927SAndroid Build Coastguard Worker
101*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < pass->hw_setup->render_count; i++) {
102*61046927SAndroid Build Coastguard Worker const struct pvr_renderpass_hwsetup_render *hw_render =
103*61046927SAndroid Build Coastguard Worker &pass->hw_setup->renders[i];
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Worker nr_tile_buffers = MAX2(nr_tile_buffers, hw_render->tile_buffers_count);
106*61046927SAndroid Build Coastguard Worker nr_output_regs = MAX2(nr_output_regs, hw_render->output_regs_count);
107*61046927SAndroid Build Coastguard Worker }
108*61046927SAndroid Build Coastguard Worker
109*61046927SAndroid Build Coastguard Worker dwords_per_pixel =
110*61046927SAndroid Build Coastguard Worker (uint64_t)pass->max_sample_count * nr_output_regs * nr_tile_buffers;
111*61046927SAndroid Build Coastguard Worker
112*61046927SAndroid Build Coastguard Worker buffer_size = ALIGN_POT((uint64_t)framebuffer_width,
113*61046927SAndroid Build Coastguard Worker PVRX(CR_PBE_WORD0_MRT0_LINESTRIDE_ALIGNMENT));
114*61046927SAndroid Build Coastguard Worker buffer_size *=
115*61046927SAndroid Build Coastguard Worker (uint64_t)framebuffer_height * PVR_DW_TO_BYTES(dwords_per_pixel);
116*61046927SAndroid Build Coastguard Worker
117*61046927SAndroid Build Coastguard Worker return buffer_size;
118*61046927SAndroid Build Coastguard Worker }
119*61046927SAndroid Build Coastguard Worker
120*61046927SAndroid Build Coastguard Worker static VkResult
pvr_spm_scratch_buffer_alloc(struct pvr_device * device,uint64_t size,struct pvr_spm_scratch_buffer ** const buffer_out)121*61046927SAndroid Build Coastguard Worker pvr_spm_scratch_buffer_alloc(struct pvr_device *device,
122*61046927SAndroid Build Coastguard Worker uint64_t size,
123*61046927SAndroid Build Coastguard Worker struct pvr_spm_scratch_buffer **const buffer_out)
124*61046927SAndroid Build Coastguard Worker {
125*61046927SAndroid Build Coastguard Worker const uint32_t cache_line_size =
126*61046927SAndroid Build Coastguard Worker rogue_get_slc_cache_line_size(&device->pdevice->dev_info);
127*61046927SAndroid Build Coastguard Worker struct pvr_spm_scratch_buffer *scratch_buffer;
128*61046927SAndroid Build Coastguard Worker struct pvr_bo *bo;
129*61046927SAndroid Build Coastguard Worker VkResult result;
130*61046927SAndroid Build Coastguard Worker
131*61046927SAndroid Build Coastguard Worker result = pvr_bo_alloc(device,
132*61046927SAndroid Build Coastguard Worker device->heaps.general_heap,
133*61046927SAndroid Build Coastguard Worker size,
134*61046927SAndroid Build Coastguard Worker cache_line_size,
135*61046927SAndroid Build Coastguard Worker 0,
136*61046927SAndroid Build Coastguard Worker &bo);
137*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
138*61046927SAndroid Build Coastguard Worker *buffer_out = NULL;
139*61046927SAndroid Build Coastguard Worker return result;
140*61046927SAndroid Build Coastguard Worker }
141*61046927SAndroid Build Coastguard Worker
142*61046927SAndroid Build Coastguard Worker scratch_buffer = vk_alloc(&device->vk.alloc,
143*61046927SAndroid Build Coastguard Worker sizeof(*scratch_buffer),
144*61046927SAndroid Build Coastguard Worker 4,
145*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
146*61046927SAndroid Build Coastguard Worker if (!scratch_buffer) {
147*61046927SAndroid Build Coastguard Worker pvr_bo_free(device, bo);
148*61046927SAndroid Build Coastguard Worker *buffer_out = NULL;
149*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
150*61046927SAndroid Build Coastguard Worker }
151*61046927SAndroid Build Coastguard Worker
152*61046927SAndroid Build Coastguard Worker *scratch_buffer = (struct pvr_spm_scratch_buffer){
153*61046927SAndroid Build Coastguard Worker .bo = bo,
154*61046927SAndroid Build Coastguard Worker .size = size,
155*61046927SAndroid Build Coastguard Worker };
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker *buffer_out = scratch_buffer;
158*61046927SAndroid Build Coastguard Worker
159*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
160*61046927SAndroid Build Coastguard Worker }
161*61046927SAndroid Build Coastguard Worker
162*61046927SAndroid Build Coastguard Worker static void
pvr_spm_scratch_buffer_release_locked(struct pvr_device * device,struct pvr_spm_scratch_buffer * buffer)163*61046927SAndroid Build Coastguard Worker pvr_spm_scratch_buffer_release_locked(struct pvr_device *device,
164*61046927SAndroid Build Coastguard Worker struct pvr_spm_scratch_buffer *buffer)
165*61046927SAndroid Build Coastguard Worker {
166*61046927SAndroid Build Coastguard Worker struct pvr_spm_scratch_buffer_store *store =
167*61046927SAndroid Build Coastguard Worker &device->spm_scratch_buffer_store;
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard Worker simple_mtx_assert_locked(&store->mtx);
170*61046927SAndroid Build Coastguard Worker
171*61046927SAndroid Build Coastguard Worker if (p_atomic_dec_zero(&buffer->ref_count)) {
172*61046927SAndroid Build Coastguard Worker pvr_bo_free(device, buffer->bo);
173*61046927SAndroid Build Coastguard Worker vk_free(&device->vk.alloc, buffer);
174*61046927SAndroid Build Coastguard Worker }
175*61046927SAndroid Build Coastguard Worker }
176*61046927SAndroid Build Coastguard Worker
pvr_spm_scratch_buffer_release(struct pvr_device * device,struct pvr_spm_scratch_buffer * buffer)177*61046927SAndroid Build Coastguard Worker void pvr_spm_scratch_buffer_release(struct pvr_device *device,
178*61046927SAndroid Build Coastguard Worker struct pvr_spm_scratch_buffer *buffer)
179*61046927SAndroid Build Coastguard Worker {
180*61046927SAndroid Build Coastguard Worker struct pvr_spm_scratch_buffer_store *store =
181*61046927SAndroid Build Coastguard Worker &device->spm_scratch_buffer_store;
182*61046927SAndroid Build Coastguard Worker
183*61046927SAndroid Build Coastguard Worker simple_mtx_lock(&store->mtx);
184*61046927SAndroid Build Coastguard Worker
185*61046927SAndroid Build Coastguard Worker pvr_spm_scratch_buffer_release_locked(device, buffer);
186*61046927SAndroid Build Coastguard Worker
187*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(&store->mtx);
188*61046927SAndroid Build Coastguard Worker }
189*61046927SAndroid Build Coastguard Worker
pvr_spm_scratch_buffer_store_set_head_ref_locked(struct pvr_spm_scratch_buffer_store * store,struct pvr_spm_scratch_buffer * buffer)190*61046927SAndroid Build Coastguard Worker static void pvr_spm_scratch_buffer_store_set_head_ref_locked(
191*61046927SAndroid Build Coastguard Worker struct pvr_spm_scratch_buffer_store *store,
192*61046927SAndroid Build Coastguard Worker struct pvr_spm_scratch_buffer *buffer)
193*61046927SAndroid Build Coastguard Worker {
194*61046927SAndroid Build Coastguard Worker simple_mtx_assert_locked(&store->mtx);
195*61046927SAndroid Build Coastguard Worker assert(!store->head_ref);
196*61046927SAndroid Build Coastguard Worker
197*61046927SAndroid Build Coastguard Worker p_atomic_inc(&buffer->ref_count);
198*61046927SAndroid Build Coastguard Worker store->head_ref = buffer;
199*61046927SAndroid Build Coastguard Worker }
200*61046927SAndroid Build Coastguard Worker
pvr_spm_scratch_buffer_store_release_head_ref_locked(struct pvr_device * device,struct pvr_spm_scratch_buffer_store * store)201*61046927SAndroid Build Coastguard Worker static void pvr_spm_scratch_buffer_store_release_head_ref_locked(
202*61046927SAndroid Build Coastguard Worker struct pvr_device *device,
203*61046927SAndroid Build Coastguard Worker struct pvr_spm_scratch_buffer_store *store)
204*61046927SAndroid Build Coastguard Worker {
205*61046927SAndroid Build Coastguard Worker simple_mtx_assert_locked(&store->mtx);
206*61046927SAndroid Build Coastguard Worker
207*61046927SAndroid Build Coastguard Worker pvr_spm_scratch_buffer_release_locked(device, store->head_ref);
208*61046927SAndroid Build Coastguard Worker
209*61046927SAndroid Build Coastguard Worker store->head_ref = NULL;
210*61046927SAndroid Build Coastguard Worker }
211*61046927SAndroid Build Coastguard Worker
pvr_spm_scratch_buffer_get_buffer(struct pvr_device * device,uint64_t size,struct pvr_spm_scratch_buffer ** const buffer_out)212*61046927SAndroid Build Coastguard Worker VkResult pvr_spm_scratch_buffer_get_buffer(
213*61046927SAndroid Build Coastguard Worker struct pvr_device *device,
214*61046927SAndroid Build Coastguard Worker uint64_t size,
215*61046927SAndroid Build Coastguard Worker struct pvr_spm_scratch_buffer **const buffer_out)
216*61046927SAndroid Build Coastguard Worker {
217*61046927SAndroid Build Coastguard Worker struct pvr_spm_scratch_buffer_store *store =
218*61046927SAndroid Build Coastguard Worker &device->spm_scratch_buffer_store;
219*61046927SAndroid Build Coastguard Worker struct pvr_spm_scratch_buffer *buffer;
220*61046927SAndroid Build Coastguard Worker
221*61046927SAndroid Build Coastguard Worker simple_mtx_lock(&store->mtx);
222*61046927SAndroid Build Coastguard Worker
223*61046927SAndroid Build Coastguard Worker /* When a render requires a PR the fw will wait for other renders to end,
224*61046927SAndroid Build Coastguard Worker * free the PB space, unschedule any other vert/frag jobs and solely run the
225*61046927SAndroid Build Coastguard Worker * PR on the whole device until completion.
226*61046927SAndroid Build Coastguard Worker * Thus we can safely use the same scratch buffer across multiple
227*61046927SAndroid Build Coastguard Worker * framebuffers as the scratch buffer is only used during PRs and only one PR
228*61046927SAndroid Build Coastguard Worker * can ever be executed at any one time.
229*61046927SAndroid Build Coastguard Worker */
230*61046927SAndroid Build Coastguard Worker if (store->head_ref && store->head_ref->size <= size) {
231*61046927SAndroid Build Coastguard Worker buffer = store->head_ref;
232*61046927SAndroid Build Coastguard Worker } else {
233*61046927SAndroid Build Coastguard Worker VkResult result;
234*61046927SAndroid Build Coastguard Worker
235*61046927SAndroid Build Coastguard Worker if (store->head_ref)
236*61046927SAndroid Build Coastguard Worker pvr_spm_scratch_buffer_store_release_head_ref_locked(device, store);
237*61046927SAndroid Build Coastguard Worker
238*61046927SAndroid Build Coastguard Worker result = pvr_spm_scratch_buffer_alloc(device, size, &buffer);
239*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
240*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(&store->mtx);
241*61046927SAndroid Build Coastguard Worker *buffer_out = NULL;
242*61046927SAndroid Build Coastguard Worker
243*61046927SAndroid Build Coastguard Worker return result;
244*61046927SAndroid Build Coastguard Worker }
245*61046927SAndroid Build Coastguard Worker
246*61046927SAndroid Build Coastguard Worker pvr_spm_scratch_buffer_store_set_head_ref_locked(store, buffer);
247*61046927SAndroid Build Coastguard Worker }
248*61046927SAndroid Build Coastguard Worker
249*61046927SAndroid Build Coastguard Worker p_atomic_inc(&buffer->ref_count);
250*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(&store->mtx);
251*61046927SAndroid Build Coastguard Worker *buffer_out = buffer;
252*61046927SAndroid Build Coastguard Worker
253*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
254*61046927SAndroid Build Coastguard Worker }
255*61046927SAndroid Build Coastguard Worker
pvr_device_init_spm_load_state(struct pvr_device * device)256*61046927SAndroid Build Coastguard Worker VkResult pvr_device_init_spm_load_state(struct pvr_device *device)
257*61046927SAndroid Build Coastguard Worker {
258*61046927SAndroid Build Coastguard Worker const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
259*61046927SAndroid Build Coastguard Worker uint32_t pds_texture_aligned_offsets[PVR_SPM_LOAD_PROGRAM_COUNT];
260*61046927SAndroid Build Coastguard Worker uint32_t pds_kick_aligned_offsets[PVR_SPM_LOAD_PROGRAM_COUNT];
261*61046927SAndroid Build Coastguard Worker uint32_t usc_aligned_offsets[PVR_SPM_LOAD_PROGRAM_COUNT];
262*61046927SAndroid Build Coastguard Worker uint32_t pds_allocation_size = 0;
263*61046927SAndroid Build Coastguard Worker uint32_t usc_allocation_size = 0;
264*61046927SAndroid Build Coastguard Worker struct pvr_suballoc_bo *pds_bo;
265*61046927SAndroid Build Coastguard Worker struct pvr_suballoc_bo *usc_bo;
266*61046927SAndroid Build Coastguard Worker uint8_t *mem_ptr;
267*61046927SAndroid Build Coastguard Worker VkResult result;
268*61046927SAndroid Build Coastguard Worker
269*61046927SAndroid Build Coastguard Worker static_assert(PVR_SPM_LOAD_PROGRAM_COUNT == ARRAY_SIZE(spm_load_collection),
270*61046927SAndroid Build Coastguard Worker "Size mismatch");
271*61046927SAndroid Build Coastguard Worker
272*61046927SAndroid Build Coastguard Worker /* TODO: We don't need to upload all the programs since the set contains
273*61046927SAndroid Build Coastguard Worker * programs for devices with 8 output regs as well. We can save some memory
274*61046927SAndroid Build Coastguard Worker * by not uploading them on devices without the feature.
275*61046927SAndroid Build Coastguard Worker * It's likely that once the compiler is hooked up we'll be using the shader
276*61046927SAndroid Build Coastguard Worker * cache and generate the shaders as needed so this todo will be unnecessary.
277*61046927SAndroid Build Coastguard Worker */
278*61046927SAndroid Build Coastguard Worker
279*61046927SAndroid Build Coastguard Worker /* Upload USC shaders. */
280*61046927SAndroid Build Coastguard Worker
281*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < ARRAY_SIZE(spm_load_collection); i++) {
282*61046927SAndroid Build Coastguard Worker usc_aligned_offsets[i] = usc_allocation_size;
283*61046927SAndroid Build Coastguard Worker usc_allocation_size += ALIGN_POT(spm_load_collection[i].size, 4);
284*61046927SAndroid Build Coastguard Worker }
285*61046927SAndroid Build Coastguard Worker
286*61046927SAndroid Build Coastguard Worker result = pvr_bo_suballoc(&device->suballoc_usc,
287*61046927SAndroid Build Coastguard Worker usc_allocation_size,
288*61046927SAndroid Build Coastguard Worker 4,
289*61046927SAndroid Build Coastguard Worker false,
290*61046927SAndroid Build Coastguard Worker &usc_bo);
291*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
292*61046927SAndroid Build Coastguard Worker return result;
293*61046927SAndroid Build Coastguard Worker
294*61046927SAndroid Build Coastguard Worker mem_ptr = (uint8_t *)pvr_bo_suballoc_get_map_addr(usc_bo);
295*61046927SAndroid Build Coastguard Worker
296*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < ARRAY_SIZE(spm_load_collection); i++) {
297*61046927SAndroid Build Coastguard Worker memcpy(mem_ptr + usc_aligned_offsets[i],
298*61046927SAndroid Build Coastguard Worker spm_load_collection[i].code,
299*61046927SAndroid Build Coastguard Worker spm_load_collection[i].size);
300*61046927SAndroid Build Coastguard Worker }
301*61046927SAndroid Build Coastguard Worker
302*61046927SAndroid Build Coastguard Worker /* Upload PDS programs. */
303*61046927SAndroid Build Coastguard Worker
304*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < ARRAY_SIZE(spm_load_collection); i++) {
305*61046927SAndroid Build Coastguard Worker struct pvr_pds_pixel_shader_sa_program pds_texture_program = {
306*61046927SAndroid Build Coastguard Worker /* DMA for clear colors and tile buffer address parts. */
307*61046927SAndroid Build Coastguard Worker .num_texture_dma_kicks = 1,
308*61046927SAndroid Build Coastguard Worker };
309*61046927SAndroid Build Coastguard Worker struct pvr_pds_kickusc_program pds_kick_program = { 0 };
310*61046927SAndroid Build Coastguard Worker
311*61046927SAndroid Build Coastguard Worker /* TODO: This looks a bit odd and isn't consistent with other code where
312*61046927SAndroid Build Coastguard Worker * we're getting the size of the PDS program. Can we improve this?
313*61046927SAndroid Build Coastguard Worker */
314*61046927SAndroid Build Coastguard Worker pvr_pds_set_sizes_pixel_shader_uniform_texture_code(&pds_texture_program);
315*61046927SAndroid Build Coastguard Worker pvr_pds_set_sizes_pixel_shader_sa_texture_data(&pds_texture_program,
316*61046927SAndroid Build Coastguard Worker dev_info);
317*61046927SAndroid Build Coastguard Worker
318*61046927SAndroid Build Coastguard Worker /* TODO: Looking at the pvr_pds_generate_...() functions and the run-time
319*61046927SAndroid Build Coastguard Worker * behavior the data size is always the same here. Should we try saving
320*61046927SAndroid Build Coastguard Worker * some memory by adjusting things based on that?
321*61046927SAndroid Build Coastguard Worker */
322*61046927SAndroid Build Coastguard Worker device->spm_load_state.load_program[i].pds_texture_program_data_size =
323*61046927SAndroid Build Coastguard Worker pds_texture_program.data_size;
324*61046927SAndroid Build Coastguard Worker
325*61046927SAndroid Build Coastguard Worker pds_texture_aligned_offsets[i] = pds_allocation_size;
326*61046927SAndroid Build Coastguard Worker /* FIXME: Figure out the define for alignment of 16. */
327*61046927SAndroid Build Coastguard Worker pds_allocation_size +=
328*61046927SAndroid Build Coastguard Worker ALIGN_POT(PVR_DW_TO_BYTES(pds_texture_program.code_size), 16);
329*61046927SAndroid Build Coastguard Worker
330*61046927SAndroid Build Coastguard Worker pvr_pds_set_sizes_pixel_shader(&pds_kick_program);
331*61046927SAndroid Build Coastguard Worker
332*61046927SAndroid Build Coastguard Worker pds_kick_aligned_offsets[i] = pds_allocation_size;
333*61046927SAndroid Build Coastguard Worker /* FIXME: Figure out the define for alignment of 16. */
334*61046927SAndroid Build Coastguard Worker pds_allocation_size +=
335*61046927SAndroid Build Coastguard Worker ALIGN_POT(PVR_DW_TO_BYTES(pds_kick_program.code_size +
336*61046927SAndroid Build Coastguard Worker pds_kick_program.data_size),
337*61046927SAndroid Build Coastguard Worker 16);
338*61046927SAndroid Build Coastguard Worker }
339*61046927SAndroid Build Coastguard Worker
340*61046927SAndroid Build Coastguard Worker /* FIXME: Figure out the define for alignment of 16. */
341*61046927SAndroid Build Coastguard Worker result = pvr_bo_suballoc(&device->suballoc_pds,
342*61046927SAndroid Build Coastguard Worker pds_allocation_size,
343*61046927SAndroid Build Coastguard Worker 16,
344*61046927SAndroid Build Coastguard Worker false,
345*61046927SAndroid Build Coastguard Worker &pds_bo);
346*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
347*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(usc_bo);
348*61046927SAndroid Build Coastguard Worker return result;
349*61046927SAndroid Build Coastguard Worker }
350*61046927SAndroid Build Coastguard Worker
351*61046927SAndroid Build Coastguard Worker mem_ptr = (uint8_t *)pvr_bo_suballoc_get_map_addr(pds_bo);
352*61046927SAndroid Build Coastguard Worker
353*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < ARRAY_SIZE(spm_load_collection); i++) {
354*61046927SAndroid Build Coastguard Worker struct pvr_pds_pixel_shader_sa_program pds_texture_program = {
355*61046927SAndroid Build Coastguard Worker /* DMA for clear colors and tile buffer address parts. */
356*61046927SAndroid Build Coastguard Worker .num_texture_dma_kicks = 1,
357*61046927SAndroid Build Coastguard Worker };
358*61046927SAndroid Build Coastguard Worker const pvr_dev_addr_t usc_program_dev_addr =
359*61046927SAndroid Build Coastguard Worker PVR_DEV_ADDR_OFFSET(usc_bo->dev_addr, usc_aligned_offsets[i]);
360*61046927SAndroid Build Coastguard Worker struct pvr_pds_kickusc_program pds_kick_program = { 0 };
361*61046927SAndroid Build Coastguard Worker enum PVRX(PDSINST_DOUTU_SAMPLE_RATE) sample_rate;
362*61046927SAndroid Build Coastguard Worker
363*61046927SAndroid Build Coastguard Worker pvr_pds_generate_pixel_shader_sa_code_segment(
364*61046927SAndroid Build Coastguard Worker &pds_texture_program,
365*61046927SAndroid Build Coastguard Worker (uint32_t *)(mem_ptr + pds_texture_aligned_offsets[i]));
366*61046927SAndroid Build Coastguard Worker
367*61046927SAndroid Build Coastguard Worker if (spm_load_collection[i].info->msaa_sample_count > 1)
368*61046927SAndroid Build Coastguard Worker sample_rate = PVRX(PDSINST_DOUTU_SAMPLE_RATE_FULL);
369*61046927SAndroid Build Coastguard Worker else
370*61046927SAndroid Build Coastguard Worker sample_rate = PVRX(PDSINST_DOUTU_SAMPLE_RATE_INSTANCE);
371*61046927SAndroid Build Coastguard Worker
372*61046927SAndroid Build Coastguard Worker pvr_pds_setup_doutu(&pds_kick_program.usc_task_control,
373*61046927SAndroid Build Coastguard Worker usc_program_dev_addr.addr,
374*61046927SAndroid Build Coastguard Worker spm_load_collection[i].info->temps_required,
375*61046927SAndroid Build Coastguard Worker sample_rate,
376*61046927SAndroid Build Coastguard Worker false);
377*61046927SAndroid Build Coastguard Worker
378*61046927SAndroid Build Coastguard Worker /* Generated both code and data. */
379*61046927SAndroid Build Coastguard Worker pvr_pds_generate_pixel_shader_program(
380*61046927SAndroid Build Coastguard Worker &pds_kick_program,
381*61046927SAndroid Build Coastguard Worker (uint32_t *)(mem_ptr + pds_kick_aligned_offsets[i]));
382*61046927SAndroid Build Coastguard Worker
383*61046927SAndroid Build Coastguard Worker device->spm_load_state.load_program[i].pds_pixel_program_offset =
384*61046927SAndroid Build Coastguard Worker PVR_DEV_ADDR_OFFSET(pds_bo->dev_addr, pds_kick_aligned_offsets[i]);
385*61046927SAndroid Build Coastguard Worker device->spm_load_state.load_program[i].pds_uniform_program_offset =
386*61046927SAndroid Build Coastguard Worker PVR_DEV_ADDR_OFFSET(pds_bo->dev_addr, pds_texture_aligned_offsets[i]);
387*61046927SAndroid Build Coastguard Worker
388*61046927SAndroid Build Coastguard Worker /* TODO: From looking at the pvr_pds_generate_...() functions, it seems
389*61046927SAndroid Build Coastguard Worker * like temps_used is always 1. Should we remove this and hard code it
390*61046927SAndroid Build Coastguard Worker * with a define in the PDS code?
391*61046927SAndroid Build Coastguard Worker */
392*61046927SAndroid Build Coastguard Worker device->spm_load_state.load_program[i].pds_texture_program_temps_count =
393*61046927SAndroid Build Coastguard Worker pds_texture_program.temps_used;
394*61046927SAndroid Build Coastguard Worker }
395*61046927SAndroid Build Coastguard Worker
396*61046927SAndroid Build Coastguard Worker device->spm_load_state.usc_programs = usc_bo;
397*61046927SAndroid Build Coastguard Worker device->spm_load_state.pds_programs = pds_bo;
398*61046927SAndroid Build Coastguard Worker
399*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
400*61046927SAndroid Build Coastguard Worker }
401*61046927SAndroid Build Coastguard Worker
pvr_device_finish_spm_load_state(struct pvr_device * device)402*61046927SAndroid Build Coastguard Worker void pvr_device_finish_spm_load_state(struct pvr_device *device)
403*61046927SAndroid Build Coastguard Worker {
404*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(device->spm_load_state.pds_programs);
405*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(device->spm_load_state.usc_programs);
406*61046927SAndroid Build Coastguard Worker }
407*61046927SAndroid Build Coastguard Worker
PVRX(PBESTATE_PACKMODE)408*61046927SAndroid Build Coastguard Worker static inline enum PVRX(PBESTATE_PACKMODE)
409*61046927SAndroid Build Coastguard Worker pvr_spm_get_pbe_packmode(uint32_t dword_count)
410*61046927SAndroid Build Coastguard Worker {
411*61046927SAndroid Build Coastguard Worker switch (dword_count) {
412*61046927SAndroid Build Coastguard Worker case 1:
413*61046927SAndroid Build Coastguard Worker return PVRX(PBESTATE_PACKMODE_U32);
414*61046927SAndroid Build Coastguard Worker case 2:
415*61046927SAndroid Build Coastguard Worker return PVRX(PBESTATE_PACKMODE_U32U32);
416*61046927SAndroid Build Coastguard Worker case 3:
417*61046927SAndroid Build Coastguard Worker return PVRX(PBESTATE_PACKMODE_U32U32U32);
418*61046927SAndroid Build Coastguard Worker case 4:
419*61046927SAndroid Build Coastguard Worker return PVRX(PBESTATE_PACKMODE_U32U32U32U32);
420*61046927SAndroid Build Coastguard Worker default:
421*61046927SAndroid Build Coastguard Worker unreachable("Unsupported dword_count");
422*61046927SAndroid Build Coastguard Worker }
423*61046927SAndroid Build Coastguard Worker }
424*61046927SAndroid Build Coastguard Worker
425*61046927SAndroid Build Coastguard Worker /**
426*61046927SAndroid Build Coastguard Worker * \brief Sets up PBE registers and state values per a single render output.
427*61046927SAndroid Build Coastguard Worker *
428*61046927SAndroid Build Coastguard Worker * On a PR we want to store tile data to the scratch buffer so we need to
429*61046927SAndroid Build Coastguard Worker * setup the Pixel Back End (PBE) to write the data to the scratch buffer. This
430*61046927SAndroid Build Coastguard Worker * function sets up the PBE state and register values required to do so, for a
431*61046927SAndroid Build Coastguard Worker * single resource whether it be a tile buffer or the output register set.
432*61046927SAndroid Build Coastguard Worker *
433*61046927SAndroid Build Coastguard Worker * \return Size of the data saved into the scratch buffer in bytes.
434*61046927SAndroid Build Coastguard Worker */
pvr_spm_setup_pbe_state(const struct pvr_device_info * dev_info,const VkExtent2D * framebuffer_size,uint32_t dword_count,enum pvr_pbe_source_start_pos source_start,uint32_t sample_count,pvr_dev_addr_t scratch_buffer_addr,uint32_t pbe_state_words_out[static const ROGUE_NUM_PBESTATE_STATE_WORDS],uint64_t pbe_reg_words_out[static const ROGUE_NUM_PBESTATE_REG_WORDS])435*61046927SAndroid Build Coastguard Worker static uint64_t pvr_spm_setup_pbe_state(
436*61046927SAndroid Build Coastguard Worker const struct pvr_device_info *dev_info,
437*61046927SAndroid Build Coastguard Worker const VkExtent2D *framebuffer_size,
438*61046927SAndroid Build Coastguard Worker uint32_t dword_count,
439*61046927SAndroid Build Coastguard Worker enum pvr_pbe_source_start_pos source_start,
440*61046927SAndroid Build Coastguard Worker uint32_t sample_count,
441*61046927SAndroid Build Coastguard Worker pvr_dev_addr_t scratch_buffer_addr,
442*61046927SAndroid Build Coastguard Worker uint32_t pbe_state_words_out[static const ROGUE_NUM_PBESTATE_STATE_WORDS],
443*61046927SAndroid Build Coastguard Worker uint64_t pbe_reg_words_out[static const ROGUE_NUM_PBESTATE_REG_WORDS])
444*61046927SAndroid Build Coastguard Worker {
445*61046927SAndroid Build Coastguard Worker const uint32_t stride =
446*61046927SAndroid Build Coastguard Worker ALIGN_POT(framebuffer_size->width,
447*61046927SAndroid Build Coastguard Worker PVRX(PBESTATE_REG_WORD0_LINESTRIDE_UNIT_SIZE));
448*61046927SAndroid Build Coastguard Worker
449*61046927SAndroid Build Coastguard Worker const struct pvr_pbe_surf_params surface_params = {
450*61046927SAndroid Build Coastguard Worker .swizzle = {
451*61046927SAndroid Build Coastguard Worker [0] = PIPE_SWIZZLE_X,
452*61046927SAndroid Build Coastguard Worker [1] = PIPE_SWIZZLE_Y,
453*61046927SAndroid Build Coastguard Worker [2] = PIPE_SWIZZLE_Z,
454*61046927SAndroid Build Coastguard Worker [3] = PIPE_SWIZZLE_W,
455*61046927SAndroid Build Coastguard Worker },
456*61046927SAndroid Build Coastguard Worker .pbe_packmode = pvr_spm_get_pbe_packmode(dword_count),
457*61046927SAndroid Build Coastguard Worker .source_format = PVRX(PBESTATE_SOURCE_FORMAT_8_PER_CHANNEL),
458*61046927SAndroid Build Coastguard Worker .addr = scratch_buffer_addr,
459*61046927SAndroid Build Coastguard Worker .mem_layout = PVR_MEMLAYOUT_LINEAR,
460*61046927SAndroid Build Coastguard Worker .stride = stride,
461*61046927SAndroid Build Coastguard Worker };
462*61046927SAndroid Build Coastguard Worker const struct pvr_pbe_render_params render_params = {
463*61046927SAndroid Build Coastguard Worker .max_x_clip = framebuffer_size->width - 1,
464*61046927SAndroid Build Coastguard Worker .max_y_clip = framebuffer_size->height - 1,
465*61046927SAndroid Build Coastguard Worker .source_start = source_start,
466*61046927SAndroid Build Coastguard Worker };
467*61046927SAndroid Build Coastguard Worker
468*61046927SAndroid Build Coastguard Worker pvr_pbe_pack_state(dev_info,
469*61046927SAndroid Build Coastguard Worker &surface_params,
470*61046927SAndroid Build Coastguard Worker &render_params,
471*61046927SAndroid Build Coastguard Worker pbe_state_words_out,
472*61046927SAndroid Build Coastguard Worker pbe_reg_words_out);
473*61046927SAndroid Build Coastguard Worker
474*61046927SAndroid Build Coastguard Worker return (uint64_t)stride * framebuffer_size->height * sample_count *
475*61046927SAndroid Build Coastguard Worker PVR_DW_TO_BYTES(dword_count);
476*61046927SAndroid Build Coastguard Worker }
477*61046927SAndroid Build Coastguard Worker
pvr_set_pbe_all_valid_mask(struct usc_mrt_desc * desc)478*61046927SAndroid Build Coastguard Worker static inline void pvr_set_pbe_all_valid_mask(struct usc_mrt_desc *desc)
479*61046927SAndroid Build Coastguard Worker {
480*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < ARRAY_SIZE(desc->valid_mask); i++)
481*61046927SAndroid Build Coastguard Worker desc->valid_mask[i] = ~0;
482*61046927SAndroid Build Coastguard Worker }
483*61046927SAndroid Build Coastguard Worker
484*61046927SAndroid Build Coastguard Worker #define PVR_DEV_ADDR_ADVANCE(_addr, _offset) \
485*61046927SAndroid Build Coastguard Worker _addr = PVR_DEV_ADDR_OFFSET(_addr, _offset)
486*61046927SAndroid Build Coastguard Worker
487*61046927SAndroid Build Coastguard Worker /**
488*61046927SAndroid Build Coastguard Worker * \brief Sets up PBE registers, PBE state values and MRT data per a single
489*61046927SAndroid Build Coastguard Worker * render output requiring 8 dwords to be written.
490*61046927SAndroid Build Coastguard Worker *
491*61046927SAndroid Build Coastguard Worker * On a PR we want to store tile data to the scratch buffer so we need to
492*61046927SAndroid Build Coastguard Worker * setup the Pixel Back End (PBE) to write the data to the scratch buffer, as
493*61046927SAndroid Build Coastguard Worker * well as setup the Multiple Render Target (MRT) info so the compiler knows
494*61046927SAndroid Build Coastguard Worker * what data needs to be stored (output regs or tile buffers) and generate the
495*61046927SAndroid Build Coastguard Worker * appropriate EOT shader.
496*61046927SAndroid Build Coastguard Worker *
497*61046927SAndroid Build Coastguard Worker * This function is only available for devices with the eight_output_registers
498*61046927SAndroid Build Coastguard Worker * feature thus requiring 8 dwords to be stored.
499*61046927SAndroid Build Coastguard Worker *
500*61046927SAndroid Build Coastguard Worker * \return Size of the data saved into the scratch buffer in bytes.
501*61046927SAndroid Build Coastguard Worker */
pvr_spm_setup_pbe_eight_dword_write(const struct pvr_device_info * dev_info,const VkExtent2D * framebuffer_size,uint32_t sample_count,enum usc_mrt_resource_type source_type,uint32_t tile_buffer_idx,pvr_dev_addr_t scratch_buffer_addr,uint32_t pbe_state_word_0_out[static const ROGUE_NUM_PBESTATE_STATE_WORDS],uint32_t pbe_state_word_1_out[static const ROGUE_NUM_PBESTATE_STATE_WORDS],uint64_t pbe_reg_word_0_out[static const ROGUE_NUM_PBESTATE_REG_WORDS],uint64_t pbe_reg_word_1_out[static const ROGUE_NUM_PBESTATE_REG_WORDS],uint32_t * render_target_used_out)502*61046927SAndroid Build Coastguard Worker static uint64_t pvr_spm_setup_pbe_eight_dword_write(
503*61046927SAndroid Build Coastguard Worker const struct pvr_device_info *dev_info,
504*61046927SAndroid Build Coastguard Worker const VkExtent2D *framebuffer_size,
505*61046927SAndroid Build Coastguard Worker uint32_t sample_count,
506*61046927SAndroid Build Coastguard Worker enum usc_mrt_resource_type source_type,
507*61046927SAndroid Build Coastguard Worker uint32_t tile_buffer_idx,
508*61046927SAndroid Build Coastguard Worker pvr_dev_addr_t scratch_buffer_addr,
509*61046927SAndroid Build Coastguard Worker uint32_t pbe_state_word_0_out[static const ROGUE_NUM_PBESTATE_STATE_WORDS],
510*61046927SAndroid Build Coastguard Worker uint32_t pbe_state_word_1_out[static const ROGUE_NUM_PBESTATE_STATE_WORDS],
511*61046927SAndroid Build Coastguard Worker uint64_t pbe_reg_word_0_out[static const ROGUE_NUM_PBESTATE_REG_WORDS],
512*61046927SAndroid Build Coastguard Worker uint64_t pbe_reg_word_1_out[static const ROGUE_NUM_PBESTATE_REG_WORDS],
513*61046927SAndroid Build Coastguard Worker uint32_t *render_target_used_out)
514*61046927SAndroid Build Coastguard Worker {
515*61046927SAndroid Build Coastguard Worker const uint32_t max_pbe_write_size_dw = 4;
516*61046927SAndroid Build Coastguard Worker uint32_t render_target_used = 0;
517*61046927SAndroid Build Coastguard Worker uint64_t mem_stored;
518*61046927SAndroid Build Coastguard Worker
519*61046927SAndroid Build Coastguard Worker assert(PVR_HAS_FEATURE(dev_info, eight_output_registers));
520*61046927SAndroid Build Coastguard Worker assert(source_type != USC_MRT_RESOURCE_TYPE_INVALID);
521*61046927SAndroid Build Coastguard Worker
522*61046927SAndroid Build Coastguard Worker /* To store 8 dwords we need to split this into two
523*61046927SAndroid Build Coastguard Worker * ROGUE_PBESTATE_PACKMODE_U32U32U32U32 stores with the second one using
524*61046927SAndroid Build Coastguard Worker * PVR_PBE_STARTPOS_BIT128 as the source offset to store the last 4 dwords.
525*61046927SAndroid Build Coastguard Worker */
526*61046927SAndroid Build Coastguard Worker
527*61046927SAndroid Build Coastguard Worker mem_stored = pvr_spm_setup_pbe_state(dev_info,
528*61046927SAndroid Build Coastguard Worker framebuffer_size,
529*61046927SAndroid Build Coastguard Worker max_pbe_write_size_dw,
530*61046927SAndroid Build Coastguard Worker PVR_PBE_STARTPOS_BIT0,
531*61046927SAndroid Build Coastguard Worker sample_count,
532*61046927SAndroid Build Coastguard Worker scratch_buffer_addr,
533*61046927SAndroid Build Coastguard Worker pbe_state_word_0_out,
534*61046927SAndroid Build Coastguard Worker pbe_reg_word_0_out);
535*61046927SAndroid Build Coastguard Worker
536*61046927SAndroid Build Coastguard Worker PVR_DEV_ADDR_ADVANCE(scratch_buffer_addr, mem_stored);
537*61046927SAndroid Build Coastguard Worker
538*61046927SAndroid Build Coastguard Worker render_target_used++;
539*61046927SAndroid Build Coastguard Worker
540*61046927SAndroid Build Coastguard Worker mem_stored += pvr_spm_setup_pbe_state(dev_info,
541*61046927SAndroid Build Coastguard Worker framebuffer_size,
542*61046927SAndroid Build Coastguard Worker max_pbe_write_size_dw,
543*61046927SAndroid Build Coastguard Worker PVR_PBE_STARTPOS_BIT128,
544*61046927SAndroid Build Coastguard Worker sample_count,
545*61046927SAndroid Build Coastguard Worker scratch_buffer_addr,
546*61046927SAndroid Build Coastguard Worker pbe_state_word_1_out,
547*61046927SAndroid Build Coastguard Worker pbe_reg_word_1_out);
548*61046927SAndroid Build Coastguard Worker
549*61046927SAndroid Build Coastguard Worker PVR_DEV_ADDR_ADVANCE(scratch_buffer_addr, mem_stored);
550*61046927SAndroid Build Coastguard Worker
551*61046927SAndroid Build Coastguard Worker render_target_used++;
552*61046927SAndroid Build Coastguard Worker *render_target_used_out = render_target_used;
553*61046927SAndroid Build Coastguard Worker
554*61046927SAndroid Build Coastguard Worker return mem_stored;
555*61046927SAndroid Build Coastguard Worker }
556*61046927SAndroid Build Coastguard Worker
557*61046927SAndroid Build Coastguard Worker /**
558*61046927SAndroid Build Coastguard Worker * \brief Create and upload the EOT PDS program.
559*61046927SAndroid Build Coastguard Worker *
560*61046927SAndroid Build Coastguard Worker * Essentially DOUTU the USC EOT shader.
561*61046927SAndroid Build Coastguard Worker */
562*61046927SAndroid Build Coastguard Worker /* TODO: See if we can dedup this with
563*61046927SAndroid Build Coastguard Worker * pvr_sub_cmd_gfx_per_job_fragment_programs_create_and_upload().
564*61046927SAndroid Build Coastguard Worker */
pvr_pds_pixel_event_program_create_and_upload(struct pvr_device * device,const struct pvr_suballoc_bo * usc_eot_program,uint32_t usc_temp_count,struct pvr_pds_upload * const pds_upload_out)565*61046927SAndroid Build Coastguard Worker static VkResult pvr_pds_pixel_event_program_create_and_upload(
566*61046927SAndroid Build Coastguard Worker struct pvr_device *device,
567*61046927SAndroid Build Coastguard Worker const struct pvr_suballoc_bo *usc_eot_program,
568*61046927SAndroid Build Coastguard Worker uint32_t usc_temp_count,
569*61046927SAndroid Build Coastguard Worker struct pvr_pds_upload *const pds_upload_out)
570*61046927SAndroid Build Coastguard Worker {
571*61046927SAndroid Build Coastguard Worker const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
572*61046927SAndroid Build Coastguard Worker struct pvr_pds_event_program program = { 0 };
573*61046927SAndroid Build Coastguard Worker uint32_t *staging_buffer;
574*61046927SAndroid Build Coastguard Worker VkResult result;
575*61046927SAndroid Build Coastguard Worker
576*61046927SAndroid Build Coastguard Worker pvr_pds_setup_doutu(&program.task_control,
577*61046927SAndroid Build Coastguard Worker usc_eot_program->dev_addr.addr,
578*61046927SAndroid Build Coastguard Worker usc_temp_count,
579*61046927SAndroid Build Coastguard Worker PVRX(PDSINST_DOUTU_SAMPLE_RATE_INSTANCE),
580*61046927SAndroid Build Coastguard Worker false);
581*61046927SAndroid Build Coastguard Worker
582*61046927SAndroid Build Coastguard Worker staging_buffer =
583*61046927SAndroid Build Coastguard Worker vk_alloc(&device->vk.alloc,
584*61046927SAndroid Build Coastguard Worker PVR_DW_TO_BYTES(device->pixel_event_data_size_in_dwords),
585*61046927SAndroid Build Coastguard Worker 8,
586*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
587*61046927SAndroid Build Coastguard Worker if (!staging_buffer)
588*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
589*61046927SAndroid Build Coastguard Worker
590*61046927SAndroid Build Coastguard Worker pvr_pds_generate_pixel_event_data_segment(&program,
591*61046927SAndroid Build Coastguard Worker staging_buffer,
592*61046927SAndroid Build Coastguard Worker dev_info);
593*61046927SAndroid Build Coastguard Worker
594*61046927SAndroid Build Coastguard Worker result = pvr_gpu_upload_pds(device,
595*61046927SAndroid Build Coastguard Worker staging_buffer,
596*61046927SAndroid Build Coastguard Worker device->pixel_event_data_size_in_dwords,
597*61046927SAndroid Build Coastguard Worker 4,
598*61046927SAndroid Build Coastguard Worker NULL,
599*61046927SAndroid Build Coastguard Worker 0,
600*61046927SAndroid Build Coastguard Worker 0,
601*61046927SAndroid Build Coastguard Worker 4,
602*61046927SAndroid Build Coastguard Worker pds_upload_out);
603*61046927SAndroid Build Coastguard Worker vk_free(&device->vk.alloc, staging_buffer);
604*61046927SAndroid Build Coastguard Worker return result;
605*61046927SAndroid Build Coastguard Worker }
606*61046927SAndroid Build Coastguard Worker
607*61046927SAndroid Build Coastguard Worker /**
608*61046927SAndroid Build Coastguard Worker * \brief Sets up the End of Tile (EOT) program for SPM.
609*61046927SAndroid Build Coastguard Worker *
610*61046927SAndroid Build Coastguard Worker * This sets up an EOT program to store the render pass'es on-chip and
611*61046927SAndroid Build Coastguard Worker * off-chip tile data to the SPM scratch buffer on the EOT event.
612*61046927SAndroid Build Coastguard Worker */
613*61046927SAndroid Build Coastguard Worker VkResult
pvr_spm_init_eot_state(struct pvr_device * device,struct pvr_spm_eot_state * spm_eot_state,const struct pvr_framebuffer * framebuffer,const struct pvr_renderpass_hwsetup_render * hw_render,uint32_t * emit_count_out)614*61046927SAndroid Build Coastguard Worker pvr_spm_init_eot_state(struct pvr_device *device,
615*61046927SAndroid Build Coastguard Worker struct pvr_spm_eot_state *spm_eot_state,
616*61046927SAndroid Build Coastguard Worker const struct pvr_framebuffer *framebuffer,
617*61046927SAndroid Build Coastguard Worker const struct pvr_renderpass_hwsetup_render *hw_render,
618*61046927SAndroid Build Coastguard Worker uint32_t *emit_count_out)
619*61046927SAndroid Build Coastguard Worker {
620*61046927SAndroid Build Coastguard Worker const VkExtent2D framebuffer_size = {
621*61046927SAndroid Build Coastguard Worker .width = framebuffer->width,
622*61046927SAndroid Build Coastguard Worker .height = framebuffer->height,
623*61046927SAndroid Build Coastguard Worker };
624*61046927SAndroid Build Coastguard Worker uint32_t pbe_state_words[PVR_MAX_COLOR_ATTACHMENTS]
625*61046927SAndroid Build Coastguard Worker [ROGUE_NUM_PBESTATE_STATE_WORDS];
626*61046927SAndroid Build Coastguard Worker const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
627*61046927SAndroid Build Coastguard Worker uint32_t total_render_target_used = 0;
628*61046927SAndroid Build Coastguard Worker struct pvr_pds_upload pds_eot_program;
629*61046927SAndroid Build Coastguard Worker struct util_dynarray usc_shader_binary;
630*61046927SAndroid Build Coastguard Worker uint32_t usc_temp_count;
631*61046927SAndroid Build Coastguard Worker VkResult result;
632*61046927SAndroid Build Coastguard Worker
633*61046927SAndroid Build Coastguard Worker pvr_dev_addr_t next_scratch_buffer_addr =
634*61046927SAndroid Build Coastguard Worker framebuffer->scratch_buffer->bo->vma->dev_addr;
635*61046927SAndroid Build Coastguard Worker uint64_t mem_stored;
636*61046927SAndroid Build Coastguard Worker
637*61046927SAndroid Build Coastguard Worker /* TODO: See if instead of having a separate path for devices with 8 output
638*61046927SAndroid Build Coastguard Worker * regs we can instead do this in a loop and dedup some stuff.
639*61046927SAndroid Build Coastguard Worker */
640*61046927SAndroid Build Coastguard Worker assert(util_is_power_of_two_or_zero(hw_render->output_regs_count) &&
641*61046927SAndroid Build Coastguard Worker hw_render->output_regs_count <= 8);
642*61046927SAndroid Build Coastguard Worker if (hw_render->output_regs_count == 8) {
643*61046927SAndroid Build Coastguard Worker uint32_t render_targets_used;
644*61046927SAndroid Build Coastguard Worker
645*61046927SAndroid Build Coastguard Worker /* Store on-chip tile data (i.e. output regs). */
646*61046927SAndroid Build Coastguard Worker
647*61046927SAndroid Build Coastguard Worker mem_stored = pvr_spm_setup_pbe_eight_dword_write(
648*61046927SAndroid Build Coastguard Worker dev_info,
649*61046927SAndroid Build Coastguard Worker &framebuffer_size,
650*61046927SAndroid Build Coastguard Worker hw_render->sample_count,
651*61046927SAndroid Build Coastguard Worker USC_MRT_RESOURCE_TYPE_OUTPUT_REG,
652*61046927SAndroid Build Coastguard Worker 0,
653*61046927SAndroid Build Coastguard Worker next_scratch_buffer_addr,
654*61046927SAndroid Build Coastguard Worker pbe_state_words[total_render_target_used],
655*61046927SAndroid Build Coastguard Worker pbe_state_words[total_render_target_used + 1],
656*61046927SAndroid Build Coastguard Worker spm_eot_state->pbe_reg_words[total_render_target_used],
657*61046927SAndroid Build Coastguard Worker spm_eot_state->pbe_reg_words[total_render_target_used + 1],
658*61046927SAndroid Build Coastguard Worker &render_targets_used);
659*61046927SAndroid Build Coastguard Worker
660*61046927SAndroid Build Coastguard Worker PVR_DEV_ADDR_ADVANCE(next_scratch_buffer_addr, mem_stored);
661*61046927SAndroid Build Coastguard Worker total_render_target_used += render_targets_used;
662*61046927SAndroid Build Coastguard Worker
663*61046927SAndroid Build Coastguard Worker /* Store off-chip tile data (i.e. tile buffers). */
664*61046927SAndroid Build Coastguard Worker
665*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < hw_render->tile_buffers_count; i++) {
666*61046927SAndroid Build Coastguard Worker assert(!"Add support for tile buffers in EOT");
667*61046927SAndroid Build Coastguard Worker pvr_finishme("Add support for tile buffers in EOT");
668*61046927SAndroid Build Coastguard Worker
669*61046927SAndroid Build Coastguard Worker /* `+ 1` since we have 2 emits per tile buffer. */
670*61046927SAndroid Build Coastguard Worker assert(total_render_target_used + 1 < PVR_MAX_COLOR_ATTACHMENTS);
671*61046927SAndroid Build Coastguard Worker
672*61046927SAndroid Build Coastguard Worker mem_stored = pvr_spm_setup_pbe_eight_dword_write(
673*61046927SAndroid Build Coastguard Worker dev_info,
674*61046927SAndroid Build Coastguard Worker &framebuffer_size,
675*61046927SAndroid Build Coastguard Worker hw_render->sample_count,
676*61046927SAndroid Build Coastguard Worker USC_MRT_RESOURCE_TYPE_MEMORY,
677*61046927SAndroid Build Coastguard Worker i,
678*61046927SAndroid Build Coastguard Worker next_scratch_buffer_addr,
679*61046927SAndroid Build Coastguard Worker pbe_state_words[total_render_target_used],
680*61046927SAndroid Build Coastguard Worker pbe_state_words[total_render_target_used + 1],
681*61046927SAndroid Build Coastguard Worker spm_eot_state->pbe_reg_words[total_render_target_used],
682*61046927SAndroid Build Coastguard Worker spm_eot_state->pbe_reg_words[total_render_target_used + 1],
683*61046927SAndroid Build Coastguard Worker &render_targets_used);
684*61046927SAndroid Build Coastguard Worker
685*61046927SAndroid Build Coastguard Worker PVR_DEV_ADDR_ADVANCE(next_scratch_buffer_addr, mem_stored);
686*61046927SAndroid Build Coastguard Worker total_render_target_used += render_targets_used;
687*61046927SAndroid Build Coastguard Worker }
688*61046927SAndroid Build Coastguard Worker } else {
689*61046927SAndroid Build Coastguard Worker /* Store on-chip tile data (i.e. output regs). */
690*61046927SAndroid Build Coastguard Worker
691*61046927SAndroid Build Coastguard Worker mem_stored = pvr_spm_setup_pbe_state(
692*61046927SAndroid Build Coastguard Worker dev_info,
693*61046927SAndroid Build Coastguard Worker &framebuffer_size,
694*61046927SAndroid Build Coastguard Worker hw_render->output_regs_count,
695*61046927SAndroid Build Coastguard Worker PVR_PBE_STARTPOS_BIT0,
696*61046927SAndroid Build Coastguard Worker hw_render->sample_count,
697*61046927SAndroid Build Coastguard Worker next_scratch_buffer_addr,
698*61046927SAndroid Build Coastguard Worker pbe_state_words[total_render_target_used],
699*61046927SAndroid Build Coastguard Worker spm_eot_state->pbe_reg_words[total_render_target_used]);
700*61046927SAndroid Build Coastguard Worker
701*61046927SAndroid Build Coastguard Worker PVR_DEV_ADDR_ADVANCE(next_scratch_buffer_addr, mem_stored);
702*61046927SAndroid Build Coastguard Worker
703*61046927SAndroid Build Coastguard Worker total_render_target_used++;
704*61046927SAndroid Build Coastguard Worker
705*61046927SAndroid Build Coastguard Worker /* Store off-chip tile data (i.e. tile buffers). */
706*61046927SAndroid Build Coastguard Worker
707*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < hw_render->tile_buffers_count; i++) {
708*61046927SAndroid Build Coastguard Worker assert(!"Add support for tile buffers in EOT");
709*61046927SAndroid Build Coastguard Worker pvr_finishme("Add support for tile buffers in EOT");
710*61046927SAndroid Build Coastguard Worker
711*61046927SAndroid Build Coastguard Worker assert(total_render_target_used < PVR_MAX_COLOR_ATTACHMENTS);
712*61046927SAndroid Build Coastguard Worker
713*61046927SAndroid Build Coastguard Worker mem_stored = pvr_spm_setup_pbe_state(
714*61046927SAndroid Build Coastguard Worker dev_info,
715*61046927SAndroid Build Coastguard Worker &framebuffer_size,
716*61046927SAndroid Build Coastguard Worker hw_render->output_regs_count,
717*61046927SAndroid Build Coastguard Worker PVR_PBE_STARTPOS_BIT0,
718*61046927SAndroid Build Coastguard Worker hw_render->sample_count,
719*61046927SAndroid Build Coastguard Worker next_scratch_buffer_addr,
720*61046927SAndroid Build Coastguard Worker pbe_state_words[total_render_target_used],
721*61046927SAndroid Build Coastguard Worker spm_eot_state->pbe_reg_words[total_render_target_used]);
722*61046927SAndroid Build Coastguard Worker
723*61046927SAndroid Build Coastguard Worker PVR_DEV_ADDR_ADVANCE(next_scratch_buffer_addr, mem_stored);
724*61046927SAndroid Build Coastguard Worker
725*61046927SAndroid Build Coastguard Worker total_render_target_used++;
726*61046927SAndroid Build Coastguard Worker }
727*61046927SAndroid Build Coastguard Worker }
728*61046927SAndroid Build Coastguard Worker
729*61046927SAndroid Build Coastguard Worker pvr_uscgen_eot("SPM EOT",
730*61046927SAndroid Build Coastguard Worker total_render_target_used,
731*61046927SAndroid Build Coastguard Worker pbe_state_words[0],
732*61046927SAndroid Build Coastguard Worker &usc_temp_count,
733*61046927SAndroid Build Coastguard Worker &usc_shader_binary);
734*61046927SAndroid Build Coastguard Worker
735*61046927SAndroid Build Coastguard Worker /* TODO: Create a #define in the compiler code to replace the 16. */
736*61046927SAndroid Build Coastguard Worker result = pvr_gpu_upload_usc(device,
737*61046927SAndroid Build Coastguard Worker usc_shader_binary.data,
738*61046927SAndroid Build Coastguard Worker usc_shader_binary.size,
739*61046927SAndroid Build Coastguard Worker 16,
740*61046927SAndroid Build Coastguard Worker &spm_eot_state->usc_eot_program);
741*61046927SAndroid Build Coastguard Worker
742*61046927SAndroid Build Coastguard Worker util_dynarray_fini(&usc_shader_binary);
743*61046927SAndroid Build Coastguard Worker
744*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
745*61046927SAndroid Build Coastguard Worker return result;
746*61046927SAndroid Build Coastguard Worker
747*61046927SAndroid Build Coastguard Worker result = pvr_pds_pixel_event_program_create_and_upload(
748*61046927SAndroid Build Coastguard Worker device,
749*61046927SAndroid Build Coastguard Worker spm_eot_state->usc_eot_program,
750*61046927SAndroid Build Coastguard Worker usc_temp_count,
751*61046927SAndroid Build Coastguard Worker &pds_eot_program);
752*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
753*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(spm_eot_state->usc_eot_program);
754*61046927SAndroid Build Coastguard Worker return result;
755*61046927SAndroid Build Coastguard Worker }
756*61046927SAndroid Build Coastguard Worker
757*61046927SAndroid Build Coastguard Worker spm_eot_state->pixel_event_program_data_upload = pds_eot_program.pvr_bo;
758*61046927SAndroid Build Coastguard Worker spm_eot_state->pixel_event_program_data_offset = pds_eot_program.data_offset;
759*61046927SAndroid Build Coastguard Worker
760*61046927SAndroid Build Coastguard Worker *emit_count_out = total_render_target_used;
761*61046927SAndroid Build Coastguard Worker
762*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
763*61046927SAndroid Build Coastguard Worker }
764*61046927SAndroid Build Coastguard Worker
pvr_spm_finish_eot_state(struct pvr_device * device,struct pvr_spm_eot_state * spm_eot_state)765*61046927SAndroid Build Coastguard Worker void pvr_spm_finish_eot_state(struct pvr_device *device,
766*61046927SAndroid Build Coastguard Worker struct pvr_spm_eot_state *spm_eot_state)
767*61046927SAndroid Build Coastguard Worker {
768*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(spm_eot_state->pixel_event_program_data_upload);
769*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(spm_eot_state->usc_eot_program);
770*61046927SAndroid Build Coastguard Worker }
771*61046927SAndroid Build Coastguard Worker
pvr_get_format_from_dword_count(uint32_t dword_count)772*61046927SAndroid Build Coastguard Worker static VkFormat pvr_get_format_from_dword_count(uint32_t dword_count)
773*61046927SAndroid Build Coastguard Worker {
774*61046927SAndroid Build Coastguard Worker switch (dword_count) {
775*61046927SAndroid Build Coastguard Worker case 1:
776*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R32_UINT;
777*61046927SAndroid Build Coastguard Worker case 2:
778*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R32G32_UINT;
779*61046927SAndroid Build Coastguard Worker case 4:
780*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R32G32B32A32_UINT;
781*61046927SAndroid Build Coastguard Worker default:
782*61046927SAndroid Build Coastguard Worker unreachable("Invalid dword_count");
783*61046927SAndroid Build Coastguard Worker }
784*61046927SAndroid Build Coastguard Worker }
785*61046927SAndroid Build Coastguard Worker
pvr_spm_setup_texture_state_words(struct pvr_device * device,uint32_t dword_count,const VkExtent2D framebuffer_size,uint32_t sample_count,pvr_dev_addr_t scratch_buffer_addr,uint64_t image_descriptor[static const ROGUE_NUM_TEXSTATE_IMAGE_WORDS],uint64_t * mem_used_out)786*61046927SAndroid Build Coastguard Worker static VkResult pvr_spm_setup_texture_state_words(
787*61046927SAndroid Build Coastguard Worker struct pvr_device *device,
788*61046927SAndroid Build Coastguard Worker uint32_t dword_count,
789*61046927SAndroid Build Coastguard Worker const VkExtent2D framebuffer_size,
790*61046927SAndroid Build Coastguard Worker uint32_t sample_count,
791*61046927SAndroid Build Coastguard Worker pvr_dev_addr_t scratch_buffer_addr,
792*61046927SAndroid Build Coastguard Worker uint64_t image_descriptor[static const ROGUE_NUM_TEXSTATE_IMAGE_WORDS],
793*61046927SAndroid Build Coastguard Worker uint64_t *mem_used_out)
794*61046927SAndroid Build Coastguard Worker {
795*61046927SAndroid Build Coastguard Worker /* We can ignore the framebuffer's layer count since we only support
796*61046927SAndroid Build Coastguard Worker * writing to layer 0.
797*61046927SAndroid Build Coastguard Worker */
798*61046927SAndroid Build Coastguard Worker struct pvr_texture_state_info info = {
799*61046927SAndroid Build Coastguard Worker .format = pvr_get_format_from_dword_count(dword_count),
800*61046927SAndroid Build Coastguard Worker .mem_layout = PVR_MEMLAYOUT_LINEAR,
801*61046927SAndroid Build Coastguard Worker
802*61046927SAndroid Build Coastguard Worker .type = VK_IMAGE_VIEW_TYPE_2D,
803*61046927SAndroid Build Coastguard Worker .tex_state_type = PVR_TEXTURE_STATE_STORAGE,
804*61046927SAndroid Build Coastguard Worker .extent = {
805*61046927SAndroid Build Coastguard Worker .width = framebuffer_size.width,
806*61046927SAndroid Build Coastguard Worker .height = framebuffer_size.height,
807*61046927SAndroid Build Coastguard Worker },
808*61046927SAndroid Build Coastguard Worker
809*61046927SAndroid Build Coastguard Worker .mip_levels = 1,
810*61046927SAndroid Build Coastguard Worker
811*61046927SAndroid Build Coastguard Worker .sample_count = sample_count,
812*61046927SAndroid Build Coastguard Worker .stride = framebuffer_size.width,
813*61046927SAndroid Build Coastguard Worker
814*61046927SAndroid Build Coastguard Worker .addr = scratch_buffer_addr,
815*61046927SAndroid Build Coastguard Worker };
816*61046927SAndroid Build Coastguard Worker const uint64_t aligned_fb_width =
817*61046927SAndroid Build Coastguard Worker ALIGN_POT(framebuffer_size.width,
818*61046927SAndroid Build Coastguard Worker PVRX(CR_PBE_WORD0_MRT0_LINESTRIDE_ALIGNMENT));
819*61046927SAndroid Build Coastguard Worker const uint64_t fb_area = aligned_fb_width * framebuffer_size.height;
820*61046927SAndroid Build Coastguard Worker const uint8_t *format_swizzle;
821*61046927SAndroid Build Coastguard Worker VkResult result;
822*61046927SAndroid Build Coastguard Worker
823*61046927SAndroid Build Coastguard Worker format_swizzle = pvr_get_format_swizzle(info.format);
824*61046927SAndroid Build Coastguard Worker memcpy(info.swizzle, format_swizzle, sizeof(info.swizzle));
825*61046927SAndroid Build Coastguard Worker
826*61046927SAndroid Build Coastguard Worker result = pvr_pack_tex_state(device, &info, image_descriptor);
827*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
828*61046927SAndroid Build Coastguard Worker return result;
829*61046927SAndroid Build Coastguard Worker
830*61046927SAndroid Build Coastguard Worker *mem_used_out = fb_area * PVR_DW_TO_BYTES(dword_count) * sample_count;
831*61046927SAndroid Build Coastguard Worker
832*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
833*61046927SAndroid Build Coastguard Worker }
834*61046927SAndroid Build Coastguard Worker
835*61046927SAndroid Build Coastguard Worker /* FIXME: Can we dedup this with pvr_load_op_pds_data_create_and_upload() ? */
pvr_pds_bgnd_program_create_and_upload(struct pvr_device * device,uint32_t texture_program_data_size_in_dwords,const struct pvr_bo * consts_buffer,uint32_t const_shared_regs,struct pvr_pds_upload * pds_upload_out)836*61046927SAndroid Build Coastguard Worker static VkResult pvr_pds_bgnd_program_create_and_upload(
837*61046927SAndroid Build Coastguard Worker struct pvr_device *device,
838*61046927SAndroid Build Coastguard Worker uint32_t texture_program_data_size_in_dwords,
839*61046927SAndroid Build Coastguard Worker const struct pvr_bo *consts_buffer,
840*61046927SAndroid Build Coastguard Worker uint32_t const_shared_regs,
841*61046927SAndroid Build Coastguard Worker struct pvr_pds_upload *pds_upload_out)
842*61046927SAndroid Build Coastguard Worker {
843*61046927SAndroid Build Coastguard Worker const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
844*61046927SAndroid Build Coastguard Worker struct pvr_pds_pixel_shader_sa_program texture_program = { 0 };
845*61046927SAndroid Build Coastguard Worker uint32_t staging_buffer_size;
846*61046927SAndroid Build Coastguard Worker uint32_t *staging_buffer;
847*61046927SAndroid Build Coastguard Worker VkResult result;
848*61046927SAndroid Build Coastguard Worker
849*61046927SAndroid Build Coastguard Worker pvr_csb_pack (&texture_program.texture_dma_address[0],
850*61046927SAndroid Build Coastguard Worker PDSINST_DOUT_FIELDS_DOUTD_SRC0,
851*61046927SAndroid Build Coastguard Worker doutd_src0) {
852*61046927SAndroid Build Coastguard Worker doutd_src0.sbase = consts_buffer->vma->dev_addr;
853*61046927SAndroid Build Coastguard Worker }
854*61046927SAndroid Build Coastguard Worker
855*61046927SAndroid Build Coastguard Worker pvr_csb_pack (&texture_program.texture_dma_control[0],
856*61046927SAndroid Build Coastguard Worker PDSINST_DOUT_FIELDS_DOUTD_SRC1,
857*61046927SAndroid Build Coastguard Worker doutd_src1) {
858*61046927SAndroid Build Coastguard Worker doutd_src1.dest = PVRX(PDSINST_DOUTD_DEST_COMMON_STORE);
859*61046927SAndroid Build Coastguard Worker doutd_src1.bsize = const_shared_regs;
860*61046927SAndroid Build Coastguard Worker }
861*61046927SAndroid Build Coastguard Worker
862*61046927SAndroid Build Coastguard Worker texture_program.num_texture_dma_kicks += 1;
863*61046927SAndroid Build Coastguard Worker
864*61046927SAndroid Build Coastguard Worker #if MESA_DEBUG
865*61046927SAndroid Build Coastguard Worker pvr_pds_set_sizes_pixel_shader_sa_texture_data(&texture_program, dev_info);
866*61046927SAndroid Build Coastguard Worker assert(texture_program_data_size_in_dwords == texture_program.data_size);
867*61046927SAndroid Build Coastguard Worker #endif
868*61046927SAndroid Build Coastguard Worker
869*61046927SAndroid Build Coastguard Worker staging_buffer_size = PVR_DW_TO_BYTES(texture_program_data_size_in_dwords);
870*61046927SAndroid Build Coastguard Worker
871*61046927SAndroid Build Coastguard Worker staging_buffer = vk_alloc(&device->vk.alloc,
872*61046927SAndroid Build Coastguard Worker staging_buffer_size,
873*61046927SAndroid Build Coastguard Worker 8,
874*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
875*61046927SAndroid Build Coastguard Worker if (!staging_buffer)
876*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
877*61046927SAndroid Build Coastguard Worker
878*61046927SAndroid Build Coastguard Worker pvr_pds_generate_pixel_shader_sa_texture_state_data(&texture_program,
879*61046927SAndroid Build Coastguard Worker staging_buffer,
880*61046927SAndroid Build Coastguard Worker dev_info);
881*61046927SAndroid Build Coastguard Worker
882*61046927SAndroid Build Coastguard Worker /* FIXME: Figure out the define for alignment of 16. */
883*61046927SAndroid Build Coastguard Worker result = pvr_gpu_upload_pds(device,
884*61046927SAndroid Build Coastguard Worker &staging_buffer[0],
885*61046927SAndroid Build Coastguard Worker texture_program_data_size_in_dwords,
886*61046927SAndroid Build Coastguard Worker 16,
887*61046927SAndroid Build Coastguard Worker NULL,
888*61046927SAndroid Build Coastguard Worker 0,
889*61046927SAndroid Build Coastguard Worker 0,
890*61046927SAndroid Build Coastguard Worker 16,
891*61046927SAndroid Build Coastguard Worker pds_upload_out);
892*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
893*61046927SAndroid Build Coastguard Worker vk_free(&device->vk.alloc, staging_buffer);
894*61046927SAndroid Build Coastguard Worker return result;
895*61046927SAndroid Build Coastguard Worker }
896*61046927SAndroid Build Coastguard Worker
897*61046927SAndroid Build Coastguard Worker vk_free(&device->vk.alloc, staging_buffer);
898*61046927SAndroid Build Coastguard Worker
899*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
900*61046927SAndroid Build Coastguard Worker }
901*61046927SAndroid Build Coastguard Worker
902*61046927SAndroid Build Coastguard Worker VkResult
pvr_spm_init_bgobj_state(struct pvr_device * device,struct pvr_spm_bgobj_state * spm_bgobj_state,const struct pvr_framebuffer * framebuffer,const struct pvr_renderpass_hwsetup_render * hw_render,uint32_t emit_count)903*61046927SAndroid Build Coastguard Worker pvr_spm_init_bgobj_state(struct pvr_device *device,
904*61046927SAndroid Build Coastguard Worker struct pvr_spm_bgobj_state *spm_bgobj_state,
905*61046927SAndroid Build Coastguard Worker const struct pvr_framebuffer *framebuffer,
906*61046927SAndroid Build Coastguard Worker const struct pvr_renderpass_hwsetup_render *hw_render,
907*61046927SAndroid Build Coastguard Worker uint32_t emit_count)
908*61046927SAndroid Build Coastguard Worker {
909*61046927SAndroid Build Coastguard Worker const uint32_t spm_load_program_idx =
910*61046927SAndroid Build Coastguard Worker pvr_get_spm_load_program_index(hw_render->sample_count,
911*61046927SAndroid Build Coastguard Worker hw_render->tile_buffers_count,
912*61046927SAndroid Build Coastguard Worker hw_render->output_regs_count);
913*61046927SAndroid Build Coastguard Worker const VkExtent2D framebuffer_size = {
914*61046927SAndroid Build Coastguard Worker .width = framebuffer->width,
915*61046927SAndroid Build Coastguard Worker .height = framebuffer->height,
916*61046927SAndroid Build Coastguard Worker };
917*61046927SAndroid Build Coastguard Worker pvr_dev_addr_t next_scratch_buffer_addr =
918*61046927SAndroid Build Coastguard Worker framebuffer->scratch_buffer->bo->vma->dev_addr;
919*61046927SAndroid Build Coastguard Worker struct pvr_spm_per_load_program_state *load_program_state;
920*61046927SAndroid Build Coastguard Worker struct pvr_pds_upload pds_texture_data_upload;
921*61046927SAndroid Build Coastguard Worker const struct pvr_shader_factory_info *info;
922*61046927SAndroid Build Coastguard Worker union pvr_sampler_descriptor *descriptor;
923*61046927SAndroid Build Coastguard Worker uint64_t consts_buffer_size;
924*61046927SAndroid Build Coastguard Worker uint32_t dword_count;
925*61046927SAndroid Build Coastguard Worker uint32_t *mem_ptr;
926*61046927SAndroid Build Coastguard Worker VkResult result;
927*61046927SAndroid Build Coastguard Worker
928*61046927SAndroid Build Coastguard Worker assert(spm_load_program_idx < ARRAY_SIZE(spm_load_collection));
929*61046927SAndroid Build Coastguard Worker info = spm_load_collection[spm_load_program_idx].info;
930*61046927SAndroid Build Coastguard Worker
931*61046927SAndroid Build Coastguard Worker consts_buffer_size = PVR_DW_TO_BYTES(info->const_shared_regs);
932*61046927SAndroid Build Coastguard Worker
933*61046927SAndroid Build Coastguard Worker /* TODO: Remove this check, along with the pvr_finishme(), once the zeroed
934*61046927SAndroid Build Coastguard Worker * shaders are replaced by the real shaders.
935*61046927SAndroid Build Coastguard Worker */
936*61046927SAndroid Build Coastguard Worker if (!consts_buffer_size)
937*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
938*61046927SAndroid Build Coastguard Worker
939*61046927SAndroid Build Coastguard Worker pvr_finishme("Remove consts buffer size check");
940*61046927SAndroid Build Coastguard Worker
941*61046927SAndroid Build Coastguard Worker result = pvr_bo_alloc(device,
942*61046927SAndroid Build Coastguard Worker device->heaps.general_heap,
943*61046927SAndroid Build Coastguard Worker consts_buffer_size,
944*61046927SAndroid Build Coastguard Worker sizeof(uint32_t),
945*61046927SAndroid Build Coastguard Worker PVR_BO_ALLOC_FLAG_CPU_MAPPED,
946*61046927SAndroid Build Coastguard Worker &spm_bgobj_state->consts_buffer);
947*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
948*61046927SAndroid Build Coastguard Worker return result;
949*61046927SAndroid Build Coastguard Worker
950*61046927SAndroid Build Coastguard Worker mem_ptr = spm_bgobj_state->consts_buffer->bo->map;
951*61046927SAndroid Build Coastguard Worker
952*61046927SAndroid Build Coastguard Worker if (info->driver_const_location_map) {
953*61046927SAndroid Build Coastguard Worker const uint32_t *const const_map = info->driver_const_location_map;
954*61046927SAndroid Build Coastguard Worker
955*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < PVR_SPM_LOAD_CONST_COUNT; i += 2) {
956*61046927SAndroid Build Coastguard Worker pvr_dev_addr_t tile_buffer_addr;
957*61046927SAndroid Build Coastguard Worker
958*61046927SAndroid Build Coastguard Worker if (const_map[i] == PVR_SPM_LOAD_DEST_UNUSED) {
959*61046927SAndroid Build Coastguard Worker #if MESA_DEBUG
960*61046927SAndroid Build Coastguard Worker for (uint32_t j = i; j < PVR_SPM_LOAD_CONST_COUNT; j++)
961*61046927SAndroid Build Coastguard Worker assert(const_map[j] == PVR_SPM_LOAD_DEST_UNUSED);
962*61046927SAndroid Build Coastguard Worker #endif
963*61046927SAndroid Build Coastguard Worker break;
964*61046927SAndroid Build Coastguard Worker }
965*61046927SAndroid Build Coastguard Worker
966*61046927SAndroid Build Coastguard Worker tile_buffer_addr =
967*61046927SAndroid Build Coastguard Worker device->tile_buffer_state.buffers[i / 2]->vma->dev_addr;
968*61046927SAndroid Build Coastguard Worker
969*61046927SAndroid Build Coastguard Worker assert(const_map[i] == const_map[i + 1] + 1);
970*61046927SAndroid Build Coastguard Worker mem_ptr[const_map[i]] = tile_buffer_addr.addr >> 32;
971*61046927SAndroid Build Coastguard Worker mem_ptr[const_map[i + 1]] = (uint32_t)tile_buffer_addr.addr;
972*61046927SAndroid Build Coastguard Worker }
973*61046927SAndroid Build Coastguard Worker }
974*61046927SAndroid Build Coastguard Worker
975*61046927SAndroid Build Coastguard Worker /* TODO: The 32 comes from how the shaders are compiled. We should
976*61046927SAndroid Build Coastguard Worker * unhardcode it when this is hooked up to the compiler.
977*61046927SAndroid Build Coastguard Worker */
978*61046927SAndroid Build Coastguard Worker descriptor = (union pvr_sampler_descriptor *)(mem_ptr + 32);
979*61046927SAndroid Build Coastguard Worker *descriptor = (union pvr_sampler_descriptor){ 0 };
980*61046927SAndroid Build Coastguard Worker
981*61046927SAndroid Build Coastguard Worker pvr_csb_pack (&descriptor->data.sampler_word, TEXSTATE_SAMPLER, sampler) {
982*61046927SAndroid Build Coastguard Worker sampler.non_normalized_coords = true;
983*61046927SAndroid Build Coastguard Worker sampler.addrmode_v = PVRX(TEXSTATE_ADDRMODE_CLAMP_TO_EDGE);
984*61046927SAndroid Build Coastguard Worker sampler.addrmode_u = PVRX(TEXSTATE_ADDRMODE_CLAMP_TO_EDGE);
985*61046927SAndroid Build Coastguard Worker sampler.minfilter = PVRX(TEXSTATE_FILTER_POINT);
986*61046927SAndroid Build Coastguard Worker sampler.magfilter = PVRX(TEXSTATE_FILTER_POINT);
987*61046927SAndroid Build Coastguard Worker sampler.maxlod = PVRX(TEXSTATE_CLAMP_MIN);
988*61046927SAndroid Build Coastguard Worker sampler.minlod = PVRX(TEXSTATE_CLAMP_MIN);
989*61046927SAndroid Build Coastguard Worker sampler.dadjust = PVRX(TEXSTATE_DADJUST_ZERO_UINT);
990*61046927SAndroid Build Coastguard Worker }
991*61046927SAndroid Build Coastguard Worker
992*61046927SAndroid Build Coastguard Worker /* Even if we might have 8 output regs we can only pack and write 4 dwords
993*61046927SAndroid Build Coastguard Worker * using R32G32B32A32_UINT.
994*61046927SAndroid Build Coastguard Worker */
995*61046927SAndroid Build Coastguard Worker if (hw_render->tile_buffers_count > 0)
996*61046927SAndroid Build Coastguard Worker dword_count = 4;
997*61046927SAndroid Build Coastguard Worker else
998*61046927SAndroid Build Coastguard Worker dword_count = MIN2(hw_render->output_regs_count, 4);
999*61046927SAndroid Build Coastguard Worker
1000*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < emit_count; i++) {
1001*61046927SAndroid Build Coastguard Worker uint64_t *mem_ptr_u64 = (uint64_t *)mem_ptr;
1002*61046927SAndroid Build Coastguard Worker uint64_t mem_used = 0;
1003*61046927SAndroid Build Coastguard Worker
1004*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(ROGUE_NUM_TEXSTATE_IMAGE_WORDS * sizeof(uint64_t) /
1005*61046927SAndroid Build Coastguard Worker sizeof(uint32_t) ==
1006*61046927SAndroid Build Coastguard Worker PVR_IMAGE_DESCRIPTOR_SIZE);
1007*61046927SAndroid Build Coastguard Worker mem_ptr_u64 += i * ROGUE_NUM_TEXSTATE_IMAGE_WORDS;
1008*61046927SAndroid Build Coastguard Worker
1009*61046927SAndroid Build Coastguard Worker result = pvr_spm_setup_texture_state_words(device,
1010*61046927SAndroid Build Coastguard Worker dword_count,
1011*61046927SAndroid Build Coastguard Worker framebuffer_size,
1012*61046927SAndroid Build Coastguard Worker hw_render->sample_count,
1013*61046927SAndroid Build Coastguard Worker next_scratch_buffer_addr,
1014*61046927SAndroid Build Coastguard Worker mem_ptr_u64,
1015*61046927SAndroid Build Coastguard Worker &mem_used);
1016*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1017*61046927SAndroid Build Coastguard Worker goto err_free_consts_buffer;
1018*61046927SAndroid Build Coastguard Worker
1019*61046927SAndroid Build Coastguard Worker PVR_DEV_ADDR_ADVANCE(next_scratch_buffer_addr, mem_used);
1020*61046927SAndroid Build Coastguard Worker }
1021*61046927SAndroid Build Coastguard Worker
1022*61046927SAndroid Build Coastguard Worker assert(spm_load_program_idx <
1023*61046927SAndroid Build Coastguard Worker ARRAY_SIZE(device->spm_load_state.load_program));
1024*61046927SAndroid Build Coastguard Worker load_program_state =
1025*61046927SAndroid Build Coastguard Worker &device->spm_load_state.load_program[spm_load_program_idx];
1026*61046927SAndroid Build Coastguard Worker
1027*61046927SAndroid Build Coastguard Worker result = pvr_pds_bgnd_program_create_and_upload(
1028*61046927SAndroid Build Coastguard Worker device,
1029*61046927SAndroid Build Coastguard Worker load_program_state->pds_texture_program_data_size,
1030*61046927SAndroid Build Coastguard Worker spm_bgobj_state->consts_buffer,
1031*61046927SAndroid Build Coastguard Worker info->const_shared_regs,
1032*61046927SAndroid Build Coastguard Worker &pds_texture_data_upload);
1033*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1034*61046927SAndroid Build Coastguard Worker goto err_free_consts_buffer;
1035*61046927SAndroid Build Coastguard Worker
1036*61046927SAndroid Build Coastguard Worker spm_bgobj_state->pds_texture_data_upload = pds_texture_data_upload.pvr_bo;
1037*61046927SAndroid Build Coastguard Worker
1038*61046927SAndroid Build Coastguard Worker /* TODO: Is it worth to dedup this with pvr_pds_bgnd_pack_state() ? */
1039*61046927SAndroid Build Coastguard Worker
1040*61046927SAndroid Build Coastguard Worker /* clang-format off */
1041*61046927SAndroid Build Coastguard Worker pvr_csb_pack (&spm_bgobj_state->pds_reg_values[0],
1042*61046927SAndroid Build Coastguard Worker CR_PDS_BGRND0_BASE,
1043*61046927SAndroid Build Coastguard Worker value) {
1044*61046927SAndroid Build Coastguard Worker /* clang-format on */
1045*61046927SAndroid Build Coastguard Worker value.shader_addr = load_program_state->pds_pixel_program_offset;
1046*61046927SAndroid Build Coastguard Worker value.texunicode_addr = load_program_state->pds_uniform_program_offset;
1047*61046927SAndroid Build Coastguard Worker }
1048*61046927SAndroid Build Coastguard Worker
1049*61046927SAndroid Build Coastguard Worker /* clang-format off */
1050*61046927SAndroid Build Coastguard Worker pvr_csb_pack (&spm_bgobj_state->pds_reg_values[1],
1051*61046927SAndroid Build Coastguard Worker CR_PDS_BGRND1_BASE,
1052*61046927SAndroid Build Coastguard Worker value) {
1053*61046927SAndroid Build Coastguard Worker /* clang-format on */
1054*61046927SAndroid Build Coastguard Worker value.texturedata_addr =
1055*61046927SAndroid Build Coastguard Worker PVR_DEV_ADDR(pds_texture_data_upload.data_offset);
1056*61046927SAndroid Build Coastguard Worker }
1057*61046927SAndroid Build Coastguard Worker
1058*61046927SAndroid Build Coastguard Worker /* clang-format off */
1059*61046927SAndroid Build Coastguard Worker pvr_csb_pack (&spm_bgobj_state->pds_reg_values[2],
1060*61046927SAndroid Build Coastguard Worker CR_PDS_BGRND3_SIZEINFO,
1061*61046927SAndroid Build Coastguard Worker value) {
1062*61046927SAndroid Build Coastguard Worker /* clang-format on */
1063*61046927SAndroid Build Coastguard Worker value.usc_sharedsize =
1064*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(info->const_shared_regs,
1065*61046927SAndroid Build Coastguard Worker PVRX(CR_PDS_BGRND3_SIZEINFO_USC_SHAREDSIZE_UNIT_SIZE));
1066*61046927SAndroid Build Coastguard Worker value.pds_texturestatesize = DIV_ROUND_UP(
1067*61046927SAndroid Build Coastguard Worker pds_texture_data_upload.data_size,
1068*61046927SAndroid Build Coastguard Worker PVRX(CR_PDS_BGRND3_SIZEINFO_PDS_TEXTURESTATESIZE_UNIT_SIZE));
1069*61046927SAndroid Build Coastguard Worker value.pds_tempsize =
1070*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(load_program_state->pds_texture_program_temps_count,
1071*61046927SAndroid Build Coastguard Worker PVRX(CR_PDS_BGRND3_SIZEINFO_PDS_TEMPSIZE_UNIT_SIZE));
1072*61046927SAndroid Build Coastguard Worker }
1073*61046927SAndroid Build Coastguard Worker
1074*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1075*61046927SAndroid Build Coastguard Worker
1076*61046927SAndroid Build Coastguard Worker err_free_consts_buffer:
1077*61046927SAndroid Build Coastguard Worker pvr_bo_free(device, spm_bgobj_state->consts_buffer);
1078*61046927SAndroid Build Coastguard Worker
1079*61046927SAndroid Build Coastguard Worker return result;
1080*61046927SAndroid Build Coastguard Worker }
1081*61046927SAndroid Build Coastguard Worker
pvr_spm_finish_bgobj_state(struct pvr_device * device,struct pvr_spm_bgobj_state * spm_bgobj_state)1082*61046927SAndroid Build Coastguard Worker void pvr_spm_finish_bgobj_state(struct pvr_device *device,
1083*61046927SAndroid Build Coastguard Worker struct pvr_spm_bgobj_state *spm_bgobj_state)
1084*61046927SAndroid Build Coastguard Worker {
1085*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(spm_bgobj_state->pds_texture_data_upload);
1086*61046927SAndroid Build Coastguard Worker pvr_bo_free(device, spm_bgobj_state->consts_buffer);
1087*61046927SAndroid Build Coastguard Worker }
1088*61046927SAndroid Build Coastguard Worker
1089*61046927SAndroid Build Coastguard Worker #undef PVR_DEV_ADDR_ADVANCE
1090