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/format_srgb.h"
27 #include "vc4_context.h"
30 static uint32_t translate_wrap(uint32_t p_wrap
, bool using_nearest
)
33 case PIPE_TEX_WRAP_REPEAT
:
35 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
:
37 case PIPE_TEX_WRAP_MIRROR_REPEAT
:
39 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
:
41 case PIPE_TEX_WRAP_CLAMP
:
42 return (using_nearest
? 1 : 3);
44 fprintf(stderr
, "Unknown wrap mode %d\n", p_wrap
);
45 assert(!"not reached");
51 write_texture_p0(struct vc4_context
*vc4
,
52 struct vc4_cl_out
**uniforms
,
53 struct vc4_texture_stateobj
*texstate
,
56 struct vc4_sampler_view
*sview
=
57 vc4_sampler_view(texstate
->textures
[unit
]);
58 struct vc4_resource
*rsc
= vc4_resource(sview
->base
.texture
);
60 cl_reloc(vc4
, &vc4
->uniforms
, uniforms
, rsc
->bo
, sview
->texture_p0
);
64 write_texture_p1(struct vc4_context
*vc4
,
65 struct vc4_cl_out
**uniforms
,
66 struct vc4_texture_stateobj
*texstate
,
69 struct vc4_sampler_view
*sview
=
70 vc4_sampler_view(texstate
->textures
[unit
]);
71 struct pipe_sampler_state
*sampler
= texstate
->samplers
[unit
];
72 static const uint8_t minfilter_map
[6] = {
73 VC4_TEX_P1_MINFILT_NEAR_MIP_NEAR
,
74 VC4_TEX_P1_MINFILT_LIN_MIP_NEAR
,
75 VC4_TEX_P1_MINFILT_NEAR_MIP_LIN
,
76 VC4_TEX_P1_MINFILT_LIN_MIP_LIN
,
77 VC4_TEX_P1_MINFILT_NEAREST
,
78 VC4_TEX_P1_MINFILT_LINEAR
,
80 static const uint32_t magfilter_map
[] = {
81 [PIPE_TEX_FILTER_NEAREST
] = VC4_TEX_P1_MAGFILT_NEAREST
,
82 [PIPE_TEX_FILTER_LINEAR
] = VC4_TEX_P1_MAGFILT_LINEAR
,
86 (sampler
->mag_img_filter
== PIPE_TEX_MIPFILTER_NEAREST
||
87 sampler
->min_img_filter
== PIPE_TEX_MIPFILTER_NEAREST
);
89 cl_aligned_u32(uniforms
, sview
->texture_p1
|
90 VC4_SET_FIELD(magfilter_map
[sampler
->mag_img_filter
],
92 VC4_SET_FIELD(minfilter_map
[sampler
->min_mip_filter
* 2 +
93 sampler
->min_img_filter
],
95 VC4_SET_FIELD(translate_wrap(sampler
->wrap_s
, either_nearest
),
97 VC4_SET_FIELD(translate_wrap(sampler
->wrap_t
, either_nearest
),
102 write_texture_p2(struct vc4_context
*vc4
,
103 struct vc4_cl_out
**uniforms
,
104 struct vc4_texture_stateobj
*texstate
,
107 uint32_t unit
= data
& 0xffff;
108 struct pipe_sampler_view
*texture
= texstate
->textures
[unit
];
109 struct vc4_resource
*rsc
= vc4_resource(texture
->texture
);
111 cl_aligned_u32(uniforms
,
112 VC4_SET_FIELD(VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE
,
114 VC4_SET_FIELD(rsc
->cube_map_stride
>> 12, VC4_TEX_P2_CMST
) |
115 VC4_SET_FIELD((data
>> 16) & 1, VC4_TEX_P2_BSLOD
));
119 #define SWIZ(x,y,z,w) { \
120 UTIL_FORMAT_SWIZZLE_##x, \
121 UTIL_FORMAT_SWIZZLE_##y, \
122 UTIL_FORMAT_SWIZZLE_##z, \
123 UTIL_FORMAT_SWIZZLE_##w \
127 write_texture_border_color(struct vc4_context
*vc4
,
128 struct vc4_cl_out
**uniforms
,
129 struct vc4_texture_stateobj
*texstate
,
132 struct pipe_sampler_state
*sampler
= texstate
->samplers
[unit
];
133 struct pipe_sampler_view
*texture
= texstate
->textures
[unit
];
134 struct vc4_resource
*rsc
= vc4_resource(texture
->texture
);
137 const struct util_format_description
*tex_format_desc
=
138 util_format_description(texture
->format
);
140 float border_color
[4];
141 for (int i
= 0; i
< 4; i
++)
142 border_color
[i
] = sampler
->border_color
.f
[i
];
143 if (util_format_is_srgb(texture
->format
)) {
144 for (int i
= 0; i
< 3; i
++)
146 util_format_linear_to_srgb_float(border_color
[i
]);
149 /* Turn the border color into the layout of channels that it would
150 * have when stored as texture contents.
152 float storage_color
[4];
153 util_format_unswizzle_4f(storage_color
,
155 tex_format_desc
->swizzle
);
157 /* Now, pack so that when the vc4_format-sampled texture contents are
158 * replaced with our border color, the vc4_get_format_swizzle()
159 * swizzling will get the right channels.
161 if (util_format_is_depth_or_stencil(texture
->format
)) {
162 uc
.ui
[0] = util_pack_z(PIPE_FORMAT_Z24X8_UNORM
,
163 sampler
->border_color
.f
[0]) << 8;
165 switch (rsc
->vc4_format
) {
167 case VC4_TEXTURE_TYPE_RGBA8888
:
168 util_pack_color(storage_color
,
169 PIPE_FORMAT_R8G8B8A8_UNORM
, &uc
);
171 case VC4_TEXTURE_TYPE_RGBA4444
:
172 util_pack_color(storage_color
,
173 PIPE_FORMAT_A8B8G8R8_UNORM
, &uc
);
175 case VC4_TEXTURE_TYPE_RGB565
:
176 util_pack_color(storage_color
,
177 PIPE_FORMAT_B8G8R8A8_UNORM
, &uc
);
179 case VC4_TEXTURE_TYPE_ALPHA
:
180 uc
.ui
[0] = float_to_ubyte(storage_color
[0]) << 24;
182 case VC4_TEXTURE_TYPE_LUMALPHA
:
183 uc
.ui
[0] = ((float_to_ubyte(storage_color
[1]) << 24) |
184 (float_to_ubyte(storage_color
[0]) << 0));
189 cl_aligned_u32(uniforms
, uc
.ui
[0]);
193 get_texrect_scale(struct vc4_texture_stateobj
*texstate
,
194 enum quniform_contents contents
,
197 struct pipe_sampler_view
*texture
= texstate
->textures
[data
];
200 if (contents
== QUNIFORM_TEXRECT_SCALE_X
)
201 dim
= texture
->texture
->width0
;
203 dim
= texture
->texture
->height0
;
205 return fui(1.0f
/ dim
);
208 static struct vc4_bo
*
209 vc4_upload_ubo(struct vc4_context
*vc4
,
210 struct vc4_compiled_shader
*shader
,
211 const uint32_t *gallium_uniforms
)
213 if (!shader
->ubo_size
)
216 struct vc4_bo
*ubo
= vc4_bo_alloc(vc4
->screen
, shader
->ubo_size
, "ubo");
217 uint32_t *data
= vc4_bo_map(ubo
);
218 for (uint32_t i
= 0; i
< shader
->num_ubo_ranges
; i
++) {
219 memcpy(data
+ shader
->ubo_ranges
[i
].dst_offset
,
220 gallium_uniforms
+ shader
->ubo_ranges
[i
].src_offset
,
221 shader
->ubo_ranges
[i
].size
);
228 vc4_write_uniforms(struct vc4_context
*vc4
, struct vc4_compiled_shader
*shader
,
229 struct vc4_constbuf_stateobj
*cb
,
230 struct vc4_texture_stateobj
*texstate
)
232 struct vc4_shader_uniform_info
*uinfo
= &shader
->uniforms
;
233 const uint32_t *gallium_uniforms
= cb
->cb
[0].user_buffer
;
234 struct vc4_bo
*ubo
= vc4_upload_ubo(vc4
, shader
, gallium_uniforms
);
236 cl_ensure_space(&vc4
->uniforms
, (uinfo
->count
+
237 uinfo
->num_texture_samples
) * 4);
239 struct vc4_cl_out
*uniforms
=
240 cl_start_shader_reloc(&vc4
->uniforms
,
241 uinfo
->num_texture_samples
);
243 for (int i
= 0; i
< uinfo
->count
; i
++) {
245 switch (uinfo
->contents
[i
]) {
246 case QUNIFORM_CONSTANT
:
247 cl_aligned_u32(&uniforms
, uinfo
->data
[i
]);
249 case QUNIFORM_UNIFORM
:
250 cl_aligned_u32(&uniforms
,
251 gallium_uniforms
[uinfo
->data
[i
]]);
253 case QUNIFORM_VIEWPORT_X_SCALE
:
254 cl_aligned_f(&uniforms
, vc4
->viewport
.scale
[0] * 16.0f
);
256 case QUNIFORM_VIEWPORT_Y_SCALE
:
257 cl_aligned_f(&uniforms
, vc4
->viewport
.scale
[1] * 16.0f
);
260 case QUNIFORM_VIEWPORT_Z_OFFSET
:
261 cl_aligned_f(&uniforms
, vc4
->viewport
.translate
[2]);
263 case QUNIFORM_VIEWPORT_Z_SCALE
:
264 cl_aligned_f(&uniforms
, vc4
->viewport
.scale
[2]);
267 case QUNIFORM_USER_CLIP_PLANE
:
268 cl_aligned_f(&uniforms
,
269 vc4
->clip
.ucp
[uinfo
->data
[i
] / 4][uinfo
->data
[i
] % 4]);
272 case QUNIFORM_TEXTURE_CONFIG_P0
:
273 write_texture_p0(vc4
, &uniforms
, texstate
,
277 case QUNIFORM_TEXTURE_CONFIG_P1
:
278 write_texture_p1(vc4
, &uniforms
, texstate
,
282 case QUNIFORM_TEXTURE_CONFIG_P2
:
283 write_texture_p2(vc4
, &uniforms
, texstate
,
287 case QUNIFORM_UBO_ADDR
:
288 cl_aligned_reloc(vc4
, &vc4
->uniforms
, &uniforms
, ubo
, 0);
291 case QUNIFORM_TEXTURE_BORDER_COLOR
:
292 write_texture_border_color(vc4
, &uniforms
,
293 texstate
, uinfo
->data
[i
]);
296 case QUNIFORM_TEXRECT_SCALE_X
:
297 case QUNIFORM_TEXRECT_SCALE_Y
:
298 cl_aligned_u32(&uniforms
,
299 get_texrect_scale(texstate
,
304 case QUNIFORM_BLEND_CONST_COLOR
:
305 cl_aligned_f(&uniforms
,
306 CLAMP(vc4
->blend_color
.color
[uinfo
->data
[i
]], 0, 1));
309 case QUNIFORM_STENCIL
:
310 cl_aligned_u32(&uniforms
,
311 vc4
->zsa
->stencil_uniforms
[uinfo
->data
[i
]] |
312 (uinfo
->data
[i
] <= 1 ?
313 (vc4
->stencil_ref
.ref_value
[uinfo
->data
[i
]] << 8) :
317 case QUNIFORM_ALPHA_REF
:
318 cl_aligned_f(&uniforms
,
319 vc4
->zsa
->base
.alpha
.ref_value
);
323 uint32_t written_val
= *((uint32_t *)uniforms
- 1);
324 fprintf(stderr
, "%p: %d / 0x%08x (%f)\n",
325 shader
, i
, written_val
, uif(written_val
));
329 cl_end(&vc4
->uniforms
, uniforms
);