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 <xf86drm.h> 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "hwdef/rogue_hw_utils.h" 30bf215546Sopenharmony_ci#include "pvr_csb.h" 31bf215546Sopenharmony_ci#include "pvr_device_info.h" 32bf215546Sopenharmony_ci#include "pvr_private.h" 33bf215546Sopenharmony_ci#include "pvr_srv.h" 34bf215546Sopenharmony_ci#include "pvr_srv_bo.h" 35bf215546Sopenharmony_ci#include "pvr_srv_bridge.h" 36bf215546Sopenharmony_ci#include "pvr_srv_job_compute.h" 37bf215546Sopenharmony_ci#include "pvr_srv_job_render.h" 38bf215546Sopenharmony_ci#include "pvr_srv_job_transfer.h" 39bf215546Sopenharmony_ci#include "pvr_srv_public.h" 40bf215546Sopenharmony_ci#include "pvr_srv_sync.h" 41bf215546Sopenharmony_ci#include "pvr_srv_job_null.h" 42bf215546Sopenharmony_ci#include "pvr_types.h" 43bf215546Sopenharmony_ci#include "pvr_winsys.h" 44bf215546Sopenharmony_ci#include "pvr_winsys_helper.h" 45bf215546Sopenharmony_ci#include "util/log.h" 46bf215546Sopenharmony_ci#include "util/macros.h" 47bf215546Sopenharmony_ci#include "util/os_misc.h" 48bf215546Sopenharmony_ci#include "vk_log.h" 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci/* Amount of space used to hold sync prim values (in bytes). */ 51bf215546Sopenharmony_ci#define PVR_SRV_SYNC_PRIM_VALUE_SIZE 4U 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_cistatic VkResult pvr_srv_heap_init( 54bf215546Sopenharmony_ci struct pvr_srv_winsys *srv_ws, 55bf215546Sopenharmony_ci struct pvr_srv_winsys_heap *srv_heap, 56bf215546Sopenharmony_ci uint32_t heap_idx, 57bf215546Sopenharmony_ci const struct pvr_winsys_static_data_offsets *const static_data_offsets) 58bf215546Sopenharmony_ci{ 59bf215546Sopenharmony_ci pvr_dev_addr_t base_address; 60bf215546Sopenharmony_ci uint32_t log2_page_size; 61bf215546Sopenharmony_ci uint64_t reserved_size; 62bf215546Sopenharmony_ci VkResult result; 63bf215546Sopenharmony_ci uint64_t size; 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci result = pvr_srv_get_heap_details(srv_ws->render_fd, 66bf215546Sopenharmony_ci heap_idx, 67bf215546Sopenharmony_ci 0, 68bf215546Sopenharmony_ci NULL, 69bf215546Sopenharmony_ci &base_address, 70bf215546Sopenharmony_ci &size, 71bf215546Sopenharmony_ci &reserved_size, 72bf215546Sopenharmony_ci &log2_page_size); 73bf215546Sopenharmony_ci if (result != VK_SUCCESS) 74bf215546Sopenharmony_ci return result; 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci result = pvr_winsys_helper_winsys_heap_init(&srv_ws->base, 77bf215546Sopenharmony_ci base_address, 78bf215546Sopenharmony_ci size, 79bf215546Sopenharmony_ci base_address, 80bf215546Sopenharmony_ci reserved_size, 81bf215546Sopenharmony_ci log2_page_size, 82bf215546Sopenharmony_ci static_data_offsets, 83bf215546Sopenharmony_ci &srv_heap->base); 84bf215546Sopenharmony_ci if (result != VK_SUCCESS) 85bf215546Sopenharmony_ci return result; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci assert(srv_heap->base.page_size == srv_ws->base.page_size); 88bf215546Sopenharmony_ci assert(srv_heap->base.log2_page_size == srv_ws->base.log2_page_size); 89bf215546Sopenharmony_ci assert(srv_heap->base.reserved_size % PVR_SRV_RESERVED_SIZE_GRANULARITY == 90bf215546Sopenharmony_ci 0); 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci /* Create server-side counterpart of Device Memory heap */ 93bf215546Sopenharmony_ci result = pvr_srv_int_heap_create(srv_ws->render_fd, 94bf215546Sopenharmony_ci srv_heap->base.base_addr, 95bf215546Sopenharmony_ci srv_heap->base.size, 96bf215546Sopenharmony_ci srv_heap->base.log2_page_size, 97bf215546Sopenharmony_ci srv_ws->server_memctx, 98bf215546Sopenharmony_ci &srv_heap->server_heap); 99bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 100bf215546Sopenharmony_ci pvr_winsys_helper_winsys_heap_finish(&srv_heap->base); 101bf215546Sopenharmony_ci return result; 102bf215546Sopenharmony_ci } 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci return VK_SUCCESS; 105bf215546Sopenharmony_ci} 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_cistatic bool pvr_srv_heap_finish(struct pvr_srv_winsys *srv_ws, 108bf215546Sopenharmony_ci struct pvr_srv_winsys_heap *srv_heap) 109bf215546Sopenharmony_ci{ 110bf215546Sopenharmony_ci if (!pvr_winsys_helper_winsys_heap_finish(&srv_heap->base)) 111bf215546Sopenharmony_ci return false; 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci pvr_srv_int_heap_destroy(srv_ws->render_fd, srv_heap->server_heap); 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci return true; 116bf215546Sopenharmony_ci} 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_cistatic VkResult pvr_srv_memctx_init(struct pvr_srv_winsys *srv_ws) 119bf215546Sopenharmony_ci{ 120bf215546Sopenharmony_ci const struct pvr_winsys_static_data_offsets 121bf215546Sopenharmony_ci general_heap_static_data_offsets = { 122bf215546Sopenharmony_ci .yuv_csc = FWIF_GENERAL_HEAP_YUV_CSC_OFFSET_BYTES, 123bf215546Sopenharmony_ci }; 124bf215546Sopenharmony_ci const struct pvr_winsys_static_data_offsets pds_heap_static_data_offsets = { 125bf215546Sopenharmony_ci .eot = FWIF_PDS_HEAP_EOT_OFFSET_BYTES, 126bf215546Sopenharmony_ci .vdm_sync = FWIF_PDS_HEAP_VDM_SYNC_OFFSET_BYTES, 127bf215546Sopenharmony_ci }; 128bf215546Sopenharmony_ci const struct pvr_winsys_static_data_offsets usc_heap_static_data_offsets = { 129bf215546Sopenharmony_ci .vdm_sync = FWIF_USC_HEAP_VDM_SYNC_OFFSET_BYTES, 130bf215546Sopenharmony_ci }; 131bf215546Sopenharmony_ci const struct pvr_winsys_static_data_offsets no_static_data_offsets = { 0 }; 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci char heap_name[PVR_SRV_DEVMEM_HEAPNAME_MAXLENGTH]; 134bf215546Sopenharmony_ci int transfer_3d_heap_idx = -1; 135bf215546Sopenharmony_ci int vis_test_heap_idx = -1; 136bf215546Sopenharmony_ci int general_heap_idx = -1; 137bf215546Sopenharmony_ci int rgn_hdr_heap_idx = -1; 138bf215546Sopenharmony_ci int pds_heap_idx = -1; 139bf215546Sopenharmony_ci int usc_heap_idx = -1; 140bf215546Sopenharmony_ci uint32_t heap_count; 141bf215546Sopenharmony_ci VkResult result; 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci result = pvr_srv_int_ctx_create(srv_ws->render_fd, 144bf215546Sopenharmony_ci &srv_ws->server_memctx, 145bf215546Sopenharmony_ci &srv_ws->server_memctx_data); 146bf215546Sopenharmony_ci if (result != VK_SUCCESS) 147bf215546Sopenharmony_ci return result; 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci os_get_page_size(&srv_ws->base.page_size); 150bf215546Sopenharmony_ci srv_ws->base.log2_page_size = util_logbase2(srv_ws->base.page_size); 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci result = pvr_srv_get_heap_count(srv_ws->render_fd, &heap_count); 153bf215546Sopenharmony_ci if (result != VK_SUCCESS) 154bf215546Sopenharmony_ci goto err_pvr_srv_int_ctx_destroy; 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci assert(heap_count > 0); 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci for (uint32_t i = 0; i < heap_count; i++) { 159bf215546Sopenharmony_ci result = pvr_srv_get_heap_details(srv_ws->render_fd, 160bf215546Sopenharmony_ci i, 161bf215546Sopenharmony_ci sizeof(heap_name), 162bf215546Sopenharmony_ci heap_name, 163bf215546Sopenharmony_ci NULL, 164bf215546Sopenharmony_ci NULL, 165bf215546Sopenharmony_ci NULL, 166bf215546Sopenharmony_ci NULL); 167bf215546Sopenharmony_ci if (result != VK_SUCCESS) 168bf215546Sopenharmony_ci goto err_pvr_srv_int_ctx_destroy; 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci if (general_heap_idx == -1 && 171bf215546Sopenharmony_ci strncmp(heap_name, 172bf215546Sopenharmony_ci PVR_SRV_GENERAL_HEAP_IDENT, 173bf215546Sopenharmony_ci sizeof(PVR_SRV_GENERAL_HEAP_IDENT)) == 0) { 174bf215546Sopenharmony_ci general_heap_idx = i; 175bf215546Sopenharmony_ci } else if (pds_heap_idx == -1 && 176bf215546Sopenharmony_ci strncmp(heap_name, 177bf215546Sopenharmony_ci PVR_SRV_PDSCODEDATA_HEAP_IDENT, 178bf215546Sopenharmony_ci sizeof(PVR_SRV_PDSCODEDATA_HEAP_IDENT)) == 0) { 179bf215546Sopenharmony_ci pds_heap_idx = i; 180bf215546Sopenharmony_ci } else if (rgn_hdr_heap_idx == -1 && 181bf215546Sopenharmony_ci strncmp(heap_name, 182bf215546Sopenharmony_ci PVR_SRV_RGNHDR_BRN_63142_HEAP_IDENT, 183bf215546Sopenharmony_ci sizeof(PVR_SRV_RGNHDR_BRN_63142_HEAP_IDENT)) == 0) { 184bf215546Sopenharmony_ci rgn_hdr_heap_idx = i; 185bf215546Sopenharmony_ci } else if (transfer_3d_heap_idx == -1 && 186bf215546Sopenharmony_ci strncmp(heap_name, 187bf215546Sopenharmony_ci PVR_SRV_TRANSFER_3D_HEAP_IDENT, 188bf215546Sopenharmony_ci sizeof(PVR_SRV_TRANSFER_3D_HEAP_IDENT)) == 0) { 189bf215546Sopenharmony_ci transfer_3d_heap_idx = i; 190bf215546Sopenharmony_ci } else if (usc_heap_idx == -1 && 191bf215546Sopenharmony_ci strncmp(heap_name, 192bf215546Sopenharmony_ci PVR_SRV_USCCODE_HEAP_IDENT, 193bf215546Sopenharmony_ci sizeof(PVR_SRV_USCCODE_HEAP_IDENT)) == 0) { 194bf215546Sopenharmony_ci usc_heap_idx = i; 195bf215546Sopenharmony_ci } else if (vis_test_heap_idx == -1 && 196bf215546Sopenharmony_ci strncmp(heap_name, 197bf215546Sopenharmony_ci PVR_SRV_VISIBILITY_TEST_HEAP_IDENT, 198bf215546Sopenharmony_ci sizeof(PVR_SRV_VISIBILITY_TEST_HEAP_IDENT)) == 0) { 199bf215546Sopenharmony_ci vis_test_heap_idx = i; 200bf215546Sopenharmony_ci } 201bf215546Sopenharmony_ci } 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci /* Check for and initialise required heaps. */ 204bf215546Sopenharmony_ci if (general_heap_idx == -1 || pds_heap_idx == -1 || 205bf215546Sopenharmony_ci transfer_3d_heap_idx == -1 || usc_heap_idx == -1 || 206bf215546Sopenharmony_ci vis_test_heap_idx == -1) { 207bf215546Sopenharmony_ci result = vk_error(NULL, VK_ERROR_INITIALIZATION_FAILED); 208bf215546Sopenharmony_ci goto err_pvr_srv_int_ctx_destroy; 209bf215546Sopenharmony_ci } 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci result = pvr_srv_heap_init(srv_ws, 212bf215546Sopenharmony_ci &srv_ws->general_heap, 213bf215546Sopenharmony_ci general_heap_idx, 214bf215546Sopenharmony_ci &general_heap_static_data_offsets); 215bf215546Sopenharmony_ci if (result != VK_SUCCESS) 216bf215546Sopenharmony_ci goto err_pvr_srv_int_ctx_destroy; 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci result = pvr_srv_heap_init(srv_ws, 219bf215546Sopenharmony_ci &srv_ws->pds_heap, 220bf215546Sopenharmony_ci pds_heap_idx, 221bf215546Sopenharmony_ci &pds_heap_static_data_offsets); 222bf215546Sopenharmony_ci if (result != VK_SUCCESS) 223bf215546Sopenharmony_ci goto err_pvr_srv_heap_finish_general; 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci result = pvr_srv_heap_init(srv_ws, 226bf215546Sopenharmony_ci &srv_ws->transfer_3d_heap, 227bf215546Sopenharmony_ci transfer_3d_heap_idx, 228bf215546Sopenharmony_ci &no_static_data_offsets); 229bf215546Sopenharmony_ci if (result != VK_SUCCESS) 230bf215546Sopenharmony_ci goto err_pvr_srv_heap_finish_pds; 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci result = pvr_srv_heap_init(srv_ws, 233bf215546Sopenharmony_ci &srv_ws->usc_heap, 234bf215546Sopenharmony_ci usc_heap_idx, 235bf215546Sopenharmony_ci &usc_heap_static_data_offsets); 236bf215546Sopenharmony_ci if (result != VK_SUCCESS) 237bf215546Sopenharmony_ci goto err_pvr_srv_heap_finish_transfer_3d; 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci result = pvr_srv_heap_init(srv_ws, 240bf215546Sopenharmony_ci &srv_ws->vis_test_heap, 241bf215546Sopenharmony_ci vis_test_heap_idx, 242bf215546Sopenharmony_ci &no_static_data_offsets); 243bf215546Sopenharmony_ci if (result != VK_SUCCESS) 244bf215546Sopenharmony_ci goto err_pvr_srv_heap_finish_usc; 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci /* Check for and set up optional heaps. */ 247bf215546Sopenharmony_ci if (rgn_hdr_heap_idx != -1) { 248bf215546Sopenharmony_ci result = pvr_srv_heap_init(srv_ws, 249bf215546Sopenharmony_ci &srv_ws->rgn_hdr_heap, 250bf215546Sopenharmony_ci rgn_hdr_heap_idx, 251bf215546Sopenharmony_ci &no_static_data_offsets); 252bf215546Sopenharmony_ci if (result != VK_SUCCESS) 253bf215546Sopenharmony_ci goto err_pvr_srv_heap_finish_vis_test; 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci srv_ws->rgn_hdr_heap_present = true; 256bf215546Sopenharmony_ci } else { 257bf215546Sopenharmony_ci srv_ws->rgn_hdr_heap_present = false; 258bf215546Sopenharmony_ci } 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci result = 261bf215546Sopenharmony_ci pvr_winsys_helper_allocate_static_memory(&srv_ws->base, 262bf215546Sopenharmony_ci pvr_srv_heap_alloc_reserved, 263bf215546Sopenharmony_ci &srv_ws->general_heap.base, 264bf215546Sopenharmony_ci &srv_ws->pds_heap.base, 265bf215546Sopenharmony_ci &srv_ws->usc_heap.base, 266bf215546Sopenharmony_ci &srv_ws->general_vma, 267bf215546Sopenharmony_ci &srv_ws->pds_vma, 268bf215546Sopenharmony_ci &srv_ws->usc_vma); 269bf215546Sopenharmony_ci if (result != VK_SUCCESS) 270bf215546Sopenharmony_ci goto err_pvr_srv_heap_finish_rgn_hdr; 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci result = pvr_winsys_helper_fill_static_memory(&srv_ws->base, 273bf215546Sopenharmony_ci srv_ws->general_vma, 274bf215546Sopenharmony_ci srv_ws->pds_vma, 275bf215546Sopenharmony_ci srv_ws->usc_vma); 276bf215546Sopenharmony_ci if (result != VK_SUCCESS) 277bf215546Sopenharmony_ci goto err_pvr_srv_free_static_memory; 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci return VK_SUCCESS; 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_cierr_pvr_srv_free_static_memory: 282bf215546Sopenharmony_ci pvr_winsys_helper_free_static_memory(srv_ws->general_vma, 283bf215546Sopenharmony_ci srv_ws->pds_vma, 284bf215546Sopenharmony_ci srv_ws->usc_vma); 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_cierr_pvr_srv_heap_finish_rgn_hdr: 287bf215546Sopenharmony_ci if (srv_ws->rgn_hdr_heap_present) 288bf215546Sopenharmony_ci pvr_srv_heap_finish(srv_ws, &srv_ws->rgn_hdr_heap); 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_cierr_pvr_srv_heap_finish_vis_test: 291bf215546Sopenharmony_ci pvr_srv_heap_finish(srv_ws, &srv_ws->vis_test_heap); 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_cierr_pvr_srv_heap_finish_usc: 294bf215546Sopenharmony_ci pvr_srv_heap_finish(srv_ws, &srv_ws->usc_heap); 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_cierr_pvr_srv_heap_finish_transfer_3d: 297bf215546Sopenharmony_ci pvr_srv_heap_finish(srv_ws, &srv_ws->transfer_3d_heap); 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_cierr_pvr_srv_heap_finish_pds: 300bf215546Sopenharmony_ci pvr_srv_heap_finish(srv_ws, &srv_ws->pds_heap); 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_cierr_pvr_srv_heap_finish_general: 303bf215546Sopenharmony_ci pvr_srv_heap_finish(srv_ws, &srv_ws->general_heap); 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_cierr_pvr_srv_int_ctx_destroy: 306bf215546Sopenharmony_ci pvr_srv_int_ctx_destroy(srv_ws->render_fd, srv_ws->server_memctx); 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci return result; 309bf215546Sopenharmony_ci} 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_cistatic void pvr_srv_memctx_finish(struct pvr_srv_winsys *srv_ws) 312bf215546Sopenharmony_ci{ 313bf215546Sopenharmony_ci pvr_winsys_helper_free_static_memory(srv_ws->general_vma, 314bf215546Sopenharmony_ci srv_ws->pds_vma, 315bf215546Sopenharmony_ci srv_ws->usc_vma); 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci if (srv_ws->rgn_hdr_heap_present) { 318bf215546Sopenharmony_ci if (!pvr_srv_heap_finish(srv_ws, &srv_ws->rgn_hdr_heap)) { 319bf215546Sopenharmony_ci vk_errorf(NULL, 320bf215546Sopenharmony_ci VK_ERROR_UNKNOWN, 321bf215546Sopenharmony_ci "Region header heap in use, can not deinit"); 322bf215546Sopenharmony_ci } 323bf215546Sopenharmony_ci } 324bf215546Sopenharmony_ci 325bf215546Sopenharmony_ci if (!pvr_srv_heap_finish(srv_ws, &srv_ws->vis_test_heap)) { 326bf215546Sopenharmony_ci vk_errorf(NULL, 327bf215546Sopenharmony_ci VK_ERROR_UNKNOWN, 328bf215546Sopenharmony_ci "Visibility test heap in use, can not deinit"); 329bf215546Sopenharmony_ci } 330bf215546Sopenharmony_ci 331bf215546Sopenharmony_ci if (!pvr_srv_heap_finish(srv_ws, &srv_ws->usc_heap)) 332bf215546Sopenharmony_ci vk_errorf(NULL, VK_ERROR_UNKNOWN, "USC heap in use, can not deinit"); 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci if (!pvr_srv_heap_finish(srv_ws, &srv_ws->transfer_3d_heap)) { 335bf215546Sopenharmony_ci vk_errorf(NULL, 336bf215546Sopenharmony_ci VK_ERROR_UNKNOWN, 337bf215546Sopenharmony_ci "Transfer 3D heap in use, can not deinit"); 338bf215546Sopenharmony_ci } 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci if (!pvr_srv_heap_finish(srv_ws, &srv_ws->pds_heap)) 341bf215546Sopenharmony_ci vk_errorf(NULL, VK_ERROR_UNKNOWN, "PDS heap in use, can not deinit"); 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci if (!pvr_srv_heap_finish(srv_ws, &srv_ws->general_heap)) { 344bf215546Sopenharmony_ci vk_errorf(NULL, VK_ERROR_UNKNOWN, "General heap in use, can not deinit"); 345bf215546Sopenharmony_ci } 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci pvr_srv_int_ctx_destroy(srv_ws->render_fd, srv_ws->server_memctx); 348bf215546Sopenharmony_ci} 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_cistatic VkResult pvr_srv_sync_prim_block_init(struct pvr_srv_winsys *srv_ws) 351bf215546Sopenharmony_ci{ 352bf215546Sopenharmony_ci /* We don't currently make use of this value, but we're required to provide 353bf215546Sopenharmony_ci * a valid pointer to pvr_srv_alloc_sync_primitive_block. 354bf215546Sopenharmony_ci */ 355bf215546Sopenharmony_ci void *sync_block_pmr; 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci return pvr_srv_alloc_sync_primitive_block(srv_ws->render_fd, 358bf215546Sopenharmony_ci &srv_ws->sync_block_handle, 359bf215546Sopenharmony_ci &sync_block_pmr, 360bf215546Sopenharmony_ci &srv_ws->sync_block_size, 361bf215546Sopenharmony_ci &srv_ws->sync_block_fw_addr); 362bf215546Sopenharmony_ci} 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_cistatic void pvr_srv_sync_prim_block_finish(struct pvr_srv_winsys *srv_ws) 365bf215546Sopenharmony_ci{ 366bf215546Sopenharmony_ci pvr_srv_free_sync_primitive_block(srv_ws->render_fd, 367bf215546Sopenharmony_ci srv_ws->sync_block_handle); 368bf215546Sopenharmony_ci srv_ws->sync_block_handle = NULL; 369bf215546Sopenharmony_ci} 370bf215546Sopenharmony_ci 371bf215546Sopenharmony_cistatic void pvr_srv_winsys_destroy(struct pvr_winsys *ws) 372bf215546Sopenharmony_ci{ 373bf215546Sopenharmony_ci struct pvr_srv_winsys *srv_ws = to_pvr_srv_winsys(ws); 374bf215546Sopenharmony_ci int fd = srv_ws->render_fd; 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_ci pvr_srv_sync_prim_block_finish(srv_ws); 377bf215546Sopenharmony_ci pvr_srv_memctx_finish(srv_ws); 378bf215546Sopenharmony_ci vk_free(srv_ws->alloc, srv_ws); 379bf215546Sopenharmony_ci pvr_srv_connection_destroy(fd); 380bf215546Sopenharmony_ci} 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_cistatic uint64_t 383bf215546Sopenharmony_cipvr_srv_get_min_free_list_size(const struct pvr_device_info *dev_info) 384bf215546Sopenharmony_ci{ 385bf215546Sopenharmony_ci uint64_t min_num_pages; 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci if (PVR_HAS_FEATURE(dev_info, roguexe)) { 388bf215546Sopenharmony_ci if (PVR_HAS_QUIRK(dev_info, 66011)) 389bf215546Sopenharmony_ci min_num_pages = 40U; 390bf215546Sopenharmony_ci else 391bf215546Sopenharmony_ci min_num_pages = 25U; 392bf215546Sopenharmony_ci } else { 393bf215546Sopenharmony_ci min_num_pages = 50U; 394bf215546Sopenharmony_ci } 395bf215546Sopenharmony_ci 396bf215546Sopenharmony_ci return min_num_pages << ROGUE_BIF_PM_PHYSICAL_PAGE_SHIFT; 397bf215546Sopenharmony_ci} 398bf215546Sopenharmony_ci 399bf215546Sopenharmony_cistatic inline uint64_t 400bf215546Sopenharmony_cipvr_srv_get_num_phantoms(const struct pvr_device_info *dev_info) 401bf215546Sopenharmony_ci{ 402bf215546Sopenharmony_ci return DIV_ROUND_UP(PVR_GET_FEATURE_VALUE(dev_info, num_clusters, 1U), 4U); 403bf215546Sopenharmony_ci} 404bf215546Sopenharmony_ci 405bf215546Sopenharmony_ci/* Return the total reserved size of partition in dwords. */ 406bf215546Sopenharmony_cistatic inline uint64_t pvr_srv_get_total_reserved_partition_size( 407bf215546Sopenharmony_ci const struct pvr_device_info *dev_info) 408bf215546Sopenharmony_ci{ 409bf215546Sopenharmony_ci uint32_t tile_size_x = PVR_GET_FEATURE_VALUE(dev_info, tile_size_x, 0); 410bf215546Sopenharmony_ci uint32_t tile_size_y = PVR_GET_FEATURE_VALUE(dev_info, tile_size_y, 0); 411bf215546Sopenharmony_ci uint32_t max_partitions = PVR_GET_FEATURE_VALUE(dev_info, max_partitions, 0); 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci if (tile_size_x == 16 && tile_size_y == 16) { 414bf215546Sopenharmony_ci return tile_size_x * tile_size_y * max_partitions * 415bf215546Sopenharmony_ci PVR_GET_FEATURE_VALUE(dev_info, 416bf215546Sopenharmony_ci usc_min_output_registers_per_pix, 417bf215546Sopenharmony_ci 0); 418bf215546Sopenharmony_ci } 419bf215546Sopenharmony_ci 420bf215546Sopenharmony_ci return max_partitions * 1024U; 421bf215546Sopenharmony_ci} 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_cistatic inline uint64_t 424bf215546Sopenharmony_cipvr_srv_get_reserved_shared_size(const struct pvr_device_info *dev_info) 425bf215546Sopenharmony_ci{ 426bf215546Sopenharmony_ci uint32_t common_store_size_in_dwords = 427bf215546Sopenharmony_ci PVR_GET_FEATURE_VALUE(dev_info, 428bf215546Sopenharmony_ci common_store_size_in_dwords, 429bf215546Sopenharmony_ci 512U * 4U * 4U); 430bf215546Sopenharmony_ci uint32_t reserved_shared_size = 431bf215546Sopenharmony_ci common_store_size_in_dwords - (256U * 4U) - 432bf215546Sopenharmony_ci pvr_srv_get_total_reserved_partition_size(dev_info); 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_ci if (PVR_HAS_QUIRK(dev_info, 44079)) { 435bf215546Sopenharmony_ci uint32_t common_store_split_point = (768U * 4U * 4U); 436bf215546Sopenharmony_ci 437bf215546Sopenharmony_ci return MIN2(common_store_split_point - (256U * 4U), reserved_shared_size); 438bf215546Sopenharmony_ci } 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci return reserved_shared_size; 441bf215546Sopenharmony_ci} 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_cistatic inline uint64_t 444bf215546Sopenharmony_cipvr_srv_get_max_coeffs(const struct pvr_device_info *dev_info) 445bf215546Sopenharmony_ci{ 446bf215546Sopenharmony_ci uint32_t max_coeff_additional_portion = ROGUE_MAX_VERTEX_SHARED_REGISTERS; 447bf215546Sopenharmony_ci uint32_t pending_allocation_shared_regs = 2U * 1024U; 448bf215546Sopenharmony_ci uint32_t pending_allocation_coeff_regs = 0U; 449bf215546Sopenharmony_ci uint32_t num_phantoms = pvr_srv_get_num_phantoms(dev_info); 450bf215546Sopenharmony_ci uint32_t tiles_in_flight = 451bf215546Sopenharmony_ci PVR_GET_FEATURE_VALUE(dev_info, isp_max_tiles_in_flight, 0); 452bf215546Sopenharmony_ci uint32_t max_coeff_pixel_portion = 453bf215546Sopenharmony_ci DIV_ROUND_UP(tiles_in_flight, num_phantoms); 454bf215546Sopenharmony_ci 455bf215546Sopenharmony_ci max_coeff_pixel_portion *= ROGUE_MAX_PIXEL_SHARED_REGISTERS; 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci /* Compute tasks on cores with BRN48492 and without compute overlap may lock 458bf215546Sopenharmony_ci * up without two additional lines of coeffs. 459bf215546Sopenharmony_ci */ 460bf215546Sopenharmony_ci if (PVR_HAS_QUIRK(dev_info, 48492) && 461bf215546Sopenharmony_ci !PVR_HAS_FEATURE(dev_info, compute_overlap)) { 462bf215546Sopenharmony_ci pending_allocation_coeff_regs = 2U * 1024U; 463bf215546Sopenharmony_ci } 464bf215546Sopenharmony_ci 465bf215546Sopenharmony_ci if (PVR_HAS_ERN(dev_info, 38748)) 466bf215546Sopenharmony_ci pending_allocation_shared_regs = 0U; 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_ci if (PVR_HAS_ERN(dev_info, 38020)) { 469bf215546Sopenharmony_ci max_coeff_additional_portion += 470bf215546Sopenharmony_ci rogue_max_compute_shared_registers(dev_info); 471bf215546Sopenharmony_ci } 472bf215546Sopenharmony_ci 473bf215546Sopenharmony_ci return pvr_srv_get_reserved_shared_size(dev_info) + 474bf215546Sopenharmony_ci pending_allocation_coeff_regs - 475bf215546Sopenharmony_ci (max_coeff_pixel_portion + max_coeff_additional_portion + 476bf215546Sopenharmony_ci pending_allocation_shared_regs); 477bf215546Sopenharmony_ci} 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_cistatic inline uint64_t 480bf215546Sopenharmony_cipvr_srv_get_cdm_max_local_mem_size_regs(const struct pvr_device_info *dev_info) 481bf215546Sopenharmony_ci{ 482bf215546Sopenharmony_ci uint32_t available_coeffs_in_dwords = pvr_srv_get_max_coeffs(dev_info); 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_ci if (PVR_HAS_QUIRK(dev_info, 48492) && PVR_HAS_FEATURE(dev_info, roguexe) && 485bf215546Sopenharmony_ci !PVR_HAS_FEATURE(dev_info, compute_overlap)) { 486bf215546Sopenharmony_ci /* Driver must not use the 2 reserved lines. */ 487bf215546Sopenharmony_ci available_coeffs_in_dwords -= ROGUE_CSRM_LINE_SIZE_IN_DWORDS * 2; 488bf215546Sopenharmony_ci } 489bf215546Sopenharmony_ci 490bf215546Sopenharmony_ci /* The maximum amount of local memory available to a kernel is the minimum 491bf215546Sopenharmony_ci * of the total number of coefficient registers available and the max common 492bf215546Sopenharmony_ci * store allocation size which can be made by the CDM. 493bf215546Sopenharmony_ci * 494bf215546Sopenharmony_ci * If any coeff lines are reserved for tessellation or pixel then we need to 495bf215546Sopenharmony_ci * subtract those too. 496bf215546Sopenharmony_ci */ 497bf215546Sopenharmony_ci return MIN2(available_coeffs_in_dwords, 498bf215546Sopenharmony_ci ROGUE_MAX_PER_KERNEL_LOCAL_MEM_SIZE_REGS); 499bf215546Sopenharmony_ci} 500bf215546Sopenharmony_ci 501bf215546Sopenharmony_cistatic int 502bf215546Sopenharmony_cipvr_srv_winsys_device_info_init(struct pvr_winsys *ws, 503bf215546Sopenharmony_ci struct pvr_device_info *dev_info, 504bf215546Sopenharmony_ci struct pvr_device_runtime_info *runtime_info) 505bf215546Sopenharmony_ci{ 506bf215546Sopenharmony_ci struct pvr_srv_winsys *srv_ws = to_pvr_srv_winsys(ws); 507bf215546Sopenharmony_ci VkResult result; 508bf215546Sopenharmony_ci int ret; 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci ret = pvr_device_info_init(dev_info, srv_ws->bvnc); 511bf215546Sopenharmony_ci if (ret) { 512bf215546Sopenharmony_ci mesa_logw("Unsupported BVNC: %u.%u.%u.%u\n", 513bf215546Sopenharmony_ci PVR_BVNC_UNPACK_B(srv_ws->bvnc), 514bf215546Sopenharmony_ci PVR_BVNC_UNPACK_V(srv_ws->bvnc), 515bf215546Sopenharmony_ci PVR_BVNC_UNPACK_N(srv_ws->bvnc), 516bf215546Sopenharmony_ci PVR_BVNC_UNPACK_C(srv_ws->bvnc)); 517bf215546Sopenharmony_ci return ret; 518bf215546Sopenharmony_ci } 519bf215546Sopenharmony_ci 520bf215546Sopenharmony_ci runtime_info->min_free_list_size = pvr_srv_get_min_free_list_size(dev_info); 521bf215546Sopenharmony_ci runtime_info->reserved_shared_size = 522bf215546Sopenharmony_ci pvr_srv_get_reserved_shared_size(dev_info); 523bf215546Sopenharmony_ci runtime_info->total_reserved_partition_size = 524bf215546Sopenharmony_ci pvr_srv_get_total_reserved_partition_size(dev_info); 525bf215546Sopenharmony_ci runtime_info->num_phantoms = pvr_srv_get_num_phantoms(dev_info); 526bf215546Sopenharmony_ci runtime_info->max_coeffs = pvr_srv_get_max_coeffs(dev_info); 527bf215546Sopenharmony_ci runtime_info->cdm_max_local_mem_size_regs = 528bf215546Sopenharmony_ci pvr_srv_get_cdm_max_local_mem_size_regs(dev_info); 529bf215546Sopenharmony_ci 530bf215546Sopenharmony_ci if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support)) { 531bf215546Sopenharmony_ci result = pvr_srv_get_multicore_info(srv_ws->render_fd, 532bf215546Sopenharmony_ci 0, 533bf215546Sopenharmony_ci NULL, 534bf215546Sopenharmony_ci &runtime_info->core_count); 535bf215546Sopenharmony_ci if (result != VK_SUCCESS) 536bf215546Sopenharmony_ci return -ENODEV; 537bf215546Sopenharmony_ci } else { 538bf215546Sopenharmony_ci runtime_info->core_count = 1; 539bf215546Sopenharmony_ci } 540bf215546Sopenharmony_ci 541bf215546Sopenharmony_ci return 0; 542bf215546Sopenharmony_ci} 543bf215546Sopenharmony_ci 544bf215546Sopenharmony_cistatic void pvr_srv_winsys_get_heaps_info(struct pvr_winsys *ws, 545bf215546Sopenharmony_ci struct pvr_winsys_heaps *heaps) 546bf215546Sopenharmony_ci{ 547bf215546Sopenharmony_ci struct pvr_srv_winsys *srv_ws = to_pvr_srv_winsys(ws); 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_ci heaps->general_heap = &srv_ws->general_heap.base; 550bf215546Sopenharmony_ci heaps->pds_heap = &srv_ws->pds_heap.base; 551bf215546Sopenharmony_ci heaps->transfer_3d_heap = &srv_ws->transfer_3d_heap.base; 552bf215546Sopenharmony_ci heaps->usc_heap = &srv_ws->usc_heap.base; 553bf215546Sopenharmony_ci heaps->vis_test_heap = &srv_ws->vis_test_heap.base; 554bf215546Sopenharmony_ci 555bf215546Sopenharmony_ci if (srv_ws->rgn_hdr_heap_present) 556bf215546Sopenharmony_ci heaps->rgn_hdr_heap = &srv_ws->rgn_hdr_heap.base; 557bf215546Sopenharmony_ci else 558bf215546Sopenharmony_ci heaps->rgn_hdr_heap = &srv_ws->general_heap.base; 559bf215546Sopenharmony_ci} 560bf215546Sopenharmony_ci 561bf215546Sopenharmony_cistatic const struct pvr_winsys_ops srv_winsys_ops = { 562bf215546Sopenharmony_ci .destroy = pvr_srv_winsys_destroy, 563bf215546Sopenharmony_ci .device_info_init = pvr_srv_winsys_device_info_init, 564bf215546Sopenharmony_ci .get_heaps_info = pvr_srv_winsys_get_heaps_info, 565bf215546Sopenharmony_ci .buffer_create = pvr_srv_winsys_buffer_create, 566bf215546Sopenharmony_ci .buffer_create_from_fd = pvr_srv_winsys_buffer_create_from_fd, 567bf215546Sopenharmony_ci .buffer_destroy = pvr_srv_winsys_buffer_destroy, 568bf215546Sopenharmony_ci .buffer_get_fd = pvr_srv_winsys_buffer_get_fd, 569bf215546Sopenharmony_ci .buffer_map = pvr_srv_winsys_buffer_map, 570bf215546Sopenharmony_ci .buffer_unmap = pvr_srv_winsys_buffer_unmap, 571bf215546Sopenharmony_ci .heap_alloc = pvr_srv_winsys_heap_alloc, 572bf215546Sopenharmony_ci .heap_free = pvr_srv_winsys_heap_free, 573bf215546Sopenharmony_ci .vma_map = pvr_srv_winsys_vma_map, 574bf215546Sopenharmony_ci .vma_unmap = pvr_srv_winsys_vma_unmap, 575bf215546Sopenharmony_ci .free_list_create = pvr_srv_winsys_free_list_create, 576bf215546Sopenharmony_ci .free_list_destroy = pvr_srv_winsys_free_list_destroy, 577bf215546Sopenharmony_ci .render_target_dataset_create = pvr_srv_render_target_dataset_create, 578bf215546Sopenharmony_ci .render_target_dataset_destroy = pvr_srv_render_target_dataset_destroy, 579bf215546Sopenharmony_ci .render_ctx_create = pvr_srv_winsys_render_ctx_create, 580bf215546Sopenharmony_ci .render_ctx_destroy = pvr_srv_winsys_render_ctx_destroy, 581bf215546Sopenharmony_ci .render_submit = pvr_srv_winsys_render_submit, 582bf215546Sopenharmony_ci .compute_ctx_create = pvr_srv_winsys_compute_ctx_create, 583bf215546Sopenharmony_ci .compute_ctx_destroy = pvr_srv_winsys_compute_ctx_destroy, 584bf215546Sopenharmony_ci .compute_submit = pvr_srv_winsys_compute_submit, 585bf215546Sopenharmony_ci .transfer_ctx_create = pvr_srv_winsys_transfer_ctx_create, 586bf215546Sopenharmony_ci .transfer_ctx_destroy = pvr_srv_winsys_transfer_ctx_destroy, 587bf215546Sopenharmony_ci .transfer_submit = pvr_srv_winsys_transfer_submit, 588bf215546Sopenharmony_ci .null_job_submit = pvr_srv_winsys_null_job_submit, 589bf215546Sopenharmony_ci}; 590bf215546Sopenharmony_ci 591bf215546Sopenharmony_cistatic bool pvr_is_driver_compatible(int render_fd) 592bf215546Sopenharmony_ci{ 593bf215546Sopenharmony_ci drmVersionPtr version; 594bf215546Sopenharmony_ci 595bf215546Sopenharmony_ci version = drmGetVersion(render_fd); 596bf215546Sopenharmony_ci if (!version) 597bf215546Sopenharmony_ci return false; 598bf215546Sopenharmony_ci 599bf215546Sopenharmony_ci assert(strcmp(version->name, "pvr") == 0); 600bf215546Sopenharmony_ci 601bf215546Sopenharmony_ci /* Only the 1.17 driver is supported for now. */ 602bf215546Sopenharmony_ci if (version->version_major != PVR_SRV_VERSION_MAJ || 603bf215546Sopenharmony_ci version->version_minor != PVR_SRV_VERSION_MIN) { 604bf215546Sopenharmony_ci vk_errorf(NULL, 605bf215546Sopenharmony_ci VK_ERROR_INCOMPATIBLE_DRIVER, 606bf215546Sopenharmony_ci "Unsupported downstream driver version (%u.%u)", 607bf215546Sopenharmony_ci version->version_major, 608bf215546Sopenharmony_ci version->version_minor); 609bf215546Sopenharmony_ci drmFreeVersion(version); 610bf215546Sopenharmony_ci 611bf215546Sopenharmony_ci return false; 612bf215546Sopenharmony_ci } 613bf215546Sopenharmony_ci 614bf215546Sopenharmony_ci drmFreeVersion(version); 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci return true; 617bf215546Sopenharmony_ci} 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_cistruct pvr_winsys *pvr_srv_winsys_create(int master_fd, 620bf215546Sopenharmony_ci int render_fd, 621bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc) 622bf215546Sopenharmony_ci{ 623bf215546Sopenharmony_ci struct pvr_srv_winsys *srv_ws; 624bf215546Sopenharmony_ci VkResult result; 625bf215546Sopenharmony_ci uint64_t bvnc; 626bf215546Sopenharmony_ci 627bf215546Sopenharmony_ci if (!pvr_is_driver_compatible(render_fd)) 628bf215546Sopenharmony_ci return NULL; 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_ci result = pvr_srv_init_module(render_fd, PVR_SRVKM_MODULE_TYPE_SERVICES); 631bf215546Sopenharmony_ci if (result != VK_SUCCESS) 632bf215546Sopenharmony_ci return NULL; 633bf215546Sopenharmony_ci 634bf215546Sopenharmony_ci result = pvr_srv_connection_create(render_fd, &bvnc); 635bf215546Sopenharmony_ci if (result != VK_SUCCESS) 636bf215546Sopenharmony_ci return NULL; 637bf215546Sopenharmony_ci 638bf215546Sopenharmony_ci srv_ws = 639bf215546Sopenharmony_ci vk_zalloc(alloc, sizeof(*srv_ws), 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); 640bf215546Sopenharmony_ci if (!srv_ws) { 641bf215546Sopenharmony_ci vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY); 642bf215546Sopenharmony_ci goto err_pvr_srv_connection_destroy; 643bf215546Sopenharmony_ci } 644bf215546Sopenharmony_ci 645bf215546Sopenharmony_ci srv_ws->base.ops = &srv_winsys_ops; 646bf215546Sopenharmony_ci srv_ws->bvnc = bvnc; 647bf215546Sopenharmony_ci srv_ws->master_fd = master_fd; 648bf215546Sopenharmony_ci srv_ws->render_fd = render_fd; 649bf215546Sopenharmony_ci srv_ws->alloc = alloc; 650bf215546Sopenharmony_ci 651bf215546Sopenharmony_ci srv_ws->base.syncobj_type = pvr_srv_sync_type; 652bf215546Sopenharmony_ci srv_ws->base.sync_types[0] = &srv_ws->base.syncobj_type; 653bf215546Sopenharmony_ci srv_ws->base.sync_types[1] = NULL; 654bf215546Sopenharmony_ci 655bf215546Sopenharmony_ci result = pvr_srv_memctx_init(srv_ws); 656bf215546Sopenharmony_ci if (result != VK_SUCCESS) 657bf215546Sopenharmony_ci goto err_vk_free_srv_ws; 658bf215546Sopenharmony_ci 659bf215546Sopenharmony_ci result = pvr_srv_sync_prim_block_init(srv_ws); 660bf215546Sopenharmony_ci if (result != VK_SUCCESS) 661bf215546Sopenharmony_ci goto err_pvr_srv_memctx_finish; 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_ci return &srv_ws->base; 664bf215546Sopenharmony_ci 665bf215546Sopenharmony_cierr_pvr_srv_memctx_finish: 666bf215546Sopenharmony_ci pvr_srv_memctx_finish(srv_ws); 667bf215546Sopenharmony_ci 668bf215546Sopenharmony_cierr_vk_free_srv_ws: 669bf215546Sopenharmony_ci vk_free(alloc, srv_ws); 670bf215546Sopenharmony_ci 671bf215546Sopenharmony_cierr_pvr_srv_connection_destroy: 672bf215546Sopenharmony_ci pvr_srv_connection_destroy(render_fd); 673bf215546Sopenharmony_ci 674bf215546Sopenharmony_ci return NULL; 675bf215546Sopenharmony_ci} 676bf215546Sopenharmony_ci 677bf215546Sopenharmony_cistruct pvr_srv_sync_prim *pvr_srv_sync_prim_alloc(struct pvr_srv_winsys *srv_ws) 678bf215546Sopenharmony_ci{ 679bf215546Sopenharmony_ci struct pvr_srv_sync_prim *sync_prim; 680bf215546Sopenharmony_ci 681bf215546Sopenharmony_ci if (p_atomic_read(&srv_ws->sync_block_offset) == srv_ws->sync_block_size) { 682bf215546Sopenharmony_ci vk_error(NULL, VK_ERROR_UNKNOWN); 683bf215546Sopenharmony_ci return NULL; 684bf215546Sopenharmony_ci } 685bf215546Sopenharmony_ci 686bf215546Sopenharmony_ci sync_prim = vk_alloc(srv_ws->alloc, 687bf215546Sopenharmony_ci sizeof(*sync_prim), 688bf215546Sopenharmony_ci 8, 689bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); 690bf215546Sopenharmony_ci if (!sync_prim) { 691bf215546Sopenharmony_ci vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY); 692bf215546Sopenharmony_ci return NULL; 693bf215546Sopenharmony_ci } 694bf215546Sopenharmony_ci 695bf215546Sopenharmony_ci /* p_atomic_add_return() returns the new value rather than the old one, so 696bf215546Sopenharmony_ci * we have to subtract PVR_SRV_SYNC_PRIM_VALUE_SIZE to get the old value. 697bf215546Sopenharmony_ci */ 698bf215546Sopenharmony_ci sync_prim->offset = p_atomic_add_return(&srv_ws->sync_block_offset, 699bf215546Sopenharmony_ci PVR_SRV_SYNC_PRIM_VALUE_SIZE); 700bf215546Sopenharmony_ci sync_prim->offset -= PVR_SRV_SYNC_PRIM_VALUE_SIZE; 701bf215546Sopenharmony_ci if (sync_prim->offset == srv_ws->sync_block_size) { 702bf215546Sopenharmony_ci /* FIXME: need to free offset back to srv_ws->sync_block_offset. */ 703bf215546Sopenharmony_ci vk_free(srv_ws->alloc, sync_prim); 704bf215546Sopenharmony_ci 705bf215546Sopenharmony_ci vk_error(NULL, VK_ERROR_UNKNOWN); 706bf215546Sopenharmony_ci 707bf215546Sopenharmony_ci return NULL; 708bf215546Sopenharmony_ci } 709bf215546Sopenharmony_ci 710bf215546Sopenharmony_ci sync_prim->srv_ws = srv_ws; 711bf215546Sopenharmony_ci 712bf215546Sopenharmony_ci return sync_prim; 713bf215546Sopenharmony_ci} 714bf215546Sopenharmony_ci 715bf215546Sopenharmony_ci/* FIXME: Add support for freeing offsets back to the sync block. */ 716bf215546Sopenharmony_civoid pvr_srv_sync_prim_free(struct pvr_srv_sync_prim *sync_prim) 717bf215546Sopenharmony_ci{ 718bf215546Sopenharmony_ci if (sync_prim) { 719bf215546Sopenharmony_ci struct pvr_srv_winsys *srv_ws = sync_prim->srv_ws; 720bf215546Sopenharmony_ci 721bf215546Sopenharmony_ci vk_free(srv_ws->alloc, sync_prim); 722bf215546Sopenharmony_ci } 723bf215546Sopenharmony_ci} 724