Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/broadcom/vulkan/v3dv_cl.c
4560 views
1
/*
2
* Copyright © 2019 Raspberry Pi
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*/
23
24
#include "v3dv_private.h"
25
26
/* We don't expect that the packets we use in this file change across hw
27
* versions, so we just explicitly set the V3D_VERSION and include v3dx_pack
28
* here
29
*/
30
#define V3D_VERSION 33
31
#include "broadcom/common/v3d_macros.h"
32
#include "broadcom/cle/v3dx_pack.h"
33
34
void
35
v3dv_cl_init(struct v3dv_job *job, struct v3dv_cl *cl)
36
{
37
cl->base = NULL;
38
cl->next = cl->base;
39
cl->bo = NULL;
40
cl->size = 0;
41
cl->job = job;
42
list_inithead(&cl->bo_list);
43
}
44
45
void
46
v3dv_cl_destroy(struct v3dv_cl *cl)
47
{
48
list_for_each_entry_safe(struct v3dv_bo, bo, &cl->bo_list, list_link) {
49
assert(cl->job);
50
list_del(&bo->list_link);
51
v3dv_bo_free(cl->job->device, bo);
52
}
53
54
/* Leave the CL in a reset state to catch use after destroy instances */
55
v3dv_cl_init(NULL, cl);
56
}
57
58
static bool
59
cl_alloc_bo(struct v3dv_cl *cl, uint32_t space, bool use_branch)
60
{
61
struct v3dv_bo *bo = v3dv_bo_alloc(cl->job->device, space, "CL", true);
62
if (!bo) {
63
fprintf(stderr, "failed to allocate memory for command list\n");
64
v3dv_flag_oom(NULL, cl->job);
65
return false;
66
}
67
68
list_addtail(&bo->list_link, &cl->bo_list);
69
70
bool ok = v3dv_bo_map(cl->job->device, bo, bo->size);
71
if (!ok) {
72
fprintf(stderr, "failed to map command list buffer\n");
73
v3dv_flag_oom(NULL, cl->job);
74
return false;
75
}
76
77
/* Chain to the new BO from the old one if requested */
78
if (use_branch && cl->bo) {
79
cl_emit(cl, BRANCH, branch) {
80
branch.address = v3dv_cl_address(bo, 0);
81
}
82
} else {
83
v3dv_job_add_bo_unchecked(cl->job, bo);
84
}
85
86
cl->bo = bo;
87
cl->base = cl->bo->map;
88
cl->size = cl->bo->size;
89
cl->next = cl->base;
90
91
return true;
92
}
93
94
uint32_t
95
v3dv_cl_ensure_space(struct v3dv_cl *cl, uint32_t space, uint32_t alignment)
96
{
97
uint32_t offset = align(v3dv_cl_offset(cl), alignment);
98
99
if (offset + space <= cl->size) {
100
cl->next = cl->base + offset;
101
return offset;
102
}
103
104
cl_alloc_bo(cl, space, false);
105
return 0;
106
}
107
108
void
109
v3dv_cl_ensure_space_with_branch(struct v3dv_cl *cl, uint32_t space)
110
{
111
/* We do not want to emit branches from secondary command lists, instead,
112
* we will branch to them when we execute them in a primary using
113
* 'branch to sub list' commands, expecting each linked secondary to
114
* end with a 'return from sub list' command.
115
*/
116
bool needs_return_from_sub_list = false;
117
if (cl->job->type == V3DV_JOB_TYPE_GPU_CL_SECONDARY) {
118
if (cl->size > 0) {
119
needs_return_from_sub_list = true;
120
space += cl_packet_length(RETURN_FROM_SUB_LIST);
121
}
122
} else {
123
space += cl_packet_length(BRANCH);
124
}
125
126
if (v3dv_cl_offset(cl) + space <= cl->size)
127
return;
128
129
if (needs_return_from_sub_list)
130
cl_emit(cl, RETURN_FROM_SUB_LIST, ret);
131
132
cl_alloc_bo(cl, space, !needs_return_from_sub_list);
133
}
134
135