Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/freedreno/freedreno_program.c
4570 views
1
/*
2
* Copyright (C) 2014 Rob Clark <[email protected]>
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 FROM,
20
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
* SOFTWARE.
22
*
23
* Authors:
24
* Rob Clark <[email protected]>
25
*/
26
27
#include "tgsi/tgsi_text.h"
28
#include "tgsi/tgsi_ureg.h"
29
30
#include "util/u_simple_shaders.h"
31
32
#include "freedreno_context.h"
33
#include "freedreno_program.h"
34
35
static void
36
update_bound_stage(struct fd_context *ctx, enum pipe_shader_type shader,
37
bool bound) assert_dt
38
{
39
if (bound) {
40
ctx->bound_shader_stages |= BIT(shader);
41
} else {
42
ctx->bound_shader_stages &= ~BIT(shader);
43
}
44
}
45
46
static void
47
fd_vs_state_bind(struct pipe_context *pctx, void *hwcso) in_dt
48
{
49
struct fd_context *ctx = fd_context(pctx);
50
ctx->prog.vs = hwcso;
51
fd_context_dirty_shader(ctx, PIPE_SHADER_VERTEX, FD_DIRTY_SHADER_PROG);
52
update_bound_stage(ctx, PIPE_SHADER_VERTEX, !!hwcso);
53
}
54
55
static void
56
fd_tcs_state_bind(struct pipe_context *pctx, void *hwcso) in_dt
57
{
58
struct fd_context *ctx = fd_context(pctx);
59
ctx->prog.hs = hwcso;
60
fd_context_dirty_shader(ctx, PIPE_SHADER_TESS_CTRL, FD_DIRTY_SHADER_PROG);
61
update_bound_stage(ctx, PIPE_SHADER_TESS_CTRL, !!hwcso);
62
}
63
64
static void
65
fd_tes_state_bind(struct pipe_context *pctx, void *hwcso) in_dt
66
{
67
struct fd_context *ctx = fd_context(pctx);
68
ctx->prog.ds = hwcso;
69
fd_context_dirty_shader(ctx, PIPE_SHADER_TESS_EVAL, FD_DIRTY_SHADER_PROG);
70
update_bound_stage(ctx, PIPE_SHADER_TESS_EVAL, !!hwcso);
71
}
72
73
static void
74
fd_gs_state_bind(struct pipe_context *pctx, void *hwcso) in_dt
75
{
76
struct fd_context *ctx = fd_context(pctx);
77
ctx->prog.gs = hwcso;
78
fd_context_dirty_shader(ctx, PIPE_SHADER_GEOMETRY, FD_DIRTY_SHADER_PROG);
79
update_bound_stage(ctx, PIPE_SHADER_GEOMETRY, !!hwcso);
80
}
81
82
static void
83
fd_fs_state_bind(struct pipe_context *pctx, void *hwcso) in_dt
84
{
85
struct fd_context *ctx = fd_context(pctx);
86
ctx->prog.fs = hwcso;
87
fd_context_dirty_shader(ctx, PIPE_SHADER_FRAGMENT, FD_DIRTY_SHADER_PROG);
88
update_bound_stage(ctx, PIPE_SHADER_FRAGMENT, !!hwcso);
89
}
90
91
static const char *solid_fs = "FRAG \n"
92
"PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1 \n"
93
"DCL CONST[0] \n"
94
"DCL OUT[0], COLOR \n"
95
" 0: MOV OUT[0], CONST[0] \n"
96
" 1: END \n";
97
98
static const char *solid_vs = "VERT \n"
99
"DCL IN[0] \n"
100
"DCL OUT[0], POSITION \n"
101
" 0: MOV OUT[0], IN[0] \n"
102
" 1: END \n";
103
104
static void *
105
assemble_tgsi(struct pipe_context *pctx, const char *src, bool frag)
106
{
107
struct tgsi_token toks[32];
108
struct pipe_shader_state cso = {
109
.tokens = toks,
110
};
111
112
bool ret = tgsi_text_translate(src, toks, ARRAY_SIZE(toks));
113
assume(ret);
114
115
if (frag)
116
return pctx->create_fs_state(pctx, &cso);
117
else
118
return pctx->create_vs_state(pctx, &cso);
119
}
120
121
/* the correct semantic to use for the texcoord varying depends on pipe-cap: */
122
static enum tgsi_semantic
123
texcoord_semantic(struct pipe_context *pctx)
124
{
125
struct pipe_screen *pscreen = pctx->screen;
126
127
if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_TEXCOORD)) {
128
return TGSI_SEMANTIC_TEXCOORD;
129
} else {
130
return TGSI_SEMANTIC_GENERIC;
131
}
132
}
133
134
static void *
135
fd_prog_blit_vs(struct pipe_context *pctx)
136
{
137
struct ureg_program *ureg;
138
139
ureg = ureg_create(PIPE_SHADER_VERTEX);
140
if (!ureg)
141
return NULL;
142
143
struct ureg_src in0 = ureg_DECL_vs_input(ureg, 0);
144
struct ureg_src in1 = ureg_DECL_vs_input(ureg, 1);
145
146
struct ureg_dst out0 = ureg_DECL_output(ureg, texcoord_semantic(pctx), 0);
147
struct ureg_dst out1 = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 1);
148
149
ureg_MOV(ureg, out0, in0);
150
ureg_MOV(ureg, out1, in1);
151
152
ureg_END(ureg);
153
154
return ureg_create_shader_and_destroy(ureg, pctx);
155
}
156
157
static void *
158
fd_prog_blit_fs(struct pipe_context *pctx, int rts, bool depth)
159
{
160
int i;
161
struct ureg_src tc;
162
struct ureg_program *ureg;
163
164
debug_assert(rts <= MAX_RENDER_TARGETS);
165
166
ureg = ureg_create(PIPE_SHADER_FRAGMENT);
167
if (!ureg)
168
return NULL;
169
170
tc = ureg_DECL_fs_input(ureg, texcoord_semantic(pctx), 0,
171
TGSI_INTERPOLATE_PERSPECTIVE);
172
for (i = 0; i < rts; i++)
173
ureg_TEX(ureg, ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, i),
174
TGSI_TEXTURE_2D, tc, ureg_DECL_sampler(ureg, i));
175
if (depth)
176
ureg_TEX(ureg,
177
ureg_writemask(ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0),
178
TGSI_WRITEMASK_Z),
179
TGSI_TEXTURE_2D, tc, ureg_DECL_sampler(ureg, rts));
180
181
ureg_END(ureg);
182
183
return ureg_create_shader_and_destroy(ureg, pctx);
184
}
185
186
void
187
fd_prog_init(struct pipe_context *pctx)
188
{
189
struct fd_context *ctx = fd_context(pctx);
190
int i;
191
192
pctx->bind_vs_state = fd_vs_state_bind;
193
pctx->bind_tcs_state = fd_tcs_state_bind;
194
pctx->bind_tes_state = fd_tes_state_bind;
195
pctx->bind_gs_state = fd_gs_state_bind;
196
pctx->bind_fs_state = fd_fs_state_bind;
197
198
ctx->solid_prog.fs = assemble_tgsi(pctx, solid_fs, true);
199
ctx->solid_prog.vs = assemble_tgsi(pctx, solid_vs, false);
200
201
if (ctx->screen->gpu_id >= 600) {
202
ctx->solid_layered_prog.fs = assemble_tgsi(pctx, solid_fs, true);
203
ctx->solid_layered_prog.vs = util_make_layered_clear_vertex_shader(pctx);
204
}
205
206
if (ctx->screen->gpu_id >= 500)
207
return;
208
209
ctx->blit_prog[0].vs = fd_prog_blit_vs(pctx);
210
ctx->blit_prog[0].fs = fd_prog_blit_fs(pctx, 1, false);
211
212
if (ctx->screen->gpu_id < 300)
213
return;
214
215
for (i = 1; i < ctx->screen->max_rts; i++) {
216
ctx->blit_prog[i].vs = ctx->blit_prog[0].vs;
217
ctx->blit_prog[i].fs = fd_prog_blit_fs(pctx, i + 1, false);
218
}
219
220
ctx->blit_z.vs = ctx->blit_prog[0].vs;
221
ctx->blit_z.fs = fd_prog_blit_fs(pctx, 0, true);
222
ctx->blit_zs.vs = ctx->blit_prog[0].vs;
223
ctx->blit_zs.fs = fd_prog_blit_fs(pctx, 1, true);
224
}
225
226
void
227
fd_prog_fini(struct pipe_context *pctx)
228
{
229
struct fd_context *ctx = fd_context(pctx);
230
int i;
231
232
pctx->delete_vs_state(pctx, ctx->solid_prog.vs);
233
pctx->delete_fs_state(pctx, ctx->solid_prog.fs);
234
235
if (ctx->screen->gpu_id >= 600) {
236
pctx->delete_vs_state(pctx, ctx->solid_layered_prog.vs);
237
pctx->delete_fs_state(pctx, ctx->solid_layered_prog.fs);
238
}
239
240
if (ctx->screen->gpu_id >= 500)
241
return;
242
243
pctx->delete_vs_state(pctx, ctx->blit_prog[0].vs);
244
pctx->delete_fs_state(pctx, ctx->blit_prog[0].fs);
245
246
if (ctx->screen->gpu_id < 300)
247
return;
248
249
for (i = 1; i < ctx->screen->max_rts; i++)
250
pctx->delete_fs_state(pctx, ctx->blit_prog[i].fs);
251
pctx->delete_fs_state(pctx, ctx->blit_z.fs);
252
pctx->delete_fs_state(pctx, ctx->blit_zs.fs);
253
}
254
255