freedreno/a4xx: texture fixes
Signed-off-by: Rob Clark <robclark@freedesktop.org>
This commit is contained in:
@@ -162,12 +162,20 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
unsigned i;
|
||||
|
||||
if (tex->num_samplers > 0) {
|
||||
int num_samplers;
|
||||
|
||||
/* not sure if this is an a420.0 workaround, but we seem
|
||||
* to need to emit these in pairs.. emit a final dummy
|
||||
* entry if odd # of samplers:
|
||||
*/
|
||||
num_samplers = align(tex->num_samplers, 2);
|
||||
|
||||
/* output sampler state: */
|
||||
OUT_PKT3(ring, CP_LOAD_STATE, 2 + 2 + (2 * tex->num_samplers));
|
||||
OUT_PKT3(ring, CP_LOAD_STATE, 2 + (2 * num_samplers));
|
||||
OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(0) |
|
||||
CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) |
|
||||
CP_LOAD_STATE_0_STATE_BLOCK(sb) |
|
||||
CP_LOAD_STATE_0_NUM_UNIT(tex->num_samplers));
|
||||
CP_LOAD_STATE_0_NUM_UNIT(num_samplers));
|
||||
OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_SHADER) |
|
||||
CP_LOAD_STATE_1_EXT_SRC_ADDR(0));
|
||||
for (i = 0; i < tex->num_samplers; i++) {
|
||||
@@ -178,9 +186,11 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
OUT_RING(ring, sampler->texsamp0);
|
||||
OUT_RING(ring, sampler->texsamp1);
|
||||
}
|
||||
/* maybe an a420.0 (or a4xx.0) workaround?? or just driver bug? */
|
||||
OUT_RING(ring, 0x00000000);
|
||||
OUT_RING(ring, 0x00000000);
|
||||
|
||||
for (; i < num_samplers; i++) {
|
||||
OUT_RING(ring, 0x00000000);
|
||||
OUT_RING(ring, 0x00000000);
|
||||
}
|
||||
}
|
||||
|
||||
if (tex->num_textures > 0) {
|
||||
@@ -203,7 +213,8 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
OUT_RING(ring, view->texconst1);
|
||||
OUT_RING(ring, view->texconst2);
|
||||
OUT_RING(ring, view->texconst3);
|
||||
OUT_RELOC(ring, rsc->bo, slice->offset, 0, 0);
|
||||
OUT_RELOC(ring, rsc->bo, slice->offset,
|
||||
view->textconst4, 0);
|
||||
OUT_RING(ring, 0x00000000);
|
||||
OUT_RING(ring, 0x00000000);
|
||||
OUT_RING(ring, 0x00000000);
|
||||
|
||||
@@ -232,6 +232,23 @@ fd4_pipe2swap(enum pipe_format format)
|
||||
return formats[format].swap;
|
||||
}
|
||||
|
||||
enum a4xx_tex_fetchsize
|
||||
fd4_pipe2fetchsize(enum pipe_format format)
|
||||
{
|
||||
switch (util_format_get_blocksizebits(format)) {
|
||||
case 8: return TFETCH4_1_BYTE;
|
||||
case 16: return TFETCH4_2_BYTE;
|
||||
case 32: return TFETCH4_4_BYTE;
|
||||
case 64: return TFETCH4_8_BYTE;
|
||||
case 128: return TFETCH4_16_BYTE;
|
||||
default:
|
||||
debug_printf("Unknown block size for format %s: %d\n",
|
||||
util_format_name(format),
|
||||
util_format_get_blocksizebits(format));
|
||||
return TFETCH4_1_BYTE;
|
||||
}
|
||||
}
|
||||
|
||||
/* we need to special case a bit the depth/stencil restore, because we are
|
||||
* using the texture sampler to blit into the depth/stencil buffer, *not*
|
||||
* into a color buffer. Otherwise fd4_tex_swiz() will do the wrong thing,
|
||||
|
||||
@@ -38,6 +38,7 @@ enum a4xx_tex_fmt fd4_pipe2tex(enum pipe_format format);
|
||||
enum a4xx_color_fmt fd4_pipe2color(enum pipe_format format);
|
||||
enum pipe_format fd4_gmem_restore_format(enum pipe_format format);
|
||||
enum a3xx_color_swap fd4_pipe2swap(enum pipe_format format);
|
||||
enum a4xx_tex_fetchsize fd4_pipe2fetchsize(enum pipe_format format);
|
||||
enum a4xx_depth_format fd4_pipe2depth(enum pipe_format format);
|
||||
|
||||
uint32_t fd4_tex_swiz(enum pipe_format format, unsigned swizzle_r,
|
||||
|
||||
@@ -165,13 +165,25 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
|
||||
A4XX_TEX_CONST_1_WIDTH(prsc->width0) |
|
||||
A4XX_TEX_CONST_1_HEIGHT(prsc->height0);
|
||||
so->texconst2 =
|
||||
A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) |
|
||||
A4XX_TEX_CONST_2_PITCH(rsc->slices[lvl].pitch * rsc->cpp);
|
||||
|
||||
switch (prsc->target) {
|
||||
case PIPE_TEXTURE_1D_ARRAY:
|
||||
case PIPE_TEXTURE_2D_ARRAY:
|
||||
so->texconst3 =
|
||||
A4XX_TEX_CONST_3_DEPTH(prsc->array_size) |
|
||||
A4XX_TEX_CONST_3_LAYERSZ(rsc->slices[0].size0);
|
||||
break;
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
case PIPE_TEXTURE_CUBE_ARRAY: /* ?? not sure about _CUBE_ARRAY */
|
||||
so->texconst3 =
|
||||
A4XX_TEX_CONST_3_DEPTH(1) |
|
||||
A4XX_TEX_CONST_3_LAYERSZ(rsc->slices[0].size0);
|
||||
break;
|
||||
case PIPE_TEXTURE_3D:
|
||||
so->texconst3 =
|
||||
A4XX_TEX_CONST_3_DEPTH(u_minify(prsc->depth0, lvl)) |
|
||||
A4XX_TEX_CONST_3_LAYERSZ(rsc->slices[0].size0);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -51,7 +51,7 @@ fd4_sampler_stateobj(struct pipe_sampler_state *samp)
|
||||
struct fd4_pipe_sampler_view {
|
||||
struct pipe_sampler_view base;
|
||||
struct fd_resource *tex_resource;
|
||||
uint32_t texconst0, texconst1, texconst2, texconst3;
|
||||
uint32_t texconst0, texconst1, texconst2, texconst3, textconst4;
|
||||
};
|
||||
|
||||
static INLINE struct fd4_pipe_sampler_view *
|
||||
|
||||
@@ -216,6 +216,12 @@ setup_slices(struct fd_resource *rsc, uint32_t alignment)
|
||||
static uint32_t
|
||||
slice_alignment(struct pipe_screen *pscreen, const struct pipe_resource *tmpl)
|
||||
{
|
||||
struct fd_screen *screen = fd_screen(pscreen);
|
||||
|
||||
/* on a4xx, seems like everything is aligned to page: */
|
||||
if ((screen->gpu_id >= 400) && (screen->gpu_id < 500))
|
||||
return 4096;
|
||||
|
||||
/* on a3xx, 2d array and 3d textures seem to want their
|
||||
* layers aligned to page boundaries:
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user