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:
Rob Clark 2015-09-15 09:23:21 -04:00
parent 76977222af
commit 9124a49d54
4 changed files with 99 additions and 67 deletions

View File

@ -73,22 +73,6 @@ struct fd3_context {
*/
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 pipe_resource *border_color_buf;

View File

@ -149,6 +149,8 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
&fd3_ctx->border_color_buf,
&ptr);
fd_setup_border_colors(tex, ptr, tex_off[sb]);
if (tex->num_samplers > 0) {
/* output sampler state: */
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] ?
fd3_sampler_stateobj(tex->samplers[i]) :
&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->texsamp1);

View File

@ -162,3 +162,69 @@ fd_texture_init(struct pipe_context *pctx)
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]);
}
}
}
}

View File

@ -41,4 +41,35 @@ void fd_set_sampler_views(struct pipe_context *pctx, unsigned shader,
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_ */