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_ALPHA_REF
:
344 cl_aligned_f(&uniforms
,
345 vc4
->zsa
->base
.alpha
.ref_value
);
348 case QUNIFORM_SAMPLE_MASK
:
349 cl_aligned_u32(&uniforms
, vc4
->sample_mask
);
352 case QUNIFORM_UNIFORMS_ADDRESS
:
353 /* This will be filled in by the kernel. */
354 cl_aligned_u32(&uniforms
, 0xd0d0d0d0);
359 uint32_t written_val
= *((uint32_t *)uniforms
- 1);
360 char *desc
= qir_describe_uniform(uinfo
->contents
[i
],
364 fprintf(stderr
, "%p/%d: 0x%08x %s\n",
365 shader
, i
, written_val
, desc
);
371 cl_end(&job
->uniforms
, uniforms
);
375 vc4_set_shader_uniform_dirty_flags(struct vc4_compiled_shader
*shader
)
379 for (int i
= 0; i
< shader
->uniforms
.count
; i
++) {
380 switch (shader
->uniforms
.contents
[i
]) {
381 case QUNIFORM_CONSTANT
:
382 case QUNIFORM_UNIFORMS_ADDRESS
:
384 case QUNIFORM_UNIFORM
:
385 case QUNIFORM_UBO0_ADDR
:
386 case QUNIFORM_UBO1_ADDR
:
387 dirty
|= VC4_DIRTY_CONSTBUF
;
390 case QUNIFORM_VIEWPORT_X_SCALE
:
391 case QUNIFORM_VIEWPORT_Y_SCALE
:
392 case QUNIFORM_VIEWPORT_Z_OFFSET
:
393 case QUNIFORM_VIEWPORT_Z_SCALE
:
394 dirty
|= VC4_DIRTY_VIEWPORT
;
397 case QUNIFORM_USER_CLIP_PLANE
:
398 dirty
|= VC4_DIRTY_CLIP
;
401 case QUNIFORM_TEXTURE_CONFIG_P0
:
402 case QUNIFORM_TEXTURE_CONFIG_P1
:
403 case QUNIFORM_TEXTURE_CONFIG_P2
:
404 case QUNIFORM_TEXTURE_BORDER_COLOR
:
405 case QUNIFORM_TEXTURE_FIRST_LEVEL
:
406 case QUNIFORM_TEXTURE_MSAA_ADDR
:
407 case QUNIFORM_TEXRECT_SCALE_X
:
408 case QUNIFORM_TEXRECT_SCALE_Y
:
409 /* We could flag this on just the stage we're
410 * compiling for, but it's not passed in.
412 dirty
|= VC4_DIRTY_FRAGTEX
| VC4_DIRTY_VERTTEX
;
415 case QUNIFORM_BLEND_CONST_COLOR_X
:
416 case QUNIFORM_BLEND_CONST_COLOR_Y
:
417 case QUNIFORM_BLEND_CONST_COLOR_Z
:
418 case QUNIFORM_BLEND_CONST_COLOR_W
:
419 case QUNIFORM_BLEND_CONST_COLOR_RGBA
:
420 case QUNIFORM_BLEND_CONST_COLOR_AAAA
:
421 dirty
|= VC4_DIRTY_BLEND_COLOR
;
424 case QUNIFORM_STENCIL
:
425 case QUNIFORM_ALPHA_REF
:
426 dirty
|= VC4_DIRTY_ZSA
;
429 case QUNIFORM_SAMPLE_MASK
:
430 dirty
|= VC4_DIRTY_SAMPLE_MASK
;
435 shader
->uniform_dirty_bits
= dirty
;