Path: blob/21.2-virgl/src/broadcom/vulkan/v3dv_cl.c
4560 views
/*1* Copyright © 2019 Raspberry Pi2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "v3dv_private.h"2425/* We don't expect that the packets we use in this file change across hw26* versions, so we just explicitly set the V3D_VERSION and include v3dx_pack27* here28*/29#define V3D_VERSION 3330#include "broadcom/common/v3d_macros.h"31#include "broadcom/cle/v3dx_pack.h"3233void34v3dv_cl_init(struct v3dv_job *job, struct v3dv_cl *cl)35{36cl->base = NULL;37cl->next = cl->base;38cl->bo = NULL;39cl->size = 0;40cl->job = job;41list_inithead(&cl->bo_list);42}4344void45v3dv_cl_destroy(struct v3dv_cl *cl)46{47list_for_each_entry_safe(struct v3dv_bo, bo, &cl->bo_list, list_link) {48assert(cl->job);49list_del(&bo->list_link);50v3dv_bo_free(cl->job->device, bo);51}5253/* Leave the CL in a reset state to catch use after destroy instances */54v3dv_cl_init(NULL, cl);55}5657static bool58cl_alloc_bo(struct v3dv_cl *cl, uint32_t space, bool use_branch)59{60struct v3dv_bo *bo = v3dv_bo_alloc(cl->job->device, space, "CL", true);61if (!bo) {62fprintf(stderr, "failed to allocate memory for command list\n");63v3dv_flag_oom(NULL, cl->job);64return false;65}6667list_addtail(&bo->list_link, &cl->bo_list);6869bool ok = v3dv_bo_map(cl->job->device, bo, bo->size);70if (!ok) {71fprintf(stderr, "failed to map command list buffer\n");72v3dv_flag_oom(NULL, cl->job);73return false;74}7576/* Chain to the new BO from the old one if requested */77if (use_branch && cl->bo) {78cl_emit(cl, BRANCH, branch) {79branch.address = v3dv_cl_address(bo, 0);80}81} else {82v3dv_job_add_bo_unchecked(cl->job, bo);83}8485cl->bo = bo;86cl->base = cl->bo->map;87cl->size = cl->bo->size;88cl->next = cl->base;8990return true;91}9293uint32_t94v3dv_cl_ensure_space(struct v3dv_cl *cl, uint32_t space, uint32_t alignment)95{96uint32_t offset = align(v3dv_cl_offset(cl), alignment);9798if (offset + space <= cl->size) {99cl->next = cl->base + offset;100return offset;101}102103cl_alloc_bo(cl, space, false);104return 0;105}106107void108v3dv_cl_ensure_space_with_branch(struct v3dv_cl *cl, uint32_t space)109{110/* We do not want to emit branches from secondary command lists, instead,111* we will branch to them when we execute them in a primary using112* 'branch to sub list' commands, expecting each linked secondary to113* end with a 'return from sub list' command.114*/115bool needs_return_from_sub_list = false;116if (cl->job->type == V3DV_JOB_TYPE_GPU_CL_SECONDARY) {117if (cl->size > 0) {118needs_return_from_sub_list = true;119space += cl_packet_length(RETURN_FROM_SUB_LIST);120}121} else {122space += cl_packet_length(BRANCH);123}124125if (v3dv_cl_offset(cl) + space <= cl->size)126return;127128if (needs_return_from_sub_list)129cl_emit(cl, RETURN_FROM_SUB_LIST, ret);130131cl_alloc_bo(cl, space, !needs_return_from_sub_list);132}133134135