<bitfield name="SWIZ_Y" low="4" high="6" type="sq_tex_swiz"/>
<bitfield name="SWIZ_Z" low="7" high="9" type="sq_tex_swiz"/>
<bitfield name="SWIZ_W" low="10" high="12" type="sq_tex_swiz"/>
- <bitfield name="EXP_ADJUST" low="13" high="18" type="uint"/>
+ <bitfield name="EXP_ADJUST" low="13" high="18" type="int"/>
<bitfield name="XY_MAG_FILTER" low="19" high="20" type="sq_tex_filter"/>
<bitfield name="XY_MIN_FILTER" low="21" high="22" type="sq_tex_filter"/>
<bitfield name="MIP_FILTER" low="23" high="24" type="sq_tex_filter"/>
case PIPE_FORMAT_B5G5R5X1_UNORM:
case PIPE_FORMAT_B4G4R4A4_UNORM:
case PIPE_FORMAT_B4G4R4X4_UNORM:
+ case PIPE_FORMAT_B2G3R3_UNORM:
return 1;
default:
return 0;
A2XX_SQ_TEX_0_CLAMP_Z(SQ_TEX_WRAP) |
A2XX_SQ_TEX_0_PITCH(slice->pitch));
OUT_RELOC(ring, rsc->bo, offset,
- fd2_pipe2surface(format) |
+ A2XX_SQ_TEX_1_FORMAT(fd2_pipe2surface(format).format) |
A2XX_SQ_TEX_1_CLAMP_POLICY(SQ_TEX_CLAMP_POLICY_OGL), 0);
OUT_RING(ring, A2XX_SQ_TEX_2_WIDTH(psurf->width - 1) |
A2XX_SQ_TEX_2_HEIGHT(psurf->height - 1));
patch_vtx_fetch(struct fd_context *ctx, struct pipe_vertex_element *elem,
instr_fetch_vtx_t *instr, uint16_t dst_swiz)
{
- struct pipe_vertex_buffer *vb =
- &ctx->vtx.vertexbuf.vb[elem->vertex_buffer_index];
- enum pipe_format format = elem->src_format;
- const struct util_format_description *desc =
- util_format_description(format);
- unsigned j;
-
- /* Find the first non-VOID channel. */
- for (j = 0; j < 4; j++)
- if (desc->channel[j].type != UTIL_FORMAT_TYPE_VOID)
- break;
-
- instr->format = fd2_pipe2surface(format);
- instr->num_format_all = !desc->channel[j].normalized;
- instr->format_comp_all = desc->channel[j].type == UTIL_FORMAT_TYPE_SIGNED;
- instr->stride = vb->stride;
+ struct surface_format fmt = fd2_pipe2surface(elem->src_format);
+
+ instr->dst_swiz = fd2_vtx_swiz(elem->src_format, dst_swiz);
+ instr->format_comp_all = fmt.sign == SQ_TEX_SIGN_SIGNED;
+ instr->num_format_all = fmt.num_format;
+ instr->format = fmt.format;
+ instr->exp_adjust_all = fmt.exp_adjust;
+ instr->stride = ctx->vtx.vertexbuf.vb[elem->vertex_buffer_index].stride;
instr->offset = elem->src_offset;
-
- unsigned swiz = 0;
- for (int i = 0; i < 4; i++) {
- unsigned s = dst_swiz >> i*3 & 7;
- swiz |= (s >= 4 ? s : desc->swizzle[s]) << i*3;
- }
- instr->dst_swiz = swiz;
}
static void
}
if ((usage & (PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_VERTEX_BUFFER)) &&
- !util_format_is_srgb(format)) {
- enum a2xx_sq_surfaceformat fmt = fd2_pipe2surface(format);
- unsigned block_size = util_format_get_blocksize(format);
- if (fmt != ~0)
- retval |= usage & PIPE_BIND_VERTEX_BUFFER;
- if (fmt != ~0 && block_size != 3 && block_size != 6 &&
- (block_size != 12 || format == PIPE_FORMAT_R32G32B32_FLOAT))
+ !util_format_is_srgb(format) &&
+ !util_format_is_pure_integer(format) &&
+ fd2_pipe2surface(format).format != FMT_INVALID) {
+ retval |= usage & PIPE_BIND_VERTEX_BUFFER;
+ /* the only npot blocksize supported texture format is R32G32B32_FLOAT */
+ if (util_is_power_of_two_or_zero(util_format_get_blocksize(format)) ||
+ format == PIPE_FORMAT_R32G32B32_FLOAT)
retval |= usage & PIPE_BIND_SAMPLER_VIEW;
}
{
struct fd2_pipe_sampler_view *so = CALLOC_STRUCT(fd2_pipe_sampler_view);
struct fd_resource *rsc = fd_resource(prsc);
+ struct surface_format fmt = fd2_pipe2surface(cso->format);
if (!so)
return NULL;
so->base.reference.count = 1;
so->base.context = pctx;
- enum sq_tex_sign sign = SQ_TEX_SIGN_UNSIGNED;
- if (util_format_is_snorm(cso->format))
- sign = SQ_TEX_SIGN_SIGNED;
- /* note: SQ_TEX_SIGN_GAMMA same as SQ_TEX_SIGN_UNSIGNED (a200) */
-
so->tex0 =
- A2XX_SQ_TEX_0_SIGN_X(sign) |
- A2XX_SQ_TEX_0_SIGN_Y(sign) |
- A2XX_SQ_TEX_0_SIGN_Z(sign) |
- A2XX_SQ_TEX_0_SIGN_W(sign) |
+ A2XX_SQ_TEX_0_SIGN_X(fmt.sign) |
+ A2XX_SQ_TEX_0_SIGN_Y(fmt.sign) |
+ A2XX_SQ_TEX_0_SIGN_Z(fmt.sign) |
+ A2XX_SQ_TEX_0_SIGN_W(fmt.sign) |
A2XX_SQ_TEX_0_PITCH(rsc->slices[0].pitch) |
COND(rsc->tile_mode, A2XX_SQ_TEX_0_TILED);
so->tex1 =
- A2XX_SQ_TEX_1_FORMAT(fd2_pipe2surface(cso->format)) |
+ A2XX_SQ_TEX_1_FORMAT(fmt.format) |
A2XX_SQ_TEX_1_CLAMP_POLICY(SQ_TEX_CLAMP_POLICY_OGL);
so->tex2 =
A2XX_SQ_TEX_2_HEIGHT(prsc->height0 - 1) |
A2XX_SQ_TEX_2_WIDTH(prsc->width0 - 1);
- so->tex3 = fd2_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
- cso->swizzle_b, cso->swizzle_a);
+ so->tex3 =
+ A2XX_SQ_TEX_3_NUM_FORMAT(fmt.num_format) |
+ fd2_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
+ cso->swizzle_b, cso->swizzle_a) |
+ A2XX_SQ_TEX_3_EXP_ADJUST(fmt.exp_adjust);
so->tex4 =
A2XX_SQ_TEX_4_MIP_MIN_LEVEL(fd_sampler_first_level(cso)) |
#include "fd2_util.h"
-enum a2xx_sq_surfaceformat
-fd2_pipe2surface(enum pipe_format format)
+static enum a2xx_sq_surfaceformat
+pipe2surface(enum pipe_format format, struct surface_format *fmt)
{
const struct util_format_description *desc = util_format_description(format);
for (unsigned i = 0; i < 4; i++)
channel_size |= desc->channel[i].size << i*8;
+ unsigned i = util_format_get_first_non_void_channel(format);
+ if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED ||
+ desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED)
+ fmt->sign = SQ_TEX_SIGN_SIGNED;
+ if (!desc->channel[i].normalized)
+ fmt->num_format = SQ_TEX_NUM_FORMAT_INT;
+ if (desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED)
+ fmt->exp_adjust = -16;
+
/* Note: the 3 channel 24bpp/48bpp/96bpp formats are only for vertex fetch
* we can use the 4 channel format and ignore the 4th component just isn't used
* XXX: is it possible for the extra loaded component to cause a MMU fault?
CASE(32, 32, 32, 0): return FMT_32_32_32_FLOAT;
CASE(32, 32, 32, 32): return FMT_32_32_32_32_FLOAT;
}
- } else if (desc->is_unorm || desc->is_snorm) {
+ } else {
switch (channel_size) {
CASE( 8, 0, 0, 0): return FMT_8;
CASE( 8, 8, 0, 0): return FMT_8_8;
CASE( 5, 6, 5, 0): return FMT_5_6_5;
CASE(10, 10, 10, 2): return FMT_2_10_10_10;
CASE( 8, 24, 0, 0): return FMT_24_8;
+ CASE( 2, 3, 3, 0): return FMT_2_3_3; /* Note: R/B swapped */
}
}
#undef CASE
return ~0;
}
+struct surface_format
+fd2_pipe2surface(enum pipe_format format)
+{
+ struct surface_format fmt = {
+ .sign = SQ_TEX_SIGN_UNSIGNED,
+ .num_format = SQ_TEX_NUM_FORMAT_FRAC,
+ .exp_adjust = 0,
+ };
+ fmt.format = pipe2surface(format, &fmt);
+ return fmt;
+}
+
enum a2xx_colorformatx
fd2_pipe2color(enum pipe_format format)
{
/* 8-bit buffers. */
case PIPE_FORMAT_R8_UNORM:
return COLORX_8;
+ case PIPE_FORMAT_B2G3R3_UNORM:
+ return COLORX_2_3_3; /* note: untested */
/* 16-bit buffers. */
case PIPE_FORMAT_B5G6R5_UNORM:
A2XX_SQ_TEX_3_SWIZ_Z(tex_swiz(rswiz[2])) |
A2XX_SQ_TEX_3_SWIZ_W(tex_swiz(rswiz[3]));
}
+
+uint32_t
+fd2_vtx_swiz(enum pipe_format format, unsigned swizzle)
+{
+ const struct util_format_description *desc =
+ util_format_description(format);
+ unsigned char swiz[4], rswiz[4];
+
+ for (unsigned i = 0; i < 4; i++)
+ swiz[i] = (swizzle >> i * 3) & 7;
+
+ util_format_compose_swizzles(desc->swizzle, swiz, rswiz);
+
+ return rswiz[0] | rswiz[1] << 3 | rswiz[2] << 6 | rswiz[3] << 9;
+}
#include "a2xx.xml.h"
-enum a2xx_sq_surfaceformat fd2_pipe2surface(enum pipe_format format);
+struct surface_format {
+#define FMT_INVALID 0x7f
+ enum a2xx_sq_surfaceformat format : 7;
+ enum sq_tex_sign sign : 2;
+ enum sq_tex_num_format num_format : 1;
+ int exp_adjust : 6;
+};
+
+struct surface_format fd2_pipe2surface(enum pipe_format format);
enum a2xx_colorformatx fd2_pipe2color(enum pipe_format format);
uint32_t fd2_tex_swiz(enum pipe_format format, unsigned swizzle_r,
unsigned swizzle_g, unsigned swizzle_b, unsigned swizzle_a);
+uint32_t fd2_vtx_swiz(enum pipe_format format, unsigned swizzle);
/* convert x,y to dword */
static inline uint32_t xy2d(uint16_t x, uint16_t y)
uint8_t signed_rf_mode_all : 1;
uint8_t reserved1 : 1;
instr_surf_fmt_t format : 6;
- uint8_t reserved2 : 1;
- uint8_t exp_adjust_all : 7;
+ uint8_t reserved2 : 2;
+ uint8_t exp_adjust_all : 6;
uint8_t reserved3 : 1;
uint8_t pred_select : 1;
/* dword2: */