Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/freedreno/a6xx/fd6_context.c
4574 views
1
/*
2
* Copyright (C) 2016 Rob Clark <[email protected]>
3
* Copyright © 2018 Google, Inc.
4
*
5
* Permission is hereby granted, free of charge, to any person obtaining a
6
* copy of this software and associated documentation files (the "Software"),
7
* to deal in the Software without restriction, including without limitation
8
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
* and/or sell copies of the Software, and to permit persons to whom the
10
* Software is furnished to do so, subject to the following conditions:
11
*
12
* The above copyright notice and this permission notice (including the next
13
* paragraph) shall be included in all copies or substantial portions of the
14
* Software.
15
*
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
* SOFTWARE.
23
*
24
* Authors:
25
* Rob Clark <[email protected]>
26
*/
27
28
#include "freedreno_query_acc.h"
29
#include "freedreno_state.h"
30
31
#include "fd6_blend.h"
32
#include "fd6_blitter.h"
33
#include "fd6_compute.h"
34
#include "fd6_context.h"
35
#include "fd6_draw.h"
36
#include "fd6_emit.h"
37
#include "fd6_gmem.h"
38
#include "fd6_image.h"
39
#include "fd6_program.h"
40
#include "fd6_query.h"
41
#include "fd6_rasterizer.h"
42
#include "fd6_resource.h"
43
#include "fd6_texture.h"
44
#include "fd6_zsa.h"
45
46
static void
47
fd6_context_destroy(struct pipe_context *pctx) in_dt
48
{
49
struct fd6_context *fd6_ctx = fd6_context(fd_context(pctx));
50
51
u_upload_destroy(fd6_ctx->border_color_uploader);
52
pipe_resource_reference(&fd6_ctx->border_color_buf, NULL);
53
54
fd_context_destroy(pctx);
55
56
if (fd6_ctx->vsc_draw_strm)
57
fd_bo_del(fd6_ctx->vsc_draw_strm);
58
if (fd6_ctx->vsc_prim_strm)
59
fd_bo_del(fd6_ctx->vsc_prim_strm);
60
fd_bo_del(fd6_ctx->control_mem);
61
62
fd_context_cleanup_common_vbos(&fd6_ctx->base);
63
64
fd6_texture_fini(pctx);
65
66
free(fd6_ctx);
67
}
68
69
/* clang-format off */
70
static const uint8_t primtypes[] = {
71
[PIPE_PRIM_POINTS] = DI_PT_POINTLIST,
72
[PIPE_PRIM_LINES] = DI_PT_LINELIST,
73
[PIPE_PRIM_LINE_STRIP] = DI_PT_LINESTRIP,
74
[PIPE_PRIM_LINE_LOOP] = DI_PT_LINELOOP,
75
[PIPE_PRIM_TRIANGLES] = DI_PT_TRILIST,
76
[PIPE_PRIM_TRIANGLE_STRIP] = DI_PT_TRISTRIP,
77
[PIPE_PRIM_TRIANGLE_FAN] = DI_PT_TRIFAN,
78
[PIPE_PRIM_LINES_ADJACENCY] = DI_PT_LINE_ADJ,
79
[PIPE_PRIM_LINE_STRIP_ADJACENCY] = DI_PT_LINESTRIP_ADJ,
80
[PIPE_PRIM_TRIANGLES_ADJACENCY] = DI_PT_TRI_ADJ,
81
[PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY] = DI_PT_TRISTRIP_ADJ,
82
[PIPE_PRIM_PATCHES] = DI_PT_PATCHES0,
83
[PIPE_PRIM_MAX] = DI_PT_RECTLIST, /* internal clear blits */
84
};
85
/* clang-format on */
86
87
static void *
88
fd6_vertex_state_create(struct pipe_context *pctx, unsigned num_elements,
89
const struct pipe_vertex_element *elements)
90
{
91
struct fd_context *ctx = fd_context(pctx);
92
93
struct fd6_vertex_stateobj *state = CALLOC_STRUCT(fd6_vertex_stateobj);
94
memcpy(state->base.pipe, elements, sizeof(*elements) * num_elements);
95
state->base.num_elements = num_elements;
96
state->stateobj =
97
fd_ringbuffer_new_object(ctx->pipe, 4 * (num_elements * 2 + 1));
98
struct fd_ringbuffer *ring = state->stateobj;
99
100
OUT_PKT4(ring, REG_A6XX_VFD_DECODE(0), 2 * num_elements);
101
for (int32_t i = 0; i < num_elements; i++) {
102
const struct pipe_vertex_element *elem = &elements[i];
103
enum pipe_format pfmt = elem->src_format;
104
enum a6xx_format fmt = fd6_pipe2vtx(pfmt);
105
bool isint = util_format_is_pure_integer(pfmt);
106
debug_assert(fmt != FMT6_NONE);
107
108
OUT_RING(ring, A6XX_VFD_DECODE_INSTR_IDX(elem->vertex_buffer_index) |
109
A6XX_VFD_DECODE_INSTR_OFFSET(elem->src_offset) |
110
A6XX_VFD_DECODE_INSTR_FORMAT(fmt) |
111
COND(elem->instance_divisor,
112
A6XX_VFD_DECODE_INSTR_INSTANCED) |
113
A6XX_VFD_DECODE_INSTR_SWAP(fd6_pipe2swap(pfmt)) |
114
A6XX_VFD_DECODE_INSTR_UNK30 |
115
COND(!isint, A6XX_VFD_DECODE_INSTR_FLOAT));
116
OUT_RING(ring,
117
MAX2(1, elem->instance_divisor)); /* VFD_DECODE[j].STEP_RATE */
118
}
119
120
return state;
121
}
122
123
static void
124
fd6_vertex_state_delete(struct pipe_context *pctx, void *hwcso)
125
{
126
struct fd6_vertex_stateobj *so = hwcso;
127
128
fd_ringbuffer_del(so->stateobj);
129
FREE(hwcso);
130
}
131
132
static void
133
validate_surface(struct pipe_context *pctx, struct pipe_surface *psurf)
134
assert_dt
135
{
136
fd6_validate_format(fd_context(pctx), fd_resource(psurf->texture),
137
psurf->format);
138
}
139
140
static void
141
fd6_set_framebuffer_state(struct pipe_context *pctx,
142
const struct pipe_framebuffer_state *pfb)
143
in_dt
144
{
145
if (pfb->zsbuf)
146
validate_surface(pctx, pfb->zsbuf);
147
148
for (unsigned i = 0; i < pfb->nr_cbufs; i++) {
149
if (!pfb->cbufs[i])
150
continue;
151
validate_surface(pctx, pfb->cbufs[i]);
152
}
153
154
fd_set_framebuffer_state(pctx, pfb);
155
}
156
157
158
static void
159
setup_state_map(struct fd_context *ctx)
160
{
161
STATIC_ASSERT(FD6_GROUP_NON_GROUP < 32);
162
163
fd_context_add_map(ctx, FD_DIRTY_VTXSTATE, BIT(FD6_GROUP_VTXSTATE));
164
fd_context_add_map(ctx, FD_DIRTY_VTXBUF, BIT(FD6_GROUP_VBO));
165
fd_context_add_map(ctx, FD_DIRTY_ZSA | FD_DIRTY_RASTERIZER,
166
BIT(FD6_GROUP_ZSA));
167
fd_context_add_map(ctx, FD_DIRTY_ZSA | FD_DIRTY_BLEND | FD_DIRTY_PROG,
168
BIT(FD6_GROUP_LRZ) | BIT(FD6_GROUP_LRZ_BINNING));
169
fd_context_add_map(ctx, FD_DIRTY_PROG, BIT(FD6_GROUP_PROG));
170
fd_context_add_map(ctx, FD_DIRTY_RASTERIZER, BIT(FD6_GROUP_RASTERIZER));
171
fd_context_add_map(ctx,
172
FD_DIRTY_FRAMEBUFFER | FD_DIRTY_RASTERIZER_DISCARD |
173
FD_DIRTY_PROG | FD_DIRTY_BLEND_DUAL,
174
BIT(FD6_GROUP_PROG_FB_RAST));
175
fd_context_add_map(ctx, FD_DIRTY_BLEND | FD_DIRTY_SAMPLE_MASK,
176
BIT(FD6_GROUP_BLEND));
177
fd_context_add_map(ctx, FD_DIRTY_BLEND_COLOR, BIT(FD6_GROUP_BLEND_COLOR));
178
fd_context_add_map(ctx, FD_DIRTY_SSBO | FD_DIRTY_IMAGE | FD_DIRTY_PROG,
179
BIT(FD6_GROUP_IBO));
180
fd_context_add_map(ctx, FD_DIRTY_PROG,
181
BIT(FD6_GROUP_VS_TEX) | BIT(FD6_GROUP_HS_TEX) |
182
BIT(FD6_GROUP_DS_TEX) | BIT(FD6_GROUP_GS_TEX) |
183
BIT(FD6_GROUP_FS_TEX));
184
fd_context_add_map(ctx, FD_DIRTY_PROG | FD_DIRTY_CONST,
185
BIT(FD6_GROUP_CONST));
186
fd_context_add_map(ctx, FD_DIRTY_STREAMOUT, BIT(FD6_GROUP_SO));
187
188
fd_context_add_shader_map(ctx, PIPE_SHADER_VERTEX, FD_DIRTY_SHADER_TEX,
189
BIT(FD6_GROUP_VS_TEX));
190
fd_context_add_shader_map(ctx, PIPE_SHADER_TESS_CTRL, FD_DIRTY_SHADER_TEX,
191
BIT(FD6_GROUP_HS_TEX));
192
fd_context_add_shader_map(ctx, PIPE_SHADER_TESS_EVAL, FD_DIRTY_SHADER_TEX,
193
BIT(FD6_GROUP_DS_TEX));
194
fd_context_add_shader_map(ctx, PIPE_SHADER_GEOMETRY, FD_DIRTY_SHADER_TEX,
195
BIT(FD6_GROUP_GS_TEX));
196
fd_context_add_shader_map(ctx, PIPE_SHADER_FRAGMENT, FD_DIRTY_SHADER_TEX,
197
BIT(FD6_GROUP_FS_TEX));
198
199
/* NOTE: scissor enabled bit is part of rasterizer state, but
200
* fd_rasterizer_state_bind() will mark scissor dirty if needed:
201
*/
202
fd_context_add_map(ctx, FD_DIRTY_SCISSOR, BIT(FD6_GROUP_SCISSOR));
203
204
/* Stuff still emit in IB2
205
*
206
* NOTE: viewport state doesn't seem to change frequently, so possibly
207
* move it into FD6_GROUP_RASTERIZER?
208
*/
209
fd_context_add_map(
210
ctx, FD_DIRTY_STENCIL_REF | FD_DIRTY_VIEWPORT | FD_DIRTY_RASTERIZER,
211
BIT(FD6_GROUP_NON_GROUP));
212
}
213
214
struct pipe_context *
215
fd6_context_create(struct pipe_screen *pscreen, void *priv,
216
unsigned flags) disable_thread_safety_analysis
217
{
218
struct fd_screen *screen = fd_screen(pscreen);
219
struct fd6_context *fd6_ctx = CALLOC_STRUCT(fd6_context);
220
struct pipe_context *pctx;
221
222
if (!fd6_ctx)
223
return NULL;
224
225
pctx = &fd6_ctx->base.base;
226
pctx->screen = pscreen;
227
228
fd6_ctx->base.dev = fd_device_ref(screen->dev);
229
fd6_ctx->base.screen = fd_screen(pscreen);
230
fd6_ctx->base.last.key = &fd6_ctx->last_key;
231
232
pctx->destroy = fd6_context_destroy;
233
pctx->create_blend_state = fd6_blend_state_create;
234
pctx->create_rasterizer_state = fd6_rasterizer_state_create;
235
pctx->create_depth_stencil_alpha_state = fd6_zsa_state_create;
236
pctx->create_vertex_elements_state = fd6_vertex_state_create;
237
238
fd6_draw_init(pctx);
239
fd6_compute_init(pctx);
240
fd6_gmem_init(pctx);
241
fd6_texture_init(pctx);
242
fd6_prog_init(pctx);
243
fd6_emit_init(pctx);
244
fd6_query_context_init(pctx);
245
246
setup_state_map(&fd6_ctx->base);
247
248
pctx = fd_context_init(&fd6_ctx->base, pscreen, primtypes, priv, flags);
249
if (!pctx)
250
return NULL;
251
252
pctx->set_framebuffer_state = fd6_set_framebuffer_state;
253
254
/* after fd_context_init() to override set_shader_images() */
255
fd6_image_init(pctx);
256
257
util_blitter_set_texture_multisample(fd6_ctx->base.blitter, true);
258
259
pctx->delete_vertex_elements_state = fd6_vertex_state_delete;
260
261
/* fd_context_init overwrites delete_rasterizer_state, so set this
262
* here. */
263
pctx->delete_rasterizer_state = fd6_rasterizer_state_delete;
264
pctx->delete_blend_state = fd6_blend_state_delete;
265
pctx->delete_depth_stencil_alpha_state = fd6_zsa_state_delete;
266
267
/* initial sizes for VSC buffers (or rather the per-pipe sizes
268
* which is used to derive entire buffer size:
269
*/
270
fd6_ctx->vsc_draw_strm_pitch = 0x440;
271
fd6_ctx->vsc_prim_strm_pitch = 0x1040;
272
273
fd6_ctx->control_mem =
274
fd_bo_new(screen->dev, 0x1000, 0, "control");
275
276
memset(fd_bo_map(fd6_ctx->control_mem), 0, sizeof(struct fd6_control));
277
278
fd_context_setup_common_vbos(&fd6_ctx->base);
279
280
fd6_blitter_init(pctx);
281
282
fd6_ctx->border_color_uploader =
283
u_upload_create(pctx, 4096, 0, PIPE_USAGE_STREAM, 0);
284
285
return fd_context_init_tc(pctx, flags);
286
}
287
288