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_emit.h
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
#ifndef FD6_EMIT_H
29
#define FD6_EMIT_H
30
31
#include "pipe/p_context.h"
32
33
#include "fd6_context.h"
34
#include "fd6_format.h"
35
#include "fd6_program.h"
36
#include "freedreno_context.h"
37
#include "ir3_gallium.h"
38
39
struct fd_ringbuffer;
40
41
/* To collect all the state objects to emit in a single CP_SET_DRAW_STATE
42
* packet, the emit tracks a collection of however many state_group's that
43
* need to be emit'd.
44
*/
45
enum fd6_state_id {
46
FD6_GROUP_PROG_CONFIG,
47
FD6_GROUP_PROG,
48
FD6_GROUP_PROG_BINNING,
49
FD6_GROUP_PROG_INTERP,
50
FD6_GROUP_PROG_FB_RAST,
51
FD6_GROUP_LRZ,
52
FD6_GROUP_LRZ_BINNING,
53
FD6_GROUP_VTXSTATE,
54
FD6_GROUP_VBO,
55
FD6_GROUP_CONST,
56
FD6_GROUP_VS_DRIVER_PARAMS,
57
FD6_GROUP_PRIMITIVE_PARAMS,
58
FD6_GROUP_VS_TEX,
59
FD6_GROUP_HS_TEX,
60
FD6_GROUP_DS_TEX,
61
FD6_GROUP_GS_TEX,
62
FD6_GROUP_FS_TEX,
63
FD6_GROUP_RASTERIZER,
64
FD6_GROUP_ZSA,
65
FD6_GROUP_BLEND,
66
FD6_GROUP_SCISSOR,
67
FD6_GROUP_BLEND_COLOR,
68
FD6_GROUP_SO,
69
FD6_GROUP_IBO,
70
FD6_GROUP_NON_GROUP, /* placeholder group for state emit in IB2, keep last */
71
};
72
73
#define ENABLE_ALL \
74
(CP_SET_DRAW_STATE__0_BINNING | CP_SET_DRAW_STATE__0_GMEM | \
75
CP_SET_DRAW_STATE__0_SYSMEM)
76
#define ENABLE_DRAW (CP_SET_DRAW_STATE__0_GMEM | CP_SET_DRAW_STATE__0_SYSMEM)
77
78
struct fd6_state_group {
79
struct fd_ringbuffer *stateobj;
80
enum fd6_state_id group_id;
81
/* enable_mask controls which states the stateobj is evaluated in,
82
* b0 is binning pass b1 and/or b2 is draw pass
83
*/
84
uint32_t enable_mask;
85
};
86
87
/* grouped together emit-state for prog/vertex/state emit: */
88
struct fd6_emit {
89
struct fd_context *ctx;
90
const struct fd_vertex_state *vtx;
91
const struct pipe_draw_info *info;
92
unsigned drawid_offset;
93
const struct pipe_draw_indirect_info *indirect;
94
const struct pipe_draw_start_count_bias *draw;
95
struct ir3_cache_key key;
96
enum fd_dirty_3d_state dirty;
97
uint32_t dirty_groups;
98
99
uint32_t sprite_coord_enable; /* bitmask */
100
bool sprite_coord_mode;
101
bool rasterflat;
102
bool primitive_restart;
103
104
/* cached to avoid repeated lookups: */
105
const struct fd6_program_state *prog;
106
107
struct ir3_shader_variant *bs;
108
struct ir3_shader_variant *vs;
109
struct ir3_shader_variant *hs;
110
struct ir3_shader_variant *ds;
111
struct ir3_shader_variant *gs;
112
struct ir3_shader_variant *fs;
113
114
unsigned streamout_mask;
115
116
struct fd6_state_group groups[32];
117
unsigned num_groups;
118
};
119
120
static inline const struct fd6_program_state *
121
fd6_emit_get_prog(struct fd6_emit *emit)
122
{
123
if (!emit->prog) {
124
struct ir3_program_state *s = ir3_cache_lookup(
125
emit->ctx->shader_cache, &emit->key, &emit->ctx->debug);
126
emit->prog = fd6_program_state(s);
127
}
128
return emit->prog;
129
}
130
131
static inline void
132
fd6_emit_take_group(struct fd6_emit *emit, struct fd_ringbuffer *stateobj,
133
enum fd6_state_id group_id, unsigned enable_mask)
134
{
135
debug_assert(emit->num_groups < ARRAY_SIZE(emit->groups));
136
struct fd6_state_group *g = &emit->groups[emit->num_groups++];
137
g->stateobj = stateobj;
138
g->group_id = group_id;
139
g->enable_mask = enable_mask;
140
}
141
142
static inline void
143
fd6_emit_add_group(struct fd6_emit *emit, struct fd_ringbuffer *stateobj,
144
enum fd6_state_id group_id, unsigned enable_mask)
145
{
146
fd6_emit_take_group(emit, fd_ringbuffer_ref(stateobj), group_id,
147
enable_mask);
148
}
149
150
static inline unsigned
151
fd6_event_write(struct fd_batch *batch, struct fd_ringbuffer *ring,
152
enum vgt_event_type evt, bool timestamp)
153
{
154
unsigned seqno = 0;
155
156
fd_reset_wfi(batch);
157
158
OUT_PKT7(ring, CP_EVENT_WRITE, timestamp ? 4 : 1);
159
OUT_RING(ring, CP_EVENT_WRITE_0_EVENT(evt));
160
if (timestamp) {
161
struct fd6_context *fd6_ctx = fd6_context(batch->ctx);
162
seqno = ++fd6_ctx->seqno;
163
OUT_RELOC(ring, control_ptr(fd6_ctx, seqno)); /* ADDR_LO/HI */
164
OUT_RING(ring, seqno);
165
}
166
167
return seqno;
168
}
169
170
static inline void
171
fd6_cache_inv(struct fd_batch *batch, struct fd_ringbuffer *ring)
172
{
173
fd6_event_write(batch, ring, PC_CCU_INVALIDATE_COLOR, false);
174
fd6_event_write(batch, ring, PC_CCU_INVALIDATE_DEPTH, false);
175
fd6_event_write(batch, ring, CACHE_INVALIDATE, false);
176
}
177
178
static inline void
179
fd6_cache_flush(struct fd_batch *batch, struct fd_ringbuffer *ring)
180
{
181
struct fd6_context *fd6_ctx = fd6_context(batch->ctx);
182
unsigned seqno;
183
184
seqno = fd6_event_write(batch, ring, RB_DONE_TS, true);
185
186
OUT_PKT7(ring, CP_WAIT_REG_MEM, 6);
187
OUT_RING(ring, CP_WAIT_REG_MEM_0_FUNCTION(WRITE_EQ) |
188
CP_WAIT_REG_MEM_0_POLL_MEMORY);
189
OUT_RELOC(ring, control_ptr(fd6_ctx, seqno));
190
OUT_RING(ring, CP_WAIT_REG_MEM_3_REF(seqno));
191
OUT_RING(ring, CP_WAIT_REG_MEM_4_MASK(~0));
192
OUT_RING(ring, CP_WAIT_REG_MEM_5_DELAY_LOOP_CYCLES(16));
193
194
seqno = fd6_event_write(batch, ring, CACHE_FLUSH_TS, true);
195
196
OUT_PKT7(ring, CP_WAIT_MEM_GTE, 4);
197
OUT_RING(ring, CP_WAIT_MEM_GTE_0_RESERVED(0));
198
OUT_RELOC(ring, control_ptr(fd6_ctx, seqno));
199
OUT_RING(ring, CP_WAIT_MEM_GTE_3_REF(seqno));
200
}
201
202
static inline void
203
fd6_emit_blit(struct fd_batch *batch, struct fd_ringbuffer *ring)
204
{
205
emit_marker6(ring, 7);
206
fd6_event_write(batch, ring, BLIT, false);
207
emit_marker6(ring, 7);
208
}
209
210
static inline void
211
fd6_emit_lrz_flush(struct fd_ringbuffer *ring)
212
{
213
OUT_PKT7(ring, CP_EVENT_WRITE, 1);
214
OUT_RING(ring, LRZ_FLUSH);
215
}
216
217
static inline bool
218
fd6_geom_stage(gl_shader_stage type)
219
{
220
switch (type) {
221
case MESA_SHADER_VERTEX:
222
case MESA_SHADER_TESS_CTRL:
223
case MESA_SHADER_TESS_EVAL:
224
case MESA_SHADER_GEOMETRY:
225
return true;
226
case MESA_SHADER_FRAGMENT:
227
case MESA_SHADER_COMPUTE:
228
case MESA_SHADER_KERNEL:
229
return false;
230
default:
231
unreachable("bad shader type");
232
}
233
}
234
235
static inline uint32_t
236
fd6_stage2opcode(gl_shader_stage type)
237
{
238
return fd6_geom_stage(type) ? CP_LOAD_STATE6_GEOM : CP_LOAD_STATE6_FRAG;
239
}
240
241
static inline enum a6xx_state_block
242
fd6_stage2shadersb(gl_shader_stage type)
243
{
244
switch (type) {
245
case MESA_SHADER_VERTEX:
246
return SB6_VS_SHADER;
247
case MESA_SHADER_TESS_CTRL:
248
return SB6_HS_SHADER;
249
case MESA_SHADER_TESS_EVAL:
250
return SB6_DS_SHADER;
251
case MESA_SHADER_GEOMETRY:
252
return SB6_GS_SHADER;
253
case MESA_SHADER_FRAGMENT:
254
return SB6_FS_SHADER;
255
case MESA_SHADER_COMPUTE:
256
case MESA_SHADER_KERNEL:
257
return SB6_CS_SHADER;
258
default:
259
unreachable("bad shader type");
260
return ~0;
261
}
262
}
263
264
static inline enum a6xx_tess_spacing
265
fd6_gl2spacing(enum gl_tess_spacing spacing)
266
{
267
switch (spacing) {
268
case TESS_SPACING_EQUAL:
269
return TESS_EQUAL;
270
case TESS_SPACING_FRACTIONAL_ODD:
271
return TESS_FRACTIONAL_ODD;
272
case TESS_SPACING_FRACTIONAL_EVEN:
273
return TESS_FRACTIONAL_EVEN;
274
case TESS_SPACING_UNSPECIFIED:
275
default:
276
unreachable("spacing must be specified");
277
}
278
}
279
280
bool fd6_emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
281
enum pipe_shader_type type,
282
struct fd_texture_stateobj *tex, unsigned bcolor_offset,
283
const struct ir3_shader_variant *v) assert_dt;
284
285
void fd6_emit_state(struct fd_ringbuffer *ring,
286
struct fd6_emit *emit) assert_dt;
287
288
void fd6_emit_cs_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
289
struct ir3_shader_variant *cp) assert_dt;
290
291
void fd6_emit_restore(struct fd_batch *batch, struct fd_ringbuffer *ring);
292
293
void fd6_emit_init_screen(struct pipe_screen *pscreen);
294
void fd6_emit_init(struct pipe_context *pctx);
295
296
static inline void
297
fd6_emit_ib(struct fd_ringbuffer *ring, struct fd_ringbuffer *target)
298
{
299
emit_marker6(ring, 6);
300
__OUT_IB5(ring, target);
301
emit_marker6(ring, 6);
302
}
303
304
#define WRITE(reg, val) \
305
do { \
306
OUT_PKT4(ring, reg, 1); \
307
OUT_RING(ring, val); \
308
} while (0)
309
310
#endif /* FD6_EMIT_H */
311
312