mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 11:20:20 +01:00
r300g: added support for 3D textures
Mipmaps not tested. Also, I am not sure why piglit/texturing/tex3d needs to have color tolerance +-1 to pass. The classic Mesa driver doesn't need that.
This commit is contained in:
parent
94a63dccdd
commit
118dfe1688
4 changed files with 51 additions and 53 deletions
|
|
@ -181,6 +181,9 @@ struct r300_texture {
|
|||
/* Offsets into the buffer. */
|
||||
unsigned offset[PIPE_MAX_TEXTURE_LEVELS];
|
||||
|
||||
/* Size of one zslice or face based on the texture target */
|
||||
unsigned layer_size[PIPE_MAX_TEXTURE_LEVELS];
|
||||
|
||||
/**
|
||||
* If non-zero, override the natural texture layout with
|
||||
* a custom stride (in bytes).
|
||||
|
|
|
|||
|
|
@ -119,32 +119,13 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
|
|||
case PIPE_CAP_TEXTURE_SHADOW_MAP:
|
||||
return 1;
|
||||
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
|
||||
if (r300screen->caps->is_r500) {
|
||||
/* 13 == 4096x4096 */
|
||||
return 13;
|
||||
} else {
|
||||
/* 12 == 2048x2048 */
|
||||
return 12;
|
||||
}
|
||||
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
|
||||
/* So, technically, the limit is the same as above, but some math
|
||||
* shows why this is silly. Assuming RGBA, 4cpp, we can see that
|
||||
* 4096*4096*4096 = 64.0 GiB exactly, so it's not exactly
|
||||
* practical. However, if at some point a game really wants this,
|
||||
* then we can remove or raise this limit. */
|
||||
if (r300screen->caps->is_r500) {
|
||||
/* 9 == 256x256x256 */
|
||||
return 9;
|
||||
} else {
|
||||
/* 8 == 128*128*128 */
|
||||
return 8;
|
||||
}
|
||||
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
|
||||
if (r300screen->caps->is_r500) {
|
||||
/* 13 == 4096x4096 */
|
||||
/* 13 == 4096 */
|
||||
return 13;
|
||||
} else {
|
||||
/* 12 == 2048x2048 */
|
||||
/* 12 == 2048 */
|
||||
return 12;
|
||||
}
|
||||
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
|
||||
|
|
@ -191,8 +172,8 @@ static float r300_get_paramf(struct pipe_screen* pscreen, int param)
|
|||
}
|
||||
}
|
||||
|
||||
static boolean check_tex_2d_format(enum pipe_format format, uint32_t usage,
|
||||
boolean is_r500)
|
||||
static boolean check_tex_format(enum pipe_format format, uint32_t usage,
|
||||
boolean is_r500)
|
||||
{
|
||||
uint32_t retval = 0;
|
||||
|
||||
|
|
@ -286,7 +267,6 @@ static boolean check_tex_2d_format(enum pipe_format format, uint32_t usage,
|
|||
return (retval >= usage);
|
||||
}
|
||||
|
||||
/* XXX moar targets */
|
||||
static boolean r300_is_format_supported(struct pipe_screen* pscreen,
|
||||
enum pipe_format format,
|
||||
enum pipe_texture_target target,
|
||||
|
|
@ -294,15 +274,17 @@ static boolean r300_is_format_supported(struct pipe_screen* pscreen,
|
|||
unsigned geom_flags)
|
||||
{
|
||||
switch (target) {
|
||||
case PIPE_TEXTURE_1D: /* handle 1D textures as 2D ones */
|
||||
case PIPE_TEXTURE_2D:
|
||||
return check_tex_2d_format(format, tex_usage,
|
||||
r300_screen(pscreen)->caps->is_r500);
|
||||
case PIPE_TEXTURE_1D:
|
||||
case PIPE_TEXTURE_3D:
|
||||
return check_tex_format(format, tex_usage,
|
||||
r300_screen(pscreen)->caps->is_r500);
|
||||
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
debug_printf("r300: Implementation error: Unsupported format "
|
||||
"target: %d\n", target);
|
||||
break;
|
||||
|
||||
default:
|
||||
debug_printf("r300: Fatal: This is not a format target: %d\n",
|
||||
target);
|
||||
|
|
@ -322,22 +304,9 @@ r300_get_tex_transfer(struct pipe_screen *screen,
|
|||
{
|
||||
struct r300_texture *tex = (struct r300_texture *)texture;
|
||||
struct r300_transfer *trans;
|
||||
unsigned offset = 0; /* in bytes */
|
||||
unsigned offset;
|
||||
|
||||
/* XXX Add support for these things */
|
||||
if (texture->target == PIPE_TEXTURE_CUBE) {
|
||||
debug_printf("PIPE_TEXTURE_CUBE is not yet supported.\n");
|
||||
/* offset = tex->image_offset[level][face]; */
|
||||
}
|
||||
else if (texture->target == PIPE_TEXTURE_3D) {
|
||||
debug_printf("PIPE_TEXTURE_3D is not yet supported.\n");
|
||||
/* offset = tex->image_offset[level][zslice]; */
|
||||
}
|
||||
else {
|
||||
offset = tex->offset[level];
|
||||
assert(face == 0);
|
||||
assert(zslice == 0);
|
||||
}
|
||||
offset = r300_texture_get_offset(tex, level, zslice, face); /* in bytes */
|
||||
|
||||
trans = CALLOC_STRUCT(r300_transfer);
|
||||
if (trans) {
|
||||
|
|
@ -352,6 +321,12 @@ r300_get_tex_transfer(struct pipe_screen *screen,
|
|||
trans->transfer.nblocksy = texture->nblocksy[level];
|
||||
trans->transfer.stride = r300_texture_get_stride(tex, level);
|
||||
trans->transfer.usage = usage;
|
||||
|
||||
/* XXX not sure whether it's required to set these two,
|
||||
the driver doesn't use them */
|
||||
trans->transfer.zslice = zslice;
|
||||
trans->transfer.face = face;
|
||||
|
||||
trans->offset = offset;
|
||||
}
|
||||
return &trans->transfer;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ static void r300_setup_texture_state(struct r300_texture* tex)
|
|||
state->format0 = R300_TX_WIDTH((pt->width[0] - 1) & 0x7ff) |
|
||||
R300_TX_HEIGHT((pt->height[0] - 1) & 0x7ff) |
|
||||
R300_TX_DEPTH(util_logbase2(pt->depth[0]) & 0xf) |
|
||||
R300_TX_NUM_LEVELS(pt->last_level) |
|
||||
R300_TX_NUM_LEVELS(pt->last_level & 0xf) |
|
||||
R300_TX_PITCH_EN;
|
||||
|
||||
/* XXX */
|
||||
|
|
@ -48,7 +48,8 @@ static void r300_setup_texture_state(struct r300_texture* tex)
|
|||
state->format1 |= R300_TX_FORMAT_3D;
|
||||
}
|
||||
|
||||
state->format2 = (r300_texture_get_stride(tex, 0) / pt->block.size) - 1;
|
||||
state->format2 = ((r300_texture_get_stride(tex, 0) / pt->block.size) - 1)
|
||||
& 0x1fff;
|
||||
|
||||
/* Don't worry about accidentally setting this bit on non-r500;
|
||||
* the kernel should catch it. */
|
||||
|
|
@ -63,6 +64,26 @@ static void r300_setup_texture_state(struct r300_texture* tex)
|
|||
pt->width[0], pt->height[0], pt->last_level);
|
||||
}
|
||||
|
||||
unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
|
||||
unsigned zslice, unsigned face)
|
||||
{
|
||||
unsigned offset = tex->offset[level];
|
||||
|
||||
switch (tex->tex.target) {
|
||||
case PIPE_TEXTURE_3D:
|
||||
assert(face == 0);
|
||||
return offset + zslice * tex->layer_size[level];
|
||||
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
assert(zslice == 0);
|
||||
return offset + face * tex->layer_size[level];
|
||||
|
||||
default:
|
||||
assert(zslice == 0 && face == 0);
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the stride, in bytes, of the texture images of the given texture
|
||||
* at the given level.
|
||||
|
|
@ -84,7 +105,7 @@ unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level)
|
|||
static void r300_setup_miptree(struct r300_texture* tex)
|
||||
{
|
||||
struct pipe_texture* base = &tex->tex;
|
||||
int stride, size;
|
||||
int stride, size, layer_size;
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= base->last_level; i++) {
|
||||
|
|
@ -98,10 +119,12 @@ static void r300_setup_miptree(struct r300_texture* tex)
|
|||
base->nblocksy[i] = pf_get_nblocksy(&base->block, base->height[i]);
|
||||
|
||||
stride = r300_texture_get_stride(tex, i);
|
||||
size = stride * base->nblocksy[i] * base->depth[i];
|
||||
layer_size = stride * base->nblocksy[i];
|
||||
size = layer_size * base->depth[i];
|
||||
|
||||
tex->offset[i] = align(tex->size, 32);
|
||||
tex->size = tex->offset[i] + size;
|
||||
tex->layer_size[i] = layer_size;
|
||||
|
||||
debug_printf("r300: Texture miptree: Level %d "
|
||||
"(%dx%dx%d px, pitch %d bytes)\n",
|
||||
|
|
@ -161,8 +184,7 @@ static struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
|
|||
struct pipe_surface* surface = CALLOC_STRUCT(pipe_surface);
|
||||
unsigned offset;
|
||||
|
||||
/* XXX this is certainly dependent on tex target */
|
||||
offset = tex->offset[level];
|
||||
offset = r300_texture_get_offset(tex, level, zslice, face);
|
||||
|
||||
if (surface) {
|
||||
pipe_reference_init(&surface->reference, 1);
|
||||
|
|
@ -191,11 +213,6 @@ static struct pipe_texture*
|
|||
{
|
||||
struct r300_texture* tex;
|
||||
|
||||
if (base->target != PIPE_TEXTURE_2D ||
|
||||
base->depth[0] != 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tex = CALLOC_STRUCT(r300_texture);
|
||||
if (!tex) {
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen);
|
|||
|
||||
unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level);
|
||||
|
||||
unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
|
||||
unsigned zslice, unsigned face);
|
||||
|
||||
/* Note the signature of R300_EASY_TX_FORMAT(A, R, G, B, FORMAT)... */
|
||||
static INLINE uint32_t r300_translate_texformat(enum pipe_format format)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue