mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-18 09:00:31 +01:00
nvfx: move 2D format selection logic to 2D code
This commit is contained in:
parent
5bd0e0adb1
commit
25ecc9521d
3 changed files with 75 additions and 67 deletions
|
|
@ -725,15 +725,58 @@ ms:
|
|||
nouveau_bo_unmap(dst->bo);
|
||||
}
|
||||
|
||||
static inline int
|
||||
nv04_region_cs2d_format(struct nv04_region* rgn)
|
||||
{
|
||||
switch(rgn->bpps) {
|
||||
case 0:
|
||||
return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
|
||||
case 1:
|
||||
if(rgn->one_bits >= 1)
|
||||
return NV04_CONTEXT_SURFACES_2D_FORMAT_X1R5G5B5_X1R5G5B5;
|
||||
else
|
||||
return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
|
||||
case 2:
|
||||
if(rgn->one_bits >= 8)
|
||||
return NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_X8R8G8B8;
|
||||
else
|
||||
return NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
nv04_region_sifm_format(struct nv04_region* rgn)
|
||||
{
|
||||
switch(rgn->bpps) {
|
||||
case 0:
|
||||
return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_Y8;
|
||||
case 1:
|
||||
if(rgn->one_bits >= 1)
|
||||
return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X1R5G5B5;
|
||||
else
|
||||
return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5;
|
||||
case 2:
|
||||
if(rgn->one_bits >= 8)
|
||||
return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8;
|
||||
else
|
||||
return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
static void
|
||||
nv04_region_copy_swizzle(struct nv04_2d_context *ctx,
|
||||
struct nv04_region* dst,
|
||||
struct nv04_region* src,
|
||||
int w, int h, int cs2d_format, int sifm_format)
|
||||
int w, int h)
|
||||
{
|
||||
struct nouveau_channel *chan = ctx->swzsurf->channel;
|
||||
struct nouveau_grobj *swzsurf = ctx->swzsurf;
|
||||
struct nouveau_grobj *sifm = ctx->sifm;
|
||||
int cs2d_format = nv04_region_cs2d_format(dst);
|
||||
int sifm_format = nv04_region_sifm_format(src);
|
||||
/* Max width & height may not be the same on all HW, but must be POT */
|
||||
unsigned max_shift = 10;
|
||||
unsigned cw = 1 << max_shift;
|
||||
|
|
@ -951,11 +994,12 @@ nv04_region_copy_m2mf(struct nv04_2d_context *ctx, struct nv04_region *dst, stru
|
|||
}
|
||||
|
||||
static inline void
|
||||
nv04_region_copy_blit(struct nv04_2d_context *ctx, struct nv04_region* dst, struct nv04_region* src, int w, int h, int format)
|
||||
nv04_region_copy_blit(struct nv04_2d_context *ctx, struct nv04_region* dst, struct nv04_region* src, int w, int h)
|
||||
{
|
||||
struct nouveau_channel *chan = ctx->surf2d->channel;
|
||||
struct nouveau_grobj *surf2d = ctx->surf2d;
|
||||
struct nouveau_grobj *blit = ctx->blit;
|
||||
int cs2d_format = nv04_region_cs2d_format(dst);
|
||||
|
||||
#ifdef NV04_REGION_DEBUG
|
||||
fprintf(stderr, "\tRGN_COPY_BLIT [%i, %i: %i] ", w, h, dst->bpps);
|
||||
|
|
@ -976,7 +1020,7 @@ nv04_region_copy_blit(struct nv04_2d_context *ctx, struct nv04_region* dst, stru
|
|||
OUT_RELOCo(chan, src->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCo(chan, dst->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
|
||||
OUT_RING (chan, format);
|
||||
OUT_RING (chan, cs2d_format);
|
||||
OUT_RING (chan, (dst->pitch << 16) | src->pitch);
|
||||
OUT_RELOCl(chan, src->bo, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, dst->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
|
|
@ -1003,12 +1047,12 @@ nv04_region_copy_blit(struct nv04_2d_context *ctx, struct nv04_region* dst, stru
|
|||
// dst and src may be modified, and the possibly modified version should be passed to nv04_region_cpu if necessary
|
||||
int
|
||||
nv04_region_copy_2d(struct nv04_2d_context *ctx, struct nv04_region* dst, struct nv04_region* src,
|
||||
int w, int h, int cs2d_format, int sifm_format, int dst_to_gpu, int src_on_gpu)
|
||||
int w, int h, int dst_to_gpu, int src_on_gpu)
|
||||
{
|
||||
assert(src->bpps == dst->bpps);
|
||||
|
||||
#ifdef NV04_REGION_DEBUG
|
||||
fprintf(stderr, "RGN_COPY%s [%i, %i: %i] ", (cs2d_format >= 0) ? "_2D" : "_NO2D", w, h, dst->bpps);
|
||||
fprintf(stderr, "RGN_COPY [%i, %i: %i] ", w, h, dst->bpps);
|
||||
for(int i = 0; i < 2; ++i)
|
||||
{
|
||||
int gpu = i ? src_on_gpu : dst_to_gpu;
|
||||
|
|
@ -1061,7 +1105,7 @@ nv04_region_copy_2d(struct nv04_2d_context *ctx, struct nv04_region* dst, struct
|
|||
{
|
||||
if (!dst->pitch)
|
||||
{
|
||||
if(cs2d_format < 0 || sifm_format < 0 || !dst_to_gpu)
|
||||
if(!dst_to_gpu)
|
||||
{
|
||||
#ifdef NV04_REGION_DEBUG
|
||||
fprintf(stderr, "\tCOPY_ENG3D\n");
|
||||
|
|
@ -1072,7 +1116,7 @@ nv04_region_copy_2d(struct nv04_2d_context *ctx, struct nv04_region* dst, struct
|
|||
{
|
||||
assert(!nv04_region_align(dst, w, h, 6));
|
||||
|
||||
nv04_region_copy_swizzle(ctx, dst, src, w, h, cs2d_format, sifm_format);
|
||||
nv04_region_copy_swizzle(ctx, dst, src, w, h);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1081,16 +1125,20 @@ nv04_region_copy_2d(struct nv04_2d_context *ctx, struct nv04_region* dst, struct
|
|||
/* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback
|
||||
* to NV_MEMORY_TO_MEMORY_FORMAT in this case.
|
||||
* TODO: is this also true for the source? possibly not
|
||||
* TODO: should we just always use m2mf?
|
||||
* TODO: if not, add support for multiple operations to copy_blit
|
||||
*/
|
||||
|
||||
if ((cs2d_format < 0)
|
||||
|| !dst_to_gpu
|
||||
if (!dst_to_gpu
|
||||
|| w > 2047
|
||||
|| h > 2047
|
||||
|| (w & 1)
|
||||
|| nv04_region_align(src, w, h, 6)
|
||||
|| nv04_region_align(dst, w, h, 6)
|
||||
)
|
||||
nv04_region_copy_m2mf(ctx, dst, src, w, h);
|
||||
else
|
||||
nv04_region_copy_blit(ctx, dst, src, w, h, cs2d_format);
|
||||
nv04_region_copy_blit(ctx, dst, src, w, h);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1112,26 +1160,25 @@ nv04_region_fill_gdirect(struct nv04_2d_context *ctx, struct nv04_region* dst, i
|
|||
assert(!(dst->pitch & 63) && dst->pitch);
|
||||
nv04_region_assert(dst, w, h);
|
||||
|
||||
if(dst->bpps == 0)
|
||||
switch(dst->bpps)
|
||||
{
|
||||
case 0:
|
||||
gdirect_format = NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8;
|
||||
cs2d_format = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
|
||||
}
|
||||
else if(dst->bpps == 1)
|
||||
{
|
||||
break;
|
||||
case 1:
|
||||
gdirect_format = NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5;
|
||||
cs2d_format = NV04_CONTEXT_SURFACES_2D_FORMAT_Y16;
|
||||
}
|
||||
else if(dst->bpps == 2)
|
||||
{
|
||||
break;
|
||||
case 2:
|
||||
gdirect_format = NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8;
|
||||
cs2d_format = NV04_CONTEXT_SURFACES_2D_FORMAT_Y32;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
gdirect_format = 0;
|
||||
cs2d_format = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
MARK_RING (chan, 15, 4);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ struct nv04_region {
|
|||
int offset;
|
||||
unsigned pitch; // 0 -> swizzled
|
||||
unsigned bpps; // bpp shift (0, 1, 2; 3, 4 for fp/compressed)
|
||||
unsigned one_bits; // number of high bits read and written as ones (for "no-alpha" optimization)
|
||||
unsigned x, y, z;
|
||||
unsigned w, h, d;
|
||||
};
|
||||
|
|
@ -95,7 +96,6 @@ int
|
|||
nv04_region_copy_2d(struct nv04_2d_context *ctx,
|
||||
struct nv04_region* dst, struct nv04_region* src,
|
||||
int w, int h,
|
||||
int cs2d_format, int sifm_format,
|
||||
int dst_to_gpu, int src_on_gpu);
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ nvfx_region_set_format(struct nv04_region* rgn, enum pipe_format format)
|
|||
{
|
||||
unsigned bits = util_format_get_blocksizebits(format);
|
||||
unsigned shift = 0;
|
||||
rgn->one_bits = 0;
|
||||
|
||||
switch(bits)
|
||||
{
|
||||
case 8:
|
||||
|
|
@ -55,9 +57,13 @@ nvfx_region_set_format(struct nv04_region* rgn, enum pipe_format format)
|
|||
break;
|
||||
case 16:
|
||||
rgn->bpps = 1;
|
||||
if(format == PIPE_FORMAT_B5G5R5X1_UNORM)
|
||||
rgn->one_bits = 1;
|
||||
break;
|
||||
case 32:
|
||||
rgn->bpps = 2;
|
||||
if(format == PIPE_FORMAT_R8G8B8X8_UNORM || format == PIPE_FORMAT_B8G8R8X8_UNORM)
|
||||
rgn->one_bits = 8;
|
||||
break;
|
||||
case 64:
|
||||
rgn->bpps = 2;
|
||||
|
|
@ -149,48 +155,6 @@ nvfx_region_init_for_subresource(struct nv04_region* rgn, struct pipe_resource*
|
|||
nv04_region_try_to_linearize(rgn);
|
||||
}
|
||||
|
||||
// TODO: actually test this for all formats, it's probably wrong for some...
|
||||
|
||||
static INLINE int
|
||||
nvfx_surface_format(enum pipe_format format)
|
||||
{
|
||||
switch(util_format_get_blocksize(format)) {
|
||||
case 1:
|
||||
return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
|
||||
case 2:
|
||||
//return NV04_CONTEXT_SURFACES_2D_FORMAT_Y16;
|
||||
return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
|
||||
case 4:
|
||||
//if(format == PIPE_FORMAT_B8G8R8X8_UNORM || format == PIPE_FORMAT_B8G8R8A8_UNORM)
|
||||
return NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
|
||||
//else
|
||||
// return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE int
|
||||
nv04_scaled_image_format(enum pipe_format format)
|
||||
{
|
||||
switch(util_format_get_blocksize(format)) {
|
||||
case 1:
|
||||
return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_Y8;
|
||||
case 2:
|
||||
//if(format == PIPE_FORMAT_B5G5R5A1_UNORM)
|
||||
// return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A1R5G5B5;
|
||||
//else
|
||||
return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5;
|
||||
case 4:
|
||||
if(format == PIPE_FORMAT_B8G8R8X8_UNORM)
|
||||
return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8;
|
||||
else
|
||||
return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// don't save index buffer because blitter doesn't setit
|
||||
static struct blitter_context*
|
||||
nvfx_get_blitter(struct pipe_context* pipe, int copy)
|
||||
|
|
@ -284,10 +248,7 @@ nvfx_resource_copy_region(struct pipe_context *pipe,
|
|||
if((!dst_to_gpu || !src_on_gpu) && small)
|
||||
ret = -1; /* use the CPU */
|
||||
else
|
||||
ret = nv04_region_copy_2d(ctx, &dst, &src, w, h,
|
||||
dstr->target == PIPE_BUFFER ? -1 : nvfx_surface_format(dstr->format),
|
||||
dstr->target == PIPE_BUFFER ? -1 : nv04_scaled_image_format(dstr->format),
|
||||
dst_to_gpu, src_on_gpu);
|
||||
ret = nv04_region_copy_2d(ctx, &dst, &src, w, h, dst_to_gpu, src_on_gpu);
|
||||
if(!ret)
|
||||
{}
|
||||
else if(ret > 0 && dstr->bind & PIPE_BIND_RENDER_TARGET && srcr->bind & PIPE_BIND_SAMPLER_VIEW)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue