freedreno: helper for a3xx/a4xx border-colors
Both use the same layout for the buffer containing border-color values, so rather than duplicating the logic in a4xx, split it out into a helper. Signed-off-by: Rob Clark <robclark@freedesktop.org>
This commit is contained in:
parent
76977222af
commit
9124a49d54
|
@ -73,22 +73,6 @@ struct fd3_context {
|
||||||
*/
|
*/
|
||||||
struct fd_vertex_state blit_vbuf_state;
|
struct fd_vertex_state blit_vbuf_state;
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Border color layout *appears* to be as arrays of 0x40 byte
|
|
||||||
* elements, with frag shader elements starting at (16 x 0x40).
|
|
||||||
* But at some point I should probably experiment more with
|
|
||||||
* samplers in vertex shaders to be sure. Unclear about why
|
|
||||||
* there is this offset when there are separate VS and FS base
|
|
||||||
* addr regs.
|
|
||||||
*
|
|
||||||
* The first 8 bytes of each entry are the requested border
|
|
||||||
* color in fp16. Unclear about the rest.. could be used for
|
|
||||||
* other formats, or could simply be for aligning the pitch
|
|
||||||
* to 32 pixels.
|
|
||||||
*/
|
|
||||||
#define BORDERCOLOR_SIZE 0x40
|
|
||||||
|
|
||||||
struct u_upload_mgr *border_color_uploader;
|
struct u_upload_mgr *border_color_uploader;
|
||||||
struct pipe_resource *border_color_buf;
|
struct pipe_resource *border_color_buf;
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,8 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||||
&fd3_ctx->border_color_buf,
|
&fd3_ctx->border_color_buf,
|
||||||
&ptr);
|
&ptr);
|
||||||
|
|
||||||
|
fd_setup_border_colors(tex, ptr, tex_off[sb]);
|
||||||
|
|
||||||
if (tex->num_samplers > 0) {
|
if (tex->num_samplers > 0) {
|
||||||
/* output sampler state: */
|
/* output sampler state: */
|
||||||
OUT_PKT3(ring, CP_LOAD_STATE, 2 + (2 * tex->num_samplers));
|
OUT_PKT3(ring, CP_LOAD_STATE, 2 + (2 * tex->num_samplers));
|
||||||
|
@ -163,57 +165,6 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||||
const struct fd3_sampler_stateobj *sampler = tex->samplers[i] ?
|
const struct fd3_sampler_stateobj *sampler = tex->samplers[i] ?
|
||||||
fd3_sampler_stateobj(tex->samplers[i]) :
|
fd3_sampler_stateobj(tex->samplers[i]) :
|
||||||
&dummy_sampler;
|
&dummy_sampler;
|
||||||
uint16_t *bcolor = (uint16_t *)((uint8_t *)ptr +
|
|
||||||
(BORDERCOLOR_SIZE * tex_off[sb]) +
|
|
||||||
(BORDERCOLOR_SIZE * i));
|
|
||||||
uint32_t *bcolor32 = (uint32_t *)&bcolor[16];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX HACK ALERT XXX
|
|
||||||
*
|
|
||||||
* The border colors need to be swizzled in a particular
|
|
||||||
* format-dependent order. Even though samplers don't know about
|
|
||||||
* formats, we can assume that with a GL state tracker, there's a
|
|
||||||
* 1:1 correspondence between sampler and texture. Take advantage
|
|
||||||
* of that knowledge.
|
|
||||||
*/
|
|
||||||
if (i < tex->num_textures && tex->textures[i]) {
|
|
||||||
const struct util_format_description *desc =
|
|
||||||
util_format_description(tex->textures[i]->format);
|
|
||||||
for (j = 0; j < 4; j++) {
|
|
||||||
if (desc->swizzle[j] >= 4)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const struct util_format_channel_description *chan =
|
|
||||||
&desc->channel[desc->swizzle[j]];
|
|
||||||
int size = chan->size;
|
|
||||||
|
|
||||||
/* The Z16 texture format we use seems to look in the
|
|
||||||
* 32-bit border color slots
|
|
||||||
*/
|
|
||||||
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
|
|
||||||
size = 32;
|
|
||||||
|
|
||||||
/* Formats like R11G11B10 or RGB9_E5 don't specify
|
|
||||||
* per-channel sizes properly.
|
|
||||||
*/
|
|
||||||
if (desc->layout == UTIL_FORMAT_LAYOUT_OTHER)
|
|
||||||
size = 16;
|
|
||||||
|
|
||||||
if (chan->pure_integer && size > 16)
|
|
||||||
bcolor32[desc->swizzle[j] + 4] =
|
|
||||||
sampler->base.border_color.i[j];
|
|
||||||
else if (size > 16)
|
|
||||||
bcolor32[desc->swizzle[j]] =
|
|
||||||
fui(sampler->base.border_color.f[j]);
|
|
||||||
else if (chan->pure_integer)
|
|
||||||
bcolor[desc->swizzle[j] + 8] =
|
|
||||||
sampler->base.border_color.i[j];
|
|
||||||
else
|
|
||||||
bcolor[desc->swizzle[j]] =
|
|
||||||
util_float_to_half(sampler->base.border_color.f[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OUT_RING(ring, sampler->texsamp0);
|
OUT_RING(ring, sampler->texsamp0);
|
||||||
OUT_RING(ring, sampler->texsamp1);
|
OUT_RING(ring, sampler->texsamp1);
|
||||||
|
|
|
@ -162,3 +162,69 @@ fd_texture_init(struct pipe_context *pctx)
|
||||||
|
|
||||||
pctx->sampler_view_destroy = fd_sampler_view_destroy;
|
pctx->sampler_view_destroy = fd_sampler_view_destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* helper for setting up border-color buffer for a3xx/a4xx: */
|
||||||
|
void
|
||||||
|
fd_setup_border_colors(struct fd_texture_stateobj *tex, void *ptr,
|
||||||
|
unsigned offset)
|
||||||
|
{
|
||||||
|
unsigned i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < tex->num_samplers; i++) {
|
||||||
|
struct pipe_sampler_state *sampler = tex->samplers[i];
|
||||||
|
uint16_t *bcolor = (uint16_t *)((uint8_t *)ptr +
|
||||||
|
(BORDERCOLOR_SIZE * offset) +
|
||||||
|
(BORDERCOLOR_SIZE * i));
|
||||||
|
uint32_t *bcolor32 = (uint32_t *)&bcolor[16];
|
||||||
|
|
||||||
|
if (!sampler)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX HACK ALERT XXX
|
||||||
|
*
|
||||||
|
* The border colors need to be swizzled in a particular
|
||||||
|
* format-dependent order. Even though samplers don't know about
|
||||||
|
* formats, we can assume that with a GL state tracker, there's a
|
||||||
|
* 1:1 correspondence between sampler and texture. Take advantage
|
||||||
|
* of that knowledge.
|
||||||
|
*/
|
||||||
|
if (i < tex->num_textures && tex->textures[i]) {
|
||||||
|
const struct util_format_description *desc =
|
||||||
|
util_format_description(tex->textures[i]->format);
|
||||||
|
for (j = 0; j < 4; j++) {
|
||||||
|
if (desc->swizzle[j] >= 4)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const struct util_format_channel_description *chan =
|
||||||
|
&desc->channel[desc->swizzle[j]];
|
||||||
|
int size = chan->size;
|
||||||
|
|
||||||
|
/* The Z16 texture format we use seems to look in the
|
||||||
|
* 32-bit border color slots
|
||||||
|
*/
|
||||||
|
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
|
||||||
|
size = 32;
|
||||||
|
|
||||||
|
/* Formats like R11G11B10 or RGB9_E5 don't specify
|
||||||
|
* per-channel sizes properly.
|
||||||
|
*/
|
||||||
|
if (desc->layout == UTIL_FORMAT_LAYOUT_OTHER)
|
||||||
|
size = 16;
|
||||||
|
|
||||||
|
if (chan->pure_integer && size > 16)
|
||||||
|
bcolor32[desc->swizzle[j] + 4] =
|
||||||
|
sampler->border_color.i[j];
|
||||||
|
else if (size > 16)
|
||||||
|
bcolor32[desc->swizzle[j]] =
|
||||||
|
fui(sampler->border_color.f[j]);
|
||||||
|
else if (chan->pure_integer)
|
||||||
|
bcolor[desc->swizzle[j] + 8] =
|
||||||
|
sampler->border_color.i[j];
|
||||||
|
else
|
||||||
|
bcolor[desc->swizzle[j]] =
|
||||||
|
util_float_to_half(sampler->border_color.f[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -41,4 +41,35 @@ void fd_set_sampler_views(struct pipe_context *pctx, unsigned shader,
|
||||||
|
|
||||||
void fd_texture_init(struct pipe_context *pctx);
|
void fd_texture_init(struct pipe_context *pctx);
|
||||||
|
|
||||||
|
struct fd_texture_stateobj;
|
||||||
|
|
||||||
|
/* Both a3xx/a4xx share the same layout for the border-color buffer,
|
||||||
|
* which contains the pre-swizzled (based on texture format) border
|
||||||
|
* color value, with the following layout (per sampler):
|
||||||
|
*
|
||||||
|
* offset | description
|
||||||
|
* -------+-------------
|
||||||
|
* 0x00: | fp16[0] \
|
||||||
|
* | fp16[1] |___ swizzled fp16 channel values for "small float"
|
||||||
|
* | fp16[2] | formats (<= 16 bits per component, !integer)
|
||||||
|
* | fp16[3] /
|
||||||
|
* 0x08: | padding
|
||||||
|
* 0x10: | int16[0] \
|
||||||
|
* | int16[1] |___ swizzled int16 channels for for "small integer"
|
||||||
|
* | int16[2] | formats (<= 16 bits per component, integer)
|
||||||
|
* | int16[3] /
|
||||||
|
* 0x18: | padding
|
||||||
|
* 0x20: | fp32[0] \
|
||||||
|
* | fp32[1] |___ swizzled fp32 channel values for "large float"
|
||||||
|
* | fp32[2] | formats (> 16 bits per component, !integer)
|
||||||
|
* | fp32[3] /
|
||||||
|
* 0x30: | int32[0] \
|
||||||
|
* | int32[1] |___ swizzled int32 channel values for "large int"
|
||||||
|
* | int32[2] | formats (> 16 bits per component, integer)
|
||||||
|
* | int32[3] /
|
||||||
|
*/
|
||||||
|
#define BORDERCOLOR_SIZE 0x40
|
||||||
|
void fd_setup_border_colors(struct fd_texture_stateobj *tex, void *ptr,
|
||||||
|
unsigned offset);
|
||||||
|
|
||||||
#endif /* FREEDRENO_TEXTURE_H_ */
|
#endif /* FREEDRENO_TEXTURE_H_ */
|
||||||
|
|
Loading…
Reference in New Issue