1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2022 Imagination Technologies Ltd. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 5bf215546Sopenharmony_ci * of this software and associated documentation files (the "Software"), to deal 6bf215546Sopenharmony_ci * in the Software without restriction, including without limitation the rights 7bf215546Sopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8bf215546Sopenharmony_ci * copies of the Software, and to permit persons to whom the Software is 9bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18bf215546Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21bf215546Sopenharmony_ci * SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include <assert.h> 25bf215546Sopenharmony_ci#include <stdbool.h> 26bf215546Sopenharmony_ci#include <stdint.h> 27bf215546Sopenharmony_ci#include <vulkan/vulkan.h> 28bf215546Sopenharmony_ci#include <xf86drm.h> 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "pvr_private.h" 31bf215546Sopenharmony_ci#include "pvr_types.h" 32bf215546Sopenharmony_ci#include "pvr_winsys.h" 33bf215546Sopenharmony_ci#include "pvr_winsys_helper.h" 34bf215546Sopenharmony_ci#include "util/u_atomic.h" 35bf215546Sopenharmony_ci#include "vk_log.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ciint pvr_winsys_helper_display_buffer_create(int master_fd, 38bf215546Sopenharmony_ci uint64_t size, 39bf215546Sopenharmony_ci uint32_t *const handle_out) 40bf215546Sopenharmony_ci{ 41bf215546Sopenharmony_ci struct drm_mode_create_dumb args = { 42bf215546Sopenharmony_ci .width = size, 43bf215546Sopenharmony_ci .height = 1, 44bf215546Sopenharmony_ci .bpp = 8, 45bf215546Sopenharmony_ci }; 46bf215546Sopenharmony_ci int ret; 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci ret = drmIoctl(master_fd, DRM_IOCTL_MODE_CREATE_DUMB, &args); 49bf215546Sopenharmony_ci if (ret) 50bf215546Sopenharmony_ci return ret; 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci *handle_out = args.handle; 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ci return 0; 55bf215546Sopenharmony_ci} 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ciint pvr_winsys_helper_display_buffer_destroy(int master_fd, uint32_t handle) 58bf215546Sopenharmony_ci{ 59bf215546Sopenharmony_ci struct drm_mode_destroy_dumb args = { 60bf215546Sopenharmony_ci .handle = handle, 61bf215546Sopenharmony_ci }; 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci return drmIoctl(master_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &args); 64bf215546Sopenharmony_ci} 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci/* reserved_size can be 0 when no reserved area is needed. reserved_address must 67bf215546Sopenharmony_ci * be 0 if reserved_size is 0. 68bf215546Sopenharmony_ci */ 69bf215546Sopenharmony_ciVkResult pvr_winsys_helper_winsys_heap_init( 70bf215546Sopenharmony_ci struct pvr_winsys *const ws, 71bf215546Sopenharmony_ci pvr_dev_addr_t base_address, 72bf215546Sopenharmony_ci uint64_t size, 73bf215546Sopenharmony_ci pvr_dev_addr_t reserved_address, 74bf215546Sopenharmony_ci uint64_t reserved_size, 75bf215546Sopenharmony_ci uint32_t log2_page_size, 76bf215546Sopenharmony_ci const struct pvr_winsys_static_data_offsets *const static_data_offsets, 77bf215546Sopenharmony_ci struct pvr_winsys_heap *const heap) 78bf215546Sopenharmony_ci{ 79bf215546Sopenharmony_ci const bool reserved_area_bottom_of_heap = reserved_address.addr == 80bf215546Sopenharmony_ci base_address.addr; 81bf215546Sopenharmony_ci const pvr_dev_addr_t vma_heap_begin_addr = 82bf215546Sopenharmony_ci reserved_area_bottom_of_heap 83bf215546Sopenharmony_ci ? PVR_DEV_ADDR_OFFSET(base_address, reserved_size) 84bf215546Sopenharmony_ci : base_address; 85bf215546Sopenharmony_ci const uint64_t vma_heap_size = size - reserved_size; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci assert(base_address.addr); 88bf215546Sopenharmony_ci assert(reserved_size <= size); 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci /* As per the reserved_base powervr-km uapi documentation the reserved 91bf215546Sopenharmony_ci * region can only be at the beginning of the heap or at the end. 92bf215546Sopenharmony_ci * reserved_address is 0 if there is no reserved region. 93bf215546Sopenharmony_ci * pvrsrv-km doesn't explicitly provide this info and it's assumed that it's 94bf215546Sopenharmony_ci * always at the beginning. 95bf215546Sopenharmony_ci */ 96bf215546Sopenharmony_ci assert(reserved_area_bottom_of_heap || 97bf215546Sopenharmony_ci reserved_address.addr + reserved_size == base_address.addr + size || 98bf215546Sopenharmony_ci (!reserved_address.addr && !reserved_size)); 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci heap->ws = ws; 101bf215546Sopenharmony_ci heap->base_addr = base_address; 102bf215546Sopenharmony_ci heap->reserved_addr = reserved_address; 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci heap->size = size; 105bf215546Sopenharmony_ci heap->reserved_size = reserved_size; 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci heap->page_size = 1 << log2_page_size; 108bf215546Sopenharmony_ci heap->log2_page_size = log2_page_size; 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci util_vma_heap_init(&heap->vma_heap, vma_heap_begin_addr.addr, vma_heap_size); 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci heap->vma_heap.alloc_high = false; 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci /* It's expected that the heap destroy function to be the last thing that's 115bf215546Sopenharmony_ci * called, so we start the ref_count at 0. 116bf215546Sopenharmony_ci */ 117bf215546Sopenharmony_ci p_atomic_set(&heap->ref_count, 0); 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci if (pthread_mutex_init(&heap->lock, NULL)) 120bf215546Sopenharmony_ci return vk_error(NULL, VK_ERROR_INITIALIZATION_FAILED); 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci heap->static_data_offsets = *static_data_offsets; 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci return VK_SUCCESS; 125bf215546Sopenharmony_ci} 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_cibool pvr_winsys_helper_winsys_heap_finish(struct pvr_winsys_heap *const heap) 128bf215546Sopenharmony_ci{ 129bf215546Sopenharmony_ci if (p_atomic_read(&heap->ref_count) != 0) 130bf215546Sopenharmony_ci return false; 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci pthread_mutex_destroy(&heap->lock); 133bf215546Sopenharmony_ci util_vma_heap_finish(&heap->vma_heap); 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci return true; 136bf215546Sopenharmony_ci} 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_cibool pvr_winsys_helper_heap_alloc(struct pvr_winsys_heap *const heap, 139bf215546Sopenharmony_ci uint64_t size, 140bf215546Sopenharmony_ci uint64_t alignment, 141bf215546Sopenharmony_ci struct pvr_winsys_vma *const vma_out) 142bf215546Sopenharmony_ci{ 143bf215546Sopenharmony_ci struct pvr_winsys_vma vma = { 144bf215546Sopenharmony_ci .heap = heap, 145bf215546Sopenharmony_ci }; 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci assert(util_is_power_of_two_nonzero(alignment)); 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci /* pvr_srv_winsys_buffer_create() page aligns the size. We must do the same 150bf215546Sopenharmony_ci * here to ensure enough heap space is allocated to be able to map the 151bf215546Sopenharmony_ci * buffer to the GPU. 152bf215546Sopenharmony_ci * We have to do this for the powervr kernel mode driver as well, as it 153bf215546Sopenharmony_ci * returns a page aligned size when allocating buffers. 154bf215546Sopenharmony_ci */ 155bf215546Sopenharmony_ci alignment = MAX2(alignment, heap->page_size); 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci size = ALIGN_POT(size, alignment); 158bf215546Sopenharmony_ci vma.size = size; 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci pthread_mutex_lock(&heap->lock); 161bf215546Sopenharmony_ci vma.dev_addr = 162bf215546Sopenharmony_ci PVR_DEV_ADDR(util_vma_heap_alloc(&heap->vma_heap, size, heap->page_size)); 163bf215546Sopenharmony_ci pthread_mutex_unlock(&heap->lock); 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci if (!vma.dev_addr.addr) { 166bf215546Sopenharmony_ci vk_error(NULL, VK_ERROR_OUT_OF_DEVICE_MEMORY); 167bf215546Sopenharmony_ci return false; 168bf215546Sopenharmony_ci } 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci p_atomic_inc(&heap->ref_count); 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci *vma_out = vma; 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci return true; 175bf215546Sopenharmony_ci} 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_civoid pvr_winsys_helper_heap_free(struct pvr_winsys_vma *const vma) 178bf215546Sopenharmony_ci{ 179bf215546Sopenharmony_ci struct pvr_winsys_heap *const heap = vma->heap; 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci /* A vma with an existing device mapping should not be freed. */ 182bf215546Sopenharmony_ci assert(!vma->bo); 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci pthread_mutex_lock(&heap->lock); 185bf215546Sopenharmony_ci util_vma_heap_free(&heap->vma_heap, vma->dev_addr.addr, vma->size); 186bf215546Sopenharmony_ci pthread_mutex_unlock(&heap->lock); 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci p_atomic_dec(&heap->ref_count); 189bf215546Sopenharmony_ci} 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci/* Note: the function assumes the heap allocation in the reserved memory area 192bf215546Sopenharmony_ci * can be freed with the regular heap allocation free function. The free 193bf215546Sopenharmony_ci * function gets called on mapping failure. 194bf215546Sopenharmony_ci */ 195bf215546Sopenharmony_cistatic VkResult 196bf215546Sopenharmony_cipvr_buffer_create_and_map(struct pvr_winsys *const ws, 197bf215546Sopenharmony_ci heap_alloc_reserved_func heap_alloc_reserved, 198bf215546Sopenharmony_ci struct pvr_winsys_heap *heap, 199bf215546Sopenharmony_ci pvr_dev_addr_t dev_addr, 200bf215546Sopenharmony_ci uint64_t size, 201bf215546Sopenharmony_ci uint64_t alignment, 202bf215546Sopenharmony_ci struct pvr_winsys_vma **const vma_out) 203bf215546Sopenharmony_ci{ 204bf215546Sopenharmony_ci struct pvr_winsys_vma *vma; 205bf215546Sopenharmony_ci struct pvr_winsys_bo *bo; 206bf215546Sopenharmony_ci pvr_dev_addr_t addr; 207bf215546Sopenharmony_ci VkResult result; 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci /* Address should not be NULL, this function is used to allocate and map 210bf215546Sopenharmony_ci * reserved addresses and is only supposed to be used internally. 211bf215546Sopenharmony_ci */ 212bf215546Sopenharmony_ci assert(dev_addr.addr); 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci result = ws->ops->buffer_create(ws, 215bf215546Sopenharmony_ci size, 216bf215546Sopenharmony_ci alignment, 217bf215546Sopenharmony_ci PVR_WINSYS_BO_TYPE_GPU, 218bf215546Sopenharmony_ci PVR_WINSYS_BO_FLAG_CPU_ACCESS, 219bf215546Sopenharmony_ci &bo); 220bf215546Sopenharmony_ci if (result != VK_SUCCESS) 221bf215546Sopenharmony_ci return result; 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci vma = heap_alloc_reserved(heap, dev_addr, size, alignment); 224bf215546Sopenharmony_ci if (!vma) { 225bf215546Sopenharmony_ci result = VK_ERROR_OUT_OF_DEVICE_MEMORY; 226bf215546Sopenharmony_ci goto err_pvr_winsys_buffer_destroy; 227bf215546Sopenharmony_ci } 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci addr = ws->ops->vma_map(vma, bo, 0, size); 230bf215546Sopenharmony_ci if (!addr.addr) { 231bf215546Sopenharmony_ci result = VK_ERROR_MEMORY_MAP_FAILED; 232bf215546Sopenharmony_ci goto err_pvr_winsys_heap_free; 233bf215546Sopenharmony_ci } 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci /* Note this won't destroy bo as its being used by VMA, once vma is 236bf215546Sopenharmony_ci * unmapped, bo will be destroyed automatically. 237bf215546Sopenharmony_ci */ 238bf215546Sopenharmony_ci ws->ops->buffer_destroy(bo); 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_ci *vma_out = vma; 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_ci return VK_SUCCESS; 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_cierr_pvr_winsys_heap_free: 245bf215546Sopenharmony_ci ws->ops->heap_free(vma); 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_cierr_pvr_winsys_buffer_destroy: 248bf215546Sopenharmony_ci ws->ops->buffer_destroy(bo); 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci return result; 251bf215546Sopenharmony_ci} 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_cistatic void inline pvr_buffer_destroy_and_unmap(struct pvr_winsys_vma *vma) 254bf215546Sopenharmony_ci{ 255bf215546Sopenharmony_ci const struct pvr_winsys *const ws = vma->heap->ws; 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci /* Buffer object associated with the vma will be automatically destroyed 258bf215546Sopenharmony_ci * once vma is unmapped. 259bf215546Sopenharmony_ci */ 260bf215546Sopenharmony_ci ws->ops->vma_unmap(vma); 261bf215546Sopenharmony_ci ws->ops->heap_free(vma); 262bf215546Sopenharmony_ci} 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ciVkResult pvr_winsys_helper_allocate_static_memory( 265bf215546Sopenharmony_ci struct pvr_winsys *const ws, 266bf215546Sopenharmony_ci heap_alloc_reserved_func heap_alloc_reserved, 267bf215546Sopenharmony_ci struct pvr_winsys_heap *const general_heap, 268bf215546Sopenharmony_ci struct pvr_winsys_heap *const pds_heap, 269bf215546Sopenharmony_ci struct pvr_winsys_heap *const usc_heap, 270bf215546Sopenharmony_ci struct pvr_winsys_vma **const general_vma_out, 271bf215546Sopenharmony_ci struct pvr_winsys_vma **const pds_vma_out, 272bf215546Sopenharmony_ci struct pvr_winsys_vma **const usc_vma_out) 273bf215546Sopenharmony_ci{ 274bf215546Sopenharmony_ci struct pvr_winsys_vma *general_vma; 275bf215546Sopenharmony_ci struct pvr_winsys_vma *pds_vma; 276bf215546Sopenharmony_ci struct pvr_winsys_vma *usc_vma; 277bf215546Sopenharmony_ci VkResult result; 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci result = pvr_buffer_create_and_map(ws, 280bf215546Sopenharmony_ci heap_alloc_reserved, 281bf215546Sopenharmony_ci general_heap, 282bf215546Sopenharmony_ci general_heap->reserved_addr, 283bf215546Sopenharmony_ci general_heap->reserved_size, 284bf215546Sopenharmony_ci general_heap->page_size, 285bf215546Sopenharmony_ci &general_vma); 286bf215546Sopenharmony_ci if (result != VK_SUCCESS) 287bf215546Sopenharmony_ci return result; 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci result = pvr_buffer_create_and_map(ws, 290bf215546Sopenharmony_ci heap_alloc_reserved, 291bf215546Sopenharmony_ci pds_heap, 292bf215546Sopenharmony_ci pds_heap->reserved_addr, 293bf215546Sopenharmony_ci pds_heap->reserved_size, 294bf215546Sopenharmony_ci pds_heap->page_size, 295bf215546Sopenharmony_ci &pds_vma); 296bf215546Sopenharmony_ci if (result != VK_SUCCESS) 297bf215546Sopenharmony_ci goto err_pvr_buffer_destroy_and_unmap_general; 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci result = pvr_buffer_create_and_map(ws, 300bf215546Sopenharmony_ci heap_alloc_reserved, 301bf215546Sopenharmony_ci usc_heap, 302bf215546Sopenharmony_ci usc_heap->reserved_addr, 303bf215546Sopenharmony_ci pds_heap->reserved_size, 304bf215546Sopenharmony_ci usc_heap->page_size, 305bf215546Sopenharmony_ci &usc_vma); 306bf215546Sopenharmony_ci if (result != VK_SUCCESS) 307bf215546Sopenharmony_ci goto err_pvr_buffer_destroy_and_unmap_pds; 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_ci *general_vma_out = general_vma; 310bf215546Sopenharmony_ci *pds_vma_out = pds_vma; 311bf215546Sopenharmony_ci *usc_vma_out = usc_vma; 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci return VK_SUCCESS; 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_cierr_pvr_buffer_destroy_and_unmap_pds: 316bf215546Sopenharmony_ci pvr_buffer_destroy_and_unmap(pds_vma); 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_cierr_pvr_buffer_destroy_and_unmap_general: 319bf215546Sopenharmony_ci pvr_buffer_destroy_and_unmap(general_vma); 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci return result; 322bf215546Sopenharmony_ci} 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_civoid pvr_winsys_helper_free_static_memory( 325bf215546Sopenharmony_ci struct pvr_winsys_vma *const general_vma, 326bf215546Sopenharmony_ci struct pvr_winsys_vma *const pds_vma, 327bf215546Sopenharmony_ci struct pvr_winsys_vma *const usc_vma) 328bf215546Sopenharmony_ci{ 329bf215546Sopenharmony_ci pvr_buffer_destroy_and_unmap(usc_vma); 330bf215546Sopenharmony_ci pvr_buffer_destroy_and_unmap(pds_vma); 331bf215546Sopenharmony_ci pvr_buffer_destroy_and_unmap(general_vma); 332bf215546Sopenharmony_ci} 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_cistatic void pvr_setup_static_vdm_sync(uint8_t *const pds_ptr, 335bf215546Sopenharmony_ci uint64_t pds_sync_offset_in_bytes, 336bf215546Sopenharmony_ci uint8_t *const usc_ptr, 337bf215546Sopenharmony_ci uint64_t usc_sync_offset_in_bytes) 338bf215546Sopenharmony_ci{ 339bf215546Sopenharmony_ci /* TODO: this needs to be auto-generated */ 340bf215546Sopenharmony_ci const uint8_t state_update[] = { 0x44, 0xA0, 0x80, 0x05, 341bf215546Sopenharmony_ci 0x00, 0x00, 0x00, 0xFF }; 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci struct pvr_pds_kickusc_program ppp_state_update_program = { 0 }; 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci memcpy(usc_ptr + usc_sync_offset_in_bytes, 346bf215546Sopenharmony_ci state_update, 347bf215546Sopenharmony_ci sizeof(state_update)); 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_ci pvr_pds_setup_doutu(&ppp_state_update_program.usc_task_control, 350bf215546Sopenharmony_ci usc_sync_offset_in_bytes, 351bf215546Sopenharmony_ci 0, 352bf215546Sopenharmony_ci PVRX(PDSINST_DOUTU_SAMPLE_RATE_INSTANCE), 353bf215546Sopenharmony_ci false); 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci pvr_pds_kick_usc(&ppp_state_update_program, 356bf215546Sopenharmony_ci (uint32_t *)&pds_ptr[pds_sync_offset_in_bytes], 357bf215546Sopenharmony_ci 0, 358bf215546Sopenharmony_ci false, 359bf215546Sopenharmony_ci PDS_GENERATE_CODEDATA_SEGMENTS); 360bf215546Sopenharmony_ci} 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_cistatic void 363bf215546Sopenharmony_cipvr_setup_static_pixel_event_program(uint8_t *const pds_ptr, 364bf215546Sopenharmony_ci uint64_t pds_eot_offset_in_bytes) 365bf215546Sopenharmony_ci{ 366bf215546Sopenharmony_ci struct pvr_pds_event_program pixel_event_program = { 0 }; 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci pvr_pds_generate_pixel_event(&pixel_event_program, 369bf215546Sopenharmony_ci (uint32_t *)&pds_ptr[pds_eot_offset_in_bytes], 370bf215546Sopenharmony_ci PDS_GENERATE_CODE_SEGMENT, 371bf215546Sopenharmony_ci NULL); 372bf215546Sopenharmony_ci} 373bf215546Sopenharmony_ci 374bf215546Sopenharmony_ciVkResult 375bf215546Sopenharmony_cipvr_winsys_helper_fill_static_memory(struct pvr_winsys *const ws, 376bf215546Sopenharmony_ci struct pvr_winsys_vma *const general_vma, 377bf215546Sopenharmony_ci struct pvr_winsys_vma *const pds_vma, 378bf215546Sopenharmony_ci struct pvr_winsys_vma *const usc_vma) 379bf215546Sopenharmony_ci{ 380bf215546Sopenharmony_ci uint8_t *general_ptr, *pds_ptr, *usc_ptr; 381bf215546Sopenharmony_ci VkResult result; 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci general_ptr = ws->ops->buffer_map(general_vma->bo); 384bf215546Sopenharmony_ci if (!general_ptr) 385bf215546Sopenharmony_ci return VK_ERROR_MEMORY_MAP_FAILED; 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci pds_ptr = ws->ops->buffer_map(pds_vma->bo); 388bf215546Sopenharmony_ci if (!pds_ptr) { 389bf215546Sopenharmony_ci result = VK_ERROR_MEMORY_MAP_FAILED; 390bf215546Sopenharmony_ci goto err_pvr_srv_winsys_buffer_unmap_general; 391bf215546Sopenharmony_ci } 392bf215546Sopenharmony_ci 393bf215546Sopenharmony_ci usc_ptr = ws->ops->buffer_map(usc_vma->bo); 394bf215546Sopenharmony_ci if (!usc_ptr) { 395bf215546Sopenharmony_ci result = VK_ERROR_MEMORY_MAP_FAILED; 396bf215546Sopenharmony_ci goto err_pvr_srv_winsys_buffer_unmap_pds; 397bf215546Sopenharmony_ci } 398bf215546Sopenharmony_ci 399bf215546Sopenharmony_ci pvr_setup_static_vdm_sync(pds_ptr, 400bf215546Sopenharmony_ci pds_vma->heap->static_data_offsets.vdm_sync, 401bf215546Sopenharmony_ci usc_ptr, 402bf215546Sopenharmony_ci usc_vma->heap->static_data_offsets.vdm_sync); 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_ci pvr_setup_static_pixel_event_program(pds_ptr, 405bf215546Sopenharmony_ci pds_vma->heap->static_data_offsets.eot); 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci /* TODO: Complete control block copying work. */ 408bf215546Sopenharmony_ci 409bf215546Sopenharmony_ci ws->ops->buffer_unmap(usc_vma->bo); 410bf215546Sopenharmony_ci ws->ops->buffer_unmap(pds_vma->bo); 411bf215546Sopenharmony_ci ws->ops->buffer_unmap(general_vma->bo); 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci return VK_SUCCESS; 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_cierr_pvr_srv_winsys_buffer_unmap_pds: 416bf215546Sopenharmony_ci ws->ops->buffer_unmap(pds_vma->bo); 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_cierr_pvr_srv_winsys_buffer_unmap_general: 419bf215546Sopenharmony_ci ws->ops->buffer_unmap(general_vma->bo); 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ci return result; 422bf215546Sopenharmony_ci} 423