2
* Copyright © 2014-2015 Broadcom
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:
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
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
24
#include "util/u_pack_color.h"
25
#include "util/u_upload_mgr.h"
26
#include "util/format_srgb.h"
28
#include "vc4_context.h"
32
write_texture_p0(struct vc4_job *job,
33
struct vc4_cl_out **uniforms,
34
struct vc4_texture_stateobj *texstate,
37
struct vc4_sampler_view *sview =
38
vc4_sampler_view(texstate->textures[unit]);
39
struct vc4_resource *rsc = vc4_resource(sview->texture);
41
cl_reloc(job, &job->uniforms, uniforms, rsc->bo, sview->texture_p0);
45
write_texture_p1(struct vc4_job *job,
46
struct vc4_cl_out **uniforms,
47
struct vc4_texture_stateobj *texstate,
50
struct vc4_sampler_view *sview =
51
vc4_sampler_view(texstate->textures[unit]);
52
struct vc4_sampler_state *sampler =
53
vc4_sampler_state(texstate->samplers[unit]);
55
cl_aligned_u32(uniforms, sview->texture_p1 | sampler->texture_p1);
59
write_texture_p2(struct vc4_job *job,
60
struct vc4_cl_out **uniforms,
61
struct vc4_texture_stateobj *texstate,
64
uint32_t unit = data & 0xffff;
65
struct pipe_sampler_view *texture = texstate->textures[unit];
66
struct vc4_resource *rsc = vc4_resource(texture->texture);
68
cl_aligned_u32(uniforms,
69
VC4_SET_FIELD(VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE,
71
VC4_SET_FIELD(rsc->cube_map_stride >> 12, VC4_TEX_P2_CMST) |
72
VC4_SET_FIELD((data >> 16) & 1, VC4_TEX_P2_BSLOD));
76
write_texture_first_level(struct vc4_job *job,
77
struct vc4_cl_out **uniforms,
78
struct vc4_texture_stateobj *texstate,
81
uint32_t unit = data & 0xffff;
82
struct pipe_sampler_view *texture = texstate->textures[unit];
84
cl_aligned_f(uniforms, texture->u.tex.first_level);
88
write_texture_msaa_addr(struct vc4_job *job,
89
struct vc4_cl_out **uniforms,
90
struct vc4_texture_stateobj *texstate,
93
struct pipe_sampler_view *texture = texstate->textures[unit];
94
struct vc4_resource *rsc = vc4_resource(texture->texture);
96
cl_aligned_reloc(job, &job->uniforms, uniforms, rsc->bo, 0);
100
#define SWIZ(x,y,z,w) { \
108
write_texture_border_color(struct vc4_job *job,
109
struct vc4_cl_out **uniforms,
110
struct vc4_texture_stateobj *texstate,
113
struct pipe_sampler_state *sampler = texstate->samplers[unit];
114
struct pipe_sampler_view *texture = texstate->textures[unit];
115
struct vc4_resource *rsc = vc4_resource(texture->texture);
118
const struct util_format_description *tex_format_desc =
119
util_format_description(texture->format);
121
float border_color[4];
122
for (int i = 0; i < 4; i++)
123
border_color[i] = sampler->border_color.f[i];
124
if (util_format_is_srgb(texture->format)) {
125
for (int i = 0; i < 3; i++)
127
util_format_linear_to_srgb_float(border_color[i]);
130
/* Turn the border color into the layout of channels that it would
131
* have when stored as texture contents.
133
float storage_color[4];
134
util_format_unswizzle_4f(storage_color,
136
tex_format_desc->swizzle);
138
/* Now, pack so that when the vc4_format-sampled texture contents are
139
* replaced with our border color, the vc4_get_format_swizzle()
140
* swizzling will get the right channels.
142
if (util_format_is_depth_or_stencil(texture->format)) {
143
uc.ui[0] = util_pack_z(PIPE_FORMAT_Z24X8_UNORM,
144
sampler->border_color.f[0]) << 8;
146
switch (rsc->vc4_format) {
148
case VC4_TEXTURE_TYPE_RGBA8888:
149
util_pack_color(storage_color,
150
PIPE_FORMAT_R8G8B8A8_UNORM, &uc);
152
case VC4_TEXTURE_TYPE_RGBA4444:
153
case VC4_TEXTURE_TYPE_RGBA5551:
154
util_pack_color(storage_color,
155
PIPE_FORMAT_A8B8G8R8_UNORM, &uc);
157
case VC4_TEXTURE_TYPE_RGB565:
158
util_pack_color(storage_color,
159
PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
161
case VC4_TEXTURE_TYPE_ALPHA:
162
uc.ui[0] = float_to_ubyte(storage_color[0]) << 24;
164
case VC4_TEXTURE_TYPE_LUMALPHA:
165
uc.ui[0] = ((float_to_ubyte(storage_color[1]) << 24) |
166
(float_to_ubyte(storage_color[0]) << 0));
171
cl_aligned_u32(uniforms, uc.ui[0]);
175
get_texrect_scale(struct vc4_texture_stateobj *texstate,
176
enum quniform_contents contents,
179
struct pipe_sampler_view *texture = texstate->textures[data];
182
if (contents == QUNIFORM_TEXRECT_SCALE_X)
183
dim = texture->texture->width0;
185
dim = texture->texture->height0;
187
return fui(1.0f / dim);
191
vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader,
192
struct vc4_constbuf_stateobj *cb,
193
struct vc4_texture_stateobj *texstate)
195
struct vc4_shader_uniform_info *uinfo = &shader->uniforms;
196
struct vc4_job *job = vc4->job;
197
const uint32_t *gallium_uniforms = cb->cb[0].user_buffer;
199
cl_ensure_space(&job->uniforms, (uinfo->count +
200
uinfo->num_texture_samples) * 4);
202
struct vc4_cl_out *uniforms =
203
cl_start_shader_reloc(&job->uniforms,
204
uinfo->num_texture_samples);
206
for (int i = 0; i < uinfo->count; i++) {
207
enum quniform_contents contents = uinfo->contents[i];
208
uint32_t data = uinfo->data[i];
211
case QUNIFORM_CONSTANT:
212
cl_aligned_u32(&uniforms, data);
214
case QUNIFORM_UNIFORM:
215
cl_aligned_u32(&uniforms,
216
gallium_uniforms[data]);
218
case QUNIFORM_VIEWPORT_X_SCALE:
219
cl_aligned_f(&uniforms, vc4->viewport.scale[0] * 16.0f);
221
case QUNIFORM_VIEWPORT_Y_SCALE:
222
cl_aligned_f(&uniforms, vc4->viewport.scale[1] * 16.0f);
225
case QUNIFORM_VIEWPORT_Z_OFFSET:
226
cl_aligned_f(&uniforms, vc4->viewport.translate[2]);
228
case QUNIFORM_VIEWPORT_Z_SCALE:
229
cl_aligned_f(&uniforms, vc4->viewport.scale[2]);
232
case QUNIFORM_USER_CLIP_PLANE:
233
cl_aligned_f(&uniforms,
234
vc4->clip.ucp[data / 4][data % 4]);
237
case QUNIFORM_TEXTURE_CONFIG_P0:
238
write_texture_p0(job, &uniforms, texstate, data);
241
case QUNIFORM_TEXTURE_CONFIG_P1:
242
write_texture_p1(job, &uniforms, texstate, data);
245
case QUNIFORM_TEXTURE_CONFIG_P2:
246
write_texture_p2(job, &uniforms, texstate, data);
249
case QUNIFORM_TEXTURE_FIRST_LEVEL:
250
write_texture_first_level(job, &uniforms, texstate,
254
case QUNIFORM_UBO0_ADDR:
255
/* Constant buffer 0 may be a system memory pointer,
256
* in which case we want to upload a shadow copy to
259
if (!cb->cb[0].buffer) {
260
u_upload_data(vc4->uploader, 0,
261
cb->cb[0].buffer_size, 16,
262
cb->cb[0].user_buffer,
263
&cb->cb[0].buffer_offset,
267
cl_aligned_reloc(job, &job->uniforms,
269
vc4_resource(cb->cb[0].buffer)->bo,
270
cb->cb[0].buffer_offset +
274
case QUNIFORM_UBO1_ADDR: {
275
struct vc4_resource *rsc =
276
vc4_resource(cb->cb[1].buffer);
278
cl_aligned_reloc(job, &job->uniforms,
280
rsc->bo, cb->cb[1].buffer_offset);
284
case QUNIFORM_TEXTURE_MSAA_ADDR:
285
write_texture_msaa_addr(job, &uniforms, texstate, data);
288
case QUNIFORM_TEXTURE_BORDER_COLOR:
289
write_texture_border_color(job, &uniforms,
293
case QUNIFORM_TEXRECT_SCALE_X:
294
case QUNIFORM_TEXRECT_SCALE_Y:
295
cl_aligned_u32(&uniforms,
296
get_texrect_scale(texstate,
301
case QUNIFORM_BLEND_CONST_COLOR_X:
302
case QUNIFORM_BLEND_CONST_COLOR_Y:
303
case QUNIFORM_BLEND_CONST_COLOR_Z:
304
case QUNIFORM_BLEND_CONST_COLOR_W:
305
cl_aligned_f(&uniforms,
306
CLAMP(vc4->blend_color.f.color[uinfo->contents[i] -
307
QUNIFORM_BLEND_CONST_COLOR_X],
311
case QUNIFORM_BLEND_CONST_COLOR_RGBA: {
312
const uint8_t *format_swiz =
313
vc4_get_format_swizzle(vc4->framebuffer.cbufs[0]->format);
315
for (int i = 0; i < 4; i++) {
316
if (format_swiz[i] >= 4)
319
color |= (vc4->blend_color.ub[format_swiz[i]] <<
322
cl_aligned_u32(&uniforms, color);
326
case QUNIFORM_BLEND_CONST_COLOR_AAAA: {
327
uint8_t a = vc4->blend_color.ub[3];
328
cl_aligned_u32(&uniforms, ((a) |
335
case QUNIFORM_STENCIL:
336
cl_aligned_u32(&uniforms,
337
vc4->zsa->stencil_uniforms[data] |
339
(vc4->stencil_ref.ref_value[data] << 8) :
343
case QUNIFORM_SAMPLE_MASK:
344
cl_aligned_u32(&uniforms, vc4->sample_mask);
347
case QUNIFORM_UNIFORMS_ADDRESS:
348
/* This will be filled in by the kernel. */
349
cl_aligned_u32(&uniforms, 0xd0d0d0d0);
354
uint32_t written_val = *((uint32_t *)uniforms - 1);
355
char *desc = qir_describe_uniform(uinfo->contents[i],
359
fprintf(stderr, "%p/%d: 0x%08x %s\n",
360
shader, i, written_val, desc);
366
cl_end(&job->uniforms, uniforms);
370
vc4_set_shader_uniform_dirty_flags(struct vc4_compiled_shader *shader)
374
for (int i = 0; i < shader->uniforms.count; i++) {
375
switch (shader->uniforms.contents[i]) {
376
case QUNIFORM_CONSTANT:
377
case QUNIFORM_UNIFORMS_ADDRESS:
379
case QUNIFORM_UNIFORM:
380
case QUNIFORM_UBO0_ADDR:
381
case QUNIFORM_UBO1_ADDR:
382
dirty |= VC4_DIRTY_CONSTBUF;
385
case QUNIFORM_VIEWPORT_X_SCALE:
386
case QUNIFORM_VIEWPORT_Y_SCALE:
387
case QUNIFORM_VIEWPORT_Z_OFFSET:
388
case QUNIFORM_VIEWPORT_Z_SCALE:
389
dirty |= VC4_DIRTY_VIEWPORT;
392
case QUNIFORM_USER_CLIP_PLANE:
393
dirty |= VC4_DIRTY_CLIP;
396
case QUNIFORM_TEXTURE_CONFIG_P0:
397
case QUNIFORM_TEXTURE_CONFIG_P1:
398
case QUNIFORM_TEXTURE_CONFIG_P2:
399
case QUNIFORM_TEXTURE_BORDER_COLOR:
400
case QUNIFORM_TEXTURE_FIRST_LEVEL:
401
case QUNIFORM_TEXTURE_MSAA_ADDR:
402
case QUNIFORM_TEXRECT_SCALE_X:
403
case QUNIFORM_TEXRECT_SCALE_Y:
404
/* We could flag this on just the stage we're
405
* compiling for, but it's not passed in.
407
dirty |= VC4_DIRTY_FRAGTEX | VC4_DIRTY_VERTTEX;
410
case QUNIFORM_BLEND_CONST_COLOR_X:
411
case QUNIFORM_BLEND_CONST_COLOR_Y:
412
case QUNIFORM_BLEND_CONST_COLOR_Z:
413
case QUNIFORM_BLEND_CONST_COLOR_W:
414
case QUNIFORM_BLEND_CONST_COLOR_RGBA:
415
case QUNIFORM_BLEND_CONST_COLOR_AAAA:
416
dirty |= VC4_DIRTY_BLEND_COLOR;
419
case QUNIFORM_STENCIL:
420
dirty |= VC4_DIRTY_ZSA;
423
case QUNIFORM_SAMPLE_MASK:
424
dirty |= VC4_DIRTY_SAMPLE_MASK;
429
shader->uniform_dirty_bits = dirty;