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;
|
||||
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
Loading…
Reference in New Issue