mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 17:48:10 +02:00
nv50,nvc0: unify nvc0_miptree and nv50_miptree structs
Share some functions and restructure miptree creation a little. Prepare for multi-sample resources.
This commit is contained in:
parent
ebeec1d43a
commit
cad17554c4
14 changed files with 546 additions and 436 deletions
|
|
@ -130,20 +130,6 @@ nv50_context(struct pipe_context *pipe)
|
|||
return (struct nv50_context *)pipe;
|
||||
}
|
||||
|
||||
struct nv50_surface {
|
||||
struct pipe_surface base;
|
||||
uint32_t offset;
|
||||
uint32_t width;
|
||||
uint16_t height;
|
||||
uint16_t depth;
|
||||
};
|
||||
|
||||
static INLINE struct nv50_surface *
|
||||
nv50_surface(struct pipe_surface *ps)
|
||||
{
|
||||
return (struct nv50_surface *)ps;
|
||||
}
|
||||
|
||||
/* nv50_context.c */
|
||||
struct pipe_context *nv50_create(struct pipe_screen *, void *);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,49 +30,85 @@
|
|||
#include "nv50_transfer.h"
|
||||
|
||||
static INLINE uint32_t
|
||||
get_tile_dims(unsigned nx, unsigned ny, unsigned nz)
|
||||
nv50_tex_choose_tile_dims(unsigned nx, unsigned ny, unsigned nz)
|
||||
{
|
||||
uint32_t tile_mode = 0x00;
|
||||
|
||||
if (ny > 32) tile_mode = 0x04; /* height 128 tiles */
|
||||
else
|
||||
if (ny > 16) tile_mode = 0x03; /* height 64 tiles */
|
||||
else
|
||||
if (ny > 8) tile_mode = 0x02; /* height 32 tiles */
|
||||
else
|
||||
if (ny > 4) tile_mode = 0x01; /* height 16 tiles */
|
||||
|
||||
if (nz == 1)
|
||||
return tile_mode;
|
||||
else
|
||||
if (tile_mode > 0x02)
|
||||
tile_mode = 0x02;
|
||||
|
||||
if (nz > 16 && tile_mode < 0x02)
|
||||
return tile_mode | 0x50; /* depth 32 tiles */
|
||||
if (nz > 8) return tile_mode | 0x40; /* depth 16 tiles */
|
||||
if (nz > 4) return tile_mode | 0x30; /* depth 8 tiles */
|
||||
if (nz > 2) return tile_mode | 0x20; /* depth 4 tiles */
|
||||
|
||||
return tile_mode | 0x10;
|
||||
return nvc0_tex_choose_tile_dims(nx, ny * 2, nz) >> 4;
|
||||
}
|
||||
|
||||
static INLINE unsigned
|
||||
calc_zslice_offset(uint32_t tile_mode, unsigned z, unsigned pitch, unsigned nbh)
|
||||
static uint32_t
|
||||
nv50_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed)
|
||||
{
|
||||
unsigned tile_h = NV50_TILE_HEIGHT(tile_mode);
|
||||
unsigned tile_d_shift = NV50_TILE_DIM_SHIFT(tile_mode, 1);
|
||||
unsigned tile_d = 1 << tile_d_shift;
|
||||
const unsigned ms = util_logbase2(mt->base.base.nr_samples);
|
||||
|
||||
/* stride_2d == to next slice within this volume tile */
|
||||
/* stride_3d == size (in bytes) of a volume tile */
|
||||
unsigned stride_2d = tile_h * NV50_TILE_PITCH(tile_mode);
|
||||
unsigned stride_3d = tile_d * align(nbh, tile_h) * pitch;
|
||||
uint32_t tile_flags;
|
||||
|
||||
return (z & (tile_d - 1)) * stride_2d + (z >> tile_d_shift) * stride_3d;
|
||||
if (mt->base.base.bind & PIPE_BIND_CURSOR)
|
||||
return NOUVEAU_BO_TILE_SCANOUT;
|
||||
|
||||
switch (mt->base.base.format) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
tile_flags = 0x6c00 + (ms << 8);
|
||||
break;
|
||||
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
|
||||
tile_flags = 0x1800 + (ms << 8);
|
||||
break;
|
||||
case PIPE_FORMAT_Z24X8_UNORM:
|
||||
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
|
||||
tile_flags = 0x22800 + (ms << 8);
|
||||
break;
|
||||
case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
|
||||
tile_flags = 0x6000 + (ms << 8);
|
||||
break;
|
||||
default:
|
||||
switch (util_format_get_blocksizebits(mt->base.base.format)) {
|
||||
case 128:
|
||||
assert(ms < 3);
|
||||
tile_flags = 0x7400;
|
||||
break;
|
||||
case 64:
|
||||
switch (ms) {
|
||||
case 2: tile_flags = 0x17c00; break;
|
||||
case 3: tile_flags = 0x17d00; break;
|
||||
default:
|
||||
tile_flags = 0x7000;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
if (mt->base.base.bind & PIPE_BIND_SCANOUT) {
|
||||
assert(ms == 0);
|
||||
tile_flags = 0x7a00;
|
||||
} else {
|
||||
switch (ms) {
|
||||
case 2: tile_flags = 0x17800; break;
|
||||
case 3: tile_flags = 0x17900; break;
|
||||
default:
|
||||
tile_flags = 0x7000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
case 8:
|
||||
tile_flags = 0x7000;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
if (mt->base.base.bind & PIPE_BIND_CURSOR)
|
||||
tile_flags = 0;
|
||||
}
|
||||
|
||||
if (mt->base.base.bind & (PIPE_BIND_SCANOUT | PIPE_BIND_CURSOR))
|
||||
tile_flags |= NOUVEAU_BO_TILE_SCANOUT;
|
||||
|
||||
if (!compressed)
|
||||
tile_flags &= ~0x30000;
|
||||
|
||||
return tile_flags;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
nv50_miptree_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt)
|
||||
{
|
||||
struct nv50_miptree *mt = nv50_miptree(pt);
|
||||
|
|
@ -82,7 +118,7 @@ nv50_miptree_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt)
|
|||
FREE(mt);
|
||||
}
|
||||
|
||||
static boolean
|
||||
boolean
|
||||
nv50_miptree_get_handle(struct pipe_screen *pscreen,
|
||||
struct pipe_resource *pt,
|
||||
struct winsys_handle *whandle)
|
||||
|
|
@ -108,88 +144,95 @@ const struct u_resource_vtbl nv50_miptree_vtbl =
|
|||
nv50_miptree_destroy, /* resource_destroy */
|
||||
nv50_miptree_transfer_new, /* get_transfer */
|
||||
nv50_miptree_transfer_del, /* transfer_destroy */
|
||||
nv50_miptree_transfer_map, /* transfer_map */
|
||||
nv50_miptree_transfer_map, /* transfer_map */
|
||||
u_default_transfer_flush_region, /* transfer_flush_region */
|
||||
nv50_miptree_transfer_unmap, /* transfer_unmap */
|
||||
u_default_transfer_inline_write /* transfer_inline_write */
|
||||
};
|
||||
|
||||
struct pipe_resource *
|
||||
nv50_miptree_create(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *templ)
|
||||
static INLINE boolean
|
||||
nv50_miptree_init_ms_mode(struct nv50_miptree *mt)
|
||||
{
|
||||
switch (mt->base.base.nr_samples) {
|
||||
case 8:
|
||||
mt->ms_mode = NV50_3D_MULTISAMPLE_MODE_MS8;
|
||||
mt->ms_x = 2;
|
||||
mt->ms_y = 1;
|
||||
break;
|
||||
case 4:
|
||||
mt->ms_mode = NV50_3D_MULTISAMPLE_MODE_MS4;
|
||||
mt->ms_x = 1;
|
||||
mt->ms_y = 1;
|
||||
break;
|
||||
case 2:
|
||||
mt->ms_mode = NV50_3D_MULTISAMPLE_MODE_MS2;
|
||||
mt->ms_x = 1;
|
||||
break;
|
||||
case 1:
|
||||
case 0:
|
||||
mt->ms_mode = NV50_3D_MULTISAMPLE_MODE_MS1;
|
||||
break;
|
||||
default:
|
||||
NOUVEAU_ERR("invalid nr_samples: %u\n", mt->base.base.nr_samples);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean
|
||||
nv50_miptree_init_layout_linear(struct nv50_miptree *mt)
|
||||
{
|
||||
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
|
||||
struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
|
||||
struct pipe_resource *pt = &mt->base.base;
|
||||
int ret;
|
||||
unsigned w, h, d, l, alloc_size;
|
||||
uint32_t tile_flags;
|
||||
|
||||
if (!mt)
|
||||
return NULL;
|
||||
if (util_format_is_depth_or_stencil(pt->format))
|
||||
return FALSE;
|
||||
|
||||
mt->base.vtbl = &nv50_miptree_vtbl;
|
||||
*pt = *templ;
|
||||
pipe_reference_init(&pt->reference, 1);
|
||||
pt->screen = pscreen;
|
||||
if ((pt->last_level > 0) || (pt->depth0 > 1) || (pt->array_size > 1))
|
||||
return FALSE;
|
||||
if (mt->ms_x | mt->ms_y)
|
||||
return FALSE;
|
||||
|
||||
mt->level[0].pitch = align(pt->width0, 64);
|
||||
|
||||
mt->total_size = mt->level[0].pitch * pt->height0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_miptree_init_layout_tiled(struct nv50_miptree *mt)
|
||||
{
|
||||
struct pipe_resource *pt = &mt->base.base;
|
||||
unsigned w, h, d, l;
|
||||
const unsigned blocksize = util_format_get_blocksize(pt->format);
|
||||
|
||||
mt->layout_3d = pt->target == PIPE_TEXTURE_3D;
|
||||
|
||||
w = pt->width0;
|
||||
h = pt->height0;
|
||||
d = mt->layout_3d ? pt->depth0 : 1;
|
||||
|
||||
switch (pt->format) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
tile_flags = 0x6c00;
|
||||
break;
|
||||
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
|
||||
tile_flags = 0x1800;
|
||||
break;
|
||||
case PIPE_FORMAT_Z24X8_UNORM:
|
||||
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
|
||||
tile_flags = 0x2800;
|
||||
break;
|
||||
case PIPE_FORMAT_R32G32B32A32_FLOAT:
|
||||
case PIPE_FORMAT_R32G32B32_FLOAT:
|
||||
tile_flags = 0x7400;
|
||||
break;
|
||||
case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
|
||||
tile_flags = 0x6000;
|
||||
break;
|
||||
default:
|
||||
if (pt->bind & PIPE_BIND_CURSOR)
|
||||
tile_flags = 0;
|
||||
else
|
||||
if ((pt->bind & PIPE_BIND_SCANOUT) &&
|
||||
util_format_get_blocksizebits(pt->format) == 32)
|
||||
tile_flags = 0x7a00;
|
||||
else
|
||||
tile_flags = 0x7000;
|
||||
break;
|
||||
}
|
||||
if (pt->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_CURSOR))
|
||||
tile_flags |= NOUVEAU_BO_TILE_SCANOUT;
|
||||
w = pt->width0 << mt->ms_x;
|
||||
h = pt->height0 << mt->ms_y;
|
||||
|
||||
/* For 3D textures, a mipmap is spanned by all the layers, for array
|
||||
* textures and cube maps, each layer contains its own mipmaps.
|
||||
*/
|
||||
d = mt->layout_3d ? pt->depth0 : 1;
|
||||
|
||||
for (l = 0; l <= pt->last_level; ++l) {
|
||||
struct nv50_miptree_level *lvl = &mt->level[l];
|
||||
unsigned tsx, tsy, tsz;
|
||||
unsigned nbx = util_format_get_nblocksx(pt->format, w);
|
||||
unsigned nby = util_format_get_nblocksy(pt->format, h);
|
||||
unsigned blocksize = util_format_get_blocksize(pt->format);
|
||||
|
||||
lvl->offset = mt->total_size;
|
||||
|
||||
if (tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK)
|
||||
lvl->tile_mode = get_tile_dims(nbx, nby, d);
|
||||
lvl->tile_mode = nv50_tex_choose_tile_dims(nbx, nby, d);
|
||||
|
||||
lvl->pitch = align(nbx * blocksize, NV50_TILE_PITCH(lvl->tile_mode));
|
||||
tsx = NV50_TILE_SIZE_X(lvl->tile_mode); /* x is tile row pitch in bytes */
|
||||
tsy = NV50_TILE_SIZE_Y(lvl->tile_mode);
|
||||
tsz = NV50_TILE_SIZE_Z(lvl->tile_mode);
|
||||
|
||||
mt->total_size += lvl->pitch *
|
||||
align(nby, NV50_TILE_HEIGHT(lvl->tile_mode)) *
|
||||
align(d, NV50_TILE_DEPTH(lvl->tile_mode));
|
||||
lvl->pitch = align(nbx * blocksize, tsx);
|
||||
|
||||
mt->total_size += lvl->pitch * align(nby, tsy) * align(d, tsz);
|
||||
|
||||
w = u_minify(w, 1);
|
||||
h = u_minify(h, 1);
|
||||
|
|
@ -201,10 +244,43 @@ nv50_miptree_create(struct pipe_screen *pscreen,
|
|||
NV50_TILE_SIZE(mt->level[0].tile_mode));
|
||||
mt->total_size = mt->layer_stride * pt->array_size;
|
||||
}
|
||||
}
|
||||
|
||||
alloc_size = mt->total_size;
|
||||
struct pipe_resource *
|
||||
nv50_miptree_create(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *templ)
|
||||
{
|
||||
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
|
||||
struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
|
||||
struct pipe_resource *pt = &mt->base.base;
|
||||
int ret;
|
||||
uint32_t tile_flags;
|
||||
|
||||
ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 256, alloc_size,
|
||||
if (!mt)
|
||||
return NULL;
|
||||
|
||||
mt->base.vtbl = &nv50_miptree_vtbl;
|
||||
*pt = *templ;
|
||||
pipe_reference_init(&pt->reference, 1);
|
||||
pt->screen = pscreen;
|
||||
|
||||
tile_flags = nv50_mt_choose_storage_type(mt, TRUE);
|
||||
|
||||
if (!nv50_miptree_init_ms_mode(mt)) {
|
||||
FREE(mt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) {
|
||||
nv50_miptree_init_layout_tiled(mt);
|
||||
} else
|
||||
if (!nv50_miptree_init_layout_linear(mt)) {
|
||||
FREE(mt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 4096,
|
||||
mt->total_size,
|
||||
mt->level[0].tile_mode, tile_flags,
|
||||
&mt->base.bo);
|
||||
if (ret) {
|
||||
|
|
@ -255,58 +331,90 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen,
|
|||
}
|
||||
|
||||
|
||||
/* Offset of zslice @z from start of level @l. */
|
||||
INLINE unsigned
|
||||
nv50_mt_zslice_offset(const struct nv50_miptree *mt, unsigned l, unsigned z)
|
||||
{
|
||||
const struct pipe_resource *pt = &mt->base.base;
|
||||
|
||||
unsigned tds = NV50_TILE_SHIFT_Z(mt->level[l].tile_mode);
|
||||
unsigned ths = NV50_TILE_SHIFT_Y(mt->level[l].tile_mode);
|
||||
|
||||
unsigned nby = util_format_get_nblocksy(pt->format,
|
||||
u_minify(pt->height0, l));
|
||||
|
||||
/* to next 2D tile slice within a 3D tile */
|
||||
unsigned stride_2d = NV50_TILE_SIZE_2D(mt->level[l].tile_mode);
|
||||
|
||||
/* to slice in the next (in z direction) 3D tile */
|
||||
unsigned stride_3d = (align(nby, (1 << ths)) * mt->level[l].pitch) << tds;
|
||||
|
||||
return (z & ((1 << tds) - 1)) * stride_2d + (z >> tds) * stride_3d;
|
||||
}
|
||||
|
||||
/* Surface functions.
|
||||
*/
|
||||
|
||||
struct pipe_surface *
|
||||
nv50_miptree_surface_new(struct pipe_context *pipe,
|
||||
struct pipe_resource *pt,
|
||||
const struct pipe_surface *templ)
|
||||
struct nv50_surface *
|
||||
nv50_surface_from_miptree(struct nv50_miptree *mt,
|
||||
const struct pipe_surface *templ)
|
||||
{
|
||||
struct nv50_miptree *mt = nv50_miptree(pt); /* guaranteed */
|
||||
struct nv50_surface *ns;
|
||||
struct pipe_surface *ps;
|
||||
struct nv50_miptree_level *lvl = &mt->level[templ->u.tex.level];
|
||||
|
||||
ns = CALLOC_STRUCT(nv50_surface);
|
||||
struct nv50_surface *ns = CALLOC_STRUCT(nv50_surface);
|
||||
if (!ns)
|
||||
return NULL;
|
||||
ps = &ns->base;
|
||||
|
||||
pipe_reference_init(&ps->reference, 1);
|
||||
pipe_resource_reference(&ps->texture, pt);
|
||||
ps->context = pipe;
|
||||
pipe_resource_reference(&ps->texture, &mt->base.base);
|
||||
|
||||
ps->format = templ->format;
|
||||
ps->usage = templ->usage;
|
||||
ps->u.tex.level = templ->u.tex.level;
|
||||
ps->u.tex.first_layer = templ->u.tex.first_layer;
|
||||
ps->u.tex.last_layer = templ->u.tex.last_layer;
|
||||
|
||||
ns->width = u_minify(pt->width0, ps->u.tex.level);
|
||||
ns->height = u_minify(pt->height0, ps->u.tex.level);
|
||||
ns->width = u_minify(mt->base.base.width0, ps->u.tex.level);
|
||||
ns->height = u_minify(mt->base.base.height0, ps->u.tex.level);
|
||||
ns->depth = ps->u.tex.last_layer - ps->u.tex.first_layer + 1;
|
||||
ns->offset = lvl->offset;
|
||||
ns->offset = mt->level[templ->u.tex.level].offset;
|
||||
|
||||
/* comment says there are going to be removed, but they're used by the st */
|
||||
ps->width = ns->width;
|
||||
ps->height = ns->height;
|
||||
|
||||
if (mt->layout_3d) {
|
||||
unsigned zslice = ps->u.tex.first_layer;
|
||||
ns->width <<= mt->ms_x;
|
||||
ns->height <<= mt->ms_y;
|
||||
|
||||
/* TODO: re-layout the texture to use only depth 1 tiles in this case: */
|
||||
if (ns->depth > 1 && (zslice & (NV50_TILE_DEPTH(lvl->tile_mode) - 1)))
|
||||
NOUVEAU_ERR("Creating unsupported 3D surface of slices [%u:%u].\n",
|
||||
zslice, ps->u.tex.last_layer);
|
||||
return ns;
|
||||
}
|
||||
|
||||
ns->offset += calc_zslice_offset(lvl->tile_mode, zslice, lvl->pitch,
|
||||
util_format_get_nblocksy(pt->format,
|
||||
ns->height));
|
||||
} else {
|
||||
ns->offset += mt->layer_stride * ps->u.tex.first_layer;
|
||||
struct pipe_surface *
|
||||
nv50_miptree_surface_new(struct pipe_context *pipe,
|
||||
struct pipe_resource *pt,
|
||||
const struct pipe_surface *templ)
|
||||
{
|
||||
struct nv50_miptree *mt = nv50_miptree(pt);
|
||||
struct nv50_surface *ns = nv50_surface_from_miptree(mt, templ);
|
||||
if (!ns)
|
||||
return NULL;
|
||||
ns->base.context = pipe;
|
||||
|
||||
if (ns->base.u.tex.first_layer) {
|
||||
const unsigned l = ns->base.u.tex.level;
|
||||
const unsigned z = ns->base.u.tex.first_layer;
|
||||
|
||||
if (mt->layout_3d) {
|
||||
ns->offset += nv50_mt_zslice_offset(mt, l, z);
|
||||
|
||||
if (z & (NV50_TILE_SIZE_Z(mt->level[l].tile_mode) - 1))
|
||||
NOUVEAU_ERR("Creating unsupported 3D surface !\n");
|
||||
} else {
|
||||
ns->offset += mt->layer_stride * z;
|
||||
}
|
||||
}
|
||||
|
||||
return ps;
|
||||
return &ns->base;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -9,22 +9,32 @@
|
|||
#include "nouveau/nouveau_buffer.h"
|
||||
#undef NOUVEAU_NVC0
|
||||
|
||||
#ifndef __NVC0_RESOURCE_H__ /* make sure we don't use these in nvc0: */
|
||||
|
||||
void
|
||||
nv50_init_resource_functions(struct pipe_context *pcontext);
|
||||
|
||||
void
|
||||
nv50_screen_init_resource_functions(struct pipe_screen *pscreen);
|
||||
|
||||
#define NV50_TILE_DIM_SHIFT(m, d) (((m) >> (d * 4)) & 0xf)
|
||||
|
||||
#define NV50_TILE_PITCH(m) (64 << 0)
|
||||
#define NV50_TILE_HEIGHT(m) ( 4 << NV50_TILE_DIM_SHIFT(m, 0))
|
||||
#define NV50_TILE_DEPTH(m) ( 1 << NV50_TILE_DIM_SHIFT(m, 1))
|
||||
#define NV50_TILE_SHIFT_X(m) 6
|
||||
#define NV50_TILE_SHIFT_Y(m) ((((m) >> 0) & 0xf) + 2)
|
||||
#define NV50_TILE_SHIFT_Z(m) ((((m) >> 4) & 0xf) + 0)
|
||||
|
||||
#define NV50_TILE_SIZE_2D(m) ((64 * 4) << \
|
||||
NV50_TILE_DIM_SHIFT(m, 0))
|
||||
#define NV50_TILE_SIZE_X(m) 64
|
||||
#define NV50_TILE_SIZE_Y(m) ( 4 << (((m) >> 0) & 0xf))
|
||||
#define NV50_TILE_SIZE_Z(m) ( 1 << (((m) >> 4) & 0xf))
|
||||
|
||||
#define NV50_TILE_SIZE_2D(m) (NV50_TILE_SIZE_X(m) << NV50_TILE_SHIFT_Y(m))
|
||||
|
||||
#define NV50_TILE_SIZE(m) (NV50_TILE_SIZE_2D(m) << NV50_TILE_SHIFT_Z(m))
|
||||
|
||||
#endif /* __NVC0_RESOURCE_H__ */
|
||||
|
||||
uint32_t
|
||||
nvc0_tex_choose_tile_dims(unsigned nx, unsigned ny, unsigned nz);
|
||||
|
||||
#define NV50_TILE_SIZE(m) (NV50_TILE_SIZE_2D(m) << NV50_TILE_DIM_SHIFT(m, 1))
|
||||
|
||||
struct nv50_miptree_level {
|
||||
uint32_t offset;
|
||||
|
|
@ -40,6 +50,9 @@ struct nv50_miptree {
|
|||
uint32_t total_size;
|
||||
uint32_t layer_stride;
|
||||
boolean layout_3d; /* TRUE if layer count varies with mip level */
|
||||
uint8_t ms_x; /* log2 of number of samples in x/y dimension */
|
||||
uint8_t ms_y;
|
||||
uint8_t ms_mode;
|
||||
};
|
||||
|
||||
static INLINE struct nv50_miptree *
|
||||
|
|
@ -50,21 +63,57 @@ nv50_miptree(struct pipe_resource *pt)
|
|||
|
||||
/* Internal functions:
|
||||
*/
|
||||
boolean
|
||||
nv50_miptree_init_layout_linear(struct nv50_miptree *mt);
|
||||
|
||||
struct pipe_resource *
|
||||
nv50_miptree_create(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *tmp);
|
||||
|
||||
void
|
||||
nv50_miptree_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt);
|
||||
|
||||
struct pipe_resource *
|
||||
nv50_miptree_from_handle(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *template,
|
||||
struct winsys_handle *whandle);
|
||||
|
||||
boolean
|
||||
nv50_miptree_get_handle(struct pipe_screen *pscreen,
|
||||
struct pipe_resource *pt,
|
||||
struct winsys_handle *whandle);
|
||||
|
||||
struct nv50_surface {
|
||||
struct pipe_surface base;
|
||||
uint32_t offset;
|
||||
uint32_t width;
|
||||
uint16_t height;
|
||||
uint16_t depth;
|
||||
};
|
||||
|
||||
static INLINE struct nv50_surface *
|
||||
nv50_surface(struct pipe_surface *ps)
|
||||
{
|
||||
return (struct nv50_surface *)ps;
|
||||
}
|
||||
|
||||
#ifndef __NVC0_RESOURCE_H__
|
||||
|
||||
unsigned
|
||||
nv50_mt_zslice_offset(const struct nv50_miptree *mt, unsigned l, unsigned z);
|
||||
|
||||
struct pipe_surface *
|
||||
nv50_miptree_surface_new(struct pipe_context *,
|
||||
struct pipe_resource *,
|
||||
const struct pipe_surface *templ);
|
||||
|
||||
#endif /* __NVC0_RESOURCE_H__ */
|
||||
|
||||
struct nv50_surface *
|
||||
nv50_surface_from_miptree(struct nv50_miptree *mt,
|
||||
const struct pipe_surface *templ);
|
||||
|
||||
void
|
||||
nv50_miptree_surface_del(struct pipe_context *, struct pipe_surface *);
|
||||
|
||||
#endif
|
||||
#endif /* __NV50_RESOURCE_H__ */
|
||||
|
|
|
|||
|
|
@ -819,13 +819,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define NVC0_3D_LAYER_USE_GP 0x00010000
|
||||
|
||||
#define NVC0_3D_MULTISAMPLE_MODE 0x000015d0
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_1X 0x00000000
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_2XMS 0x00000001
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_4XMS 0x00000002
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_8XMS 0x00000003
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_4XMS_4XCS 0x00000008
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_4XMS_12XCS 0x00000009
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_8XMS_8XCS 0x0000000a
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_MS1 0x00000000
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_MS2 0x00000001
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_MS4 0x00000002
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_MS8 0x00000003
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_MS8_ALT 0x00000004
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_MS2_ALT 0x00000005
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_UNK6 0x00000006
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_MS4_CS4 0x00000008
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_MS4_CS12 0x00000009
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_MS8_CS8 0x0000000a
|
||||
#define NVC0_3D_MULTISAMPLE_MODE_MS8_CS24 0x0000000b
|
||||
|
||||
#define NVC0_3D_VERTEX_BEGIN_D3D 0x000015d4
|
||||
#define NVC0_3D_VERTEX_BEGIN_D3D_PRIMITIVE__MASK 0x0fffffff
|
||||
|
|
|
|||
|
|
@ -137,20 +137,6 @@ nvc0_context(struct pipe_context *pipe)
|
|||
return (struct nvc0_context *)pipe;
|
||||
}
|
||||
|
||||
struct nvc0_surface {
|
||||
struct pipe_surface base;
|
||||
uint32_t offset;
|
||||
uint32_t width;
|
||||
uint16_t height;
|
||||
uint16_t depth;
|
||||
};
|
||||
|
||||
static INLINE struct nvc0_surface *
|
||||
nvc0_surface(struct pipe_surface *ps)
|
||||
{
|
||||
return (struct nvc0_surface *)ps;
|
||||
}
|
||||
|
||||
/* nvc0_context.c */
|
||||
struct pipe_context *nvc0_create(struct pipe_screen *, void *);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@
|
|||
#include "nvc0_resource.h"
|
||||
#include "nvc0_transfer.h"
|
||||
|
||||
static INLINE uint32_t
|
||||
get_tile_dims(unsigned nx, unsigned ny, unsigned nz)
|
||||
uint32_t
|
||||
nvc0_tex_choose_tile_dims(unsigned nx, unsigned ny, unsigned nz)
|
||||
{
|
||||
uint32_t tile_mode = 0x000;
|
||||
|
||||
|
|
@ -57,151 +57,162 @@ get_tile_dims(unsigned nx, unsigned ny, unsigned nz)
|
|||
return tile_mode | 0x100;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
nvc0_miptree_zslice_offset(struct nvc0_miptree *mt, unsigned l, unsigned z)
|
||||
static uint32_t
|
||||
nvc0_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed)
|
||||
{
|
||||
unsigned nblocksy; /* height of texture level aligned to tile height */
|
||||
const unsigned ms = util_logbase2(mt->base.base.nr_samples);
|
||||
|
||||
unsigned stride_2d; /* to next slice within a 3D tile */
|
||||
unsigned stride_3d; /* to slice in the next (in z direction !) 3D tile */
|
||||
|
||||
unsigned tile_d_shift = NVC0_TILE_DIM_SHIFT(mt->level[l].tile_mode, 2);
|
||||
unsigned tile_d = 1 << tile_d_shift;
|
||||
|
||||
nblocksy = util_format_get_nblocksy(mt->base.base.format,
|
||||
u_minify(mt->base.base.height0, l));
|
||||
|
||||
nblocksy = align(nblocksy, NVC0_TILE_HEIGHT(mt->level[l].tile_mode));
|
||||
|
||||
stride_2d = NVC0_TILE_SIZE_2D(mt->level[l].tile_mode);
|
||||
|
||||
stride_3d = (nblocksy * mt->level[l].pitch) << tile_d_shift;
|
||||
|
||||
return (z & (tile_d - 1)) * stride_2d + (z >> tile_d_shift) * stride_3d;
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_miptree_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt)
|
||||
{
|
||||
struct nvc0_miptree *mt = nvc0_miptree(pt);
|
||||
|
||||
nouveau_screen_bo_release(pscreen, mt->base.bo);
|
||||
|
||||
FREE(mt);
|
||||
}
|
||||
|
||||
static boolean
|
||||
nvc0_miptree_get_handle(struct pipe_screen *pscreen,
|
||||
struct pipe_resource *pt,
|
||||
struct winsys_handle *whandle)
|
||||
{
|
||||
struct nvc0_miptree *mt = nvc0_miptree(pt);
|
||||
unsigned stride;
|
||||
|
||||
if (!mt || !mt->base.bo)
|
||||
return FALSE;
|
||||
|
||||
stride = util_format_get_stride(mt->base.base.format,
|
||||
mt->base.base.width0);
|
||||
|
||||
return nouveau_screen_bo_get_handle(pscreen,
|
||||
mt->base.bo,
|
||||
stride,
|
||||
whandle);
|
||||
}
|
||||
|
||||
const struct u_resource_vtbl nvc0_miptree_vtbl =
|
||||
{
|
||||
nvc0_miptree_get_handle, /* get_handle */
|
||||
nvc0_miptree_destroy, /* resource_destroy */
|
||||
nvc0_miptree_transfer_new, /* get_transfer */
|
||||
nvc0_miptree_transfer_del, /* transfer_destroy */
|
||||
nvc0_miptree_transfer_map, /* transfer_map */
|
||||
u_default_transfer_flush_region, /* transfer_flush_region */
|
||||
nvc0_miptree_transfer_unmap, /* transfer_unmap */
|
||||
u_default_transfer_inline_write /* transfer_inline_write */
|
||||
};
|
||||
|
||||
struct pipe_resource *
|
||||
nvc0_miptree_create(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *templ)
|
||||
{
|
||||
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
|
||||
struct nvc0_miptree *mt = CALLOC_STRUCT(nvc0_miptree);
|
||||
struct pipe_resource *pt = &mt->base.base;
|
||||
int ret;
|
||||
unsigned w, h, d, l, alloc_size;
|
||||
uint32_t tile_flags;
|
||||
|
||||
if (!mt)
|
||||
return NULL;
|
||||
compressed = FALSE; /* not yet supported */
|
||||
|
||||
mt->base.vtbl = &nvc0_miptree_vtbl;
|
||||
*pt = *templ;
|
||||
pipe_reference_init(&pt->reference, 1);
|
||||
pt->screen = pscreen;
|
||||
if (mt->base.base.bind & PIPE_BIND_CURSOR)
|
||||
return NOUVEAU_BO_TILE_SCANOUT;
|
||||
|
||||
mt->layout_3d = pt->target == PIPE_TEXTURE_3D;
|
||||
|
||||
w = pt->width0;
|
||||
h = pt->height0;
|
||||
d = mt->layout_3d ? pt->depth0 : 1;
|
||||
|
||||
switch (pt->format) {
|
||||
switch (mt->base.base.format) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
tile_flags = 0x0700; /* COMPRESSED */
|
||||
tile_flags = 0x0100; /* NORMAL */
|
||||
if (compressed)
|
||||
tile_flags = 0x0200 + (ms << 8);
|
||||
else
|
||||
tile_flags = 0x0100;
|
||||
break;
|
||||
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
|
||||
tile_flags = 0x5300; /* MSAA 4, COMPRESSED */
|
||||
tile_flags = 0x4600; /* NORMAL */
|
||||
if (compressed)
|
||||
tile_flags = 0x5100 + (ms << 8);
|
||||
else
|
||||
tile_flags = 0x4600;
|
||||
break;
|
||||
case PIPE_FORMAT_Z24X8_UNORM:
|
||||
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
|
||||
tile_flags = 0x1100; /* NORMAL */
|
||||
if (w * h >= 128 * 128 && 0)
|
||||
tile_flags = 0x1700; /* COMPRESSED, requires magic */
|
||||
break;
|
||||
case PIPE_FORMAT_R32G32B32A32_FLOAT:
|
||||
tile_flags = 0xf500; /* COMPRESSED */
|
||||
tile_flags = 0xf700; /* MSAA 2 */
|
||||
tile_flags = 0xf900; /* MSAA 4 */
|
||||
tile_flags = 0xfe00; /* NORMAL */
|
||||
if (compressed)
|
||||
tile_flags = 0x1700 + (ms << 8);
|
||||
else
|
||||
tile_flags = 0x1100;
|
||||
break;
|
||||
case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
|
||||
tile_flags = 0xce00; /* COMPRESSED */
|
||||
tile_flags = 0xcf00; /* MSAA 2, COMPRESSED */
|
||||
tile_flags = 0xd000; /* MSAA 4, COMPRESSED */
|
||||
tile_flags = 0xc300; /* NORMAL */
|
||||
break;
|
||||
case PIPE_FORMAT_R16G16B16A16_UNORM:
|
||||
tile_flags = 0xe900; /* COMPRESSED */
|
||||
tile_flags = 0xfe00; /* NORMAL */
|
||||
if (compressed)
|
||||
tile_flags = 0xce00 + (ms << 8);
|
||||
else
|
||||
tile_flags = 0xc300;
|
||||
break;
|
||||
default:
|
||||
tile_flags = 0xe000; /* MSAA 4, COMPRESSED 32 BIT */
|
||||
tile_flags = 0xfe00; /* NORMAL 32 BIT */
|
||||
if (w * h >= 128 * 128 && 0)
|
||||
tile_flags = 0xdb00; /* COMPRESSED 32 BIT, requires magic */
|
||||
switch (util_format_get_blocksizebits(mt->base.base.format)) {
|
||||
case 128:
|
||||
if (compressed)
|
||||
tile_flags = 0xf400 + (ms << 9);
|
||||
else
|
||||
tile_flags = 0xfe00;
|
||||
break;
|
||||
case 64:
|
||||
if (compressed) {
|
||||
switch (ms) {
|
||||
case 0: tile_flags = 0xe600; break;
|
||||
case 1: tile_flags = 0xeb00; break;
|
||||
case 2: tile_flags = 0xed00; break;
|
||||
case 3: tile_flags = 0xf200; break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
tile_flags = 0xfe00;
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
if (compressed) {
|
||||
switch (ms) {
|
||||
case 0: tile_flags = 0xdb00; break;
|
||||
case 1: tile_flags = 0xdd00; break;
|
||||
case 2: tile_flags = 0xdf00; break;
|
||||
case 3: tile_flags = 0xe400; break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
tile_flags = 0xfe00;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
case 8:
|
||||
tile_flags = 0xfe00;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (mt->base.base.bind & PIPE_BIND_SCANOUT)
|
||||
tile_flags |= NOUVEAU_BO_TILE_SCANOUT;
|
||||
|
||||
return tile_flags;
|
||||
}
|
||||
|
||||
static INLINE boolean
|
||||
nvc0_miptree_init_ms_mode(struct nv50_miptree *mt)
|
||||
{
|
||||
switch (mt->base.base.nr_samples) {
|
||||
case 8:
|
||||
mt->ms_mode = NVC0_3D_MULTISAMPLE_MODE_MS8;
|
||||
mt->ms_x = 2;
|
||||
mt->ms_y = 1;
|
||||
break;
|
||||
case 4:
|
||||
mt->ms_mode = NVC0_3D_MULTISAMPLE_MODE_MS4;
|
||||
mt->ms_x = 1;
|
||||
mt->ms_y = 1;
|
||||
break;
|
||||
case 2:
|
||||
mt->ms_mode = NVC0_3D_MULTISAMPLE_MODE_MS2;
|
||||
mt->ms_x = 1;
|
||||
break;
|
||||
case 1:
|
||||
case 0:
|
||||
mt->ms_mode = NVC0_3D_MULTISAMPLE_MODE_MS1;
|
||||
break;
|
||||
default:
|
||||
NOUVEAU_ERR("invalid nr_samples: %u\n", mt->base.base.nr_samples);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean
|
||||
nv50_miptree_init_layout_linear(struct nv50_miptree *);
|
||||
|
||||
static void
|
||||
nvc0_miptree_init_layout_tiled(struct nv50_miptree *mt)
|
||||
{
|
||||
struct pipe_resource *pt = &mt->base.base;
|
||||
unsigned w, h, d, l;
|
||||
const unsigned blocksize = util_format_get_blocksize(pt->format);
|
||||
|
||||
mt->layout_3d = pt->target == PIPE_TEXTURE_3D;
|
||||
|
||||
w = pt->width0 << mt->ms_x;
|
||||
h = pt->height0 << mt->ms_y;
|
||||
|
||||
/* For 3D textures, a mipmap is spanned by all the layers, for array
|
||||
* textures and cube maps, each layer contains its own mipmaps.
|
||||
*/
|
||||
d = mt->layout_3d ? pt->depth0 : 1;
|
||||
|
||||
for (l = 0; l <= pt->last_level; ++l) {
|
||||
struct nvc0_miptree_level *lvl = &mt->level[l];
|
||||
struct nv50_miptree_level *lvl = &mt->level[l];
|
||||
unsigned tsx, tsy, tsz;
|
||||
unsigned nbx = util_format_get_nblocksx(pt->format, w);
|
||||
unsigned nby = util_format_get_nblocksy(pt->format, h);
|
||||
unsigned blocksize = util_format_get_blocksize(pt->format);
|
||||
|
||||
lvl->offset = mt->total_size;
|
||||
lvl->tile_mode = get_tile_dims(nbx, nby, d);
|
||||
lvl->pitch = align(nbx * blocksize, NVC0_TILE_PITCH(lvl->tile_mode));
|
||||
|
||||
mt->total_size += lvl->pitch *
|
||||
align(nby, NVC0_TILE_HEIGHT(lvl->tile_mode)) *
|
||||
align(d, NVC0_TILE_DEPTH(lvl->tile_mode));
|
||||
lvl->tile_mode = nvc0_tex_choose_tile_dims(nbx, nby, d);
|
||||
|
||||
tsx = NVC0_TILE_SIZE_X(lvl->tile_mode); /* x is tile row pitch in bytes */
|
||||
tsy = NVC0_TILE_SIZE_Y(lvl->tile_mode);
|
||||
tsz = NVC0_TILE_SIZE_Z(lvl->tile_mode);
|
||||
|
||||
lvl->pitch = align(nbx * blocksize, tsx);
|
||||
|
||||
mt->total_size += lvl->pitch * align(nby, tsy) * align(d, tsz);
|
||||
|
||||
w = u_minify(w, 1);
|
||||
h = u_minify(h, 1);
|
||||
|
|
@ -213,12 +224,55 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
|
|||
NVC0_TILE_SIZE(mt->level[0].tile_mode));
|
||||
mt->total_size = mt->layer_stride * pt->array_size;
|
||||
}
|
||||
}
|
||||
|
||||
alloc_size = mt->total_size;
|
||||
if (tile_flags == 0x1700)
|
||||
alloc_size *= 3; /* HiZ, XXX: correct size */
|
||||
const struct u_resource_vtbl nvc0_miptree_vtbl =
|
||||
{
|
||||
nv50_miptree_get_handle, /* get_handle */
|
||||
nv50_miptree_destroy, /* resource_destroy */
|
||||
nvc0_miptree_transfer_new, /* get_transfer */
|
||||
nvc0_miptree_transfer_del, /* transfer_destroy */
|
||||
nvc0_miptree_transfer_map, /* transfer_map */
|
||||
u_default_transfer_flush_region, /* transfer_flush_region */
|
||||
nvc0_miptree_transfer_unmap, /* transfer_unmap */
|
||||
u_default_transfer_inline_write /* transfer_inline_write */
|
||||
};
|
||||
|
||||
ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 256, alloc_size,
|
||||
struct pipe_resource *
|
||||
nvc0_miptree_create(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *templ)
|
||||
{
|
||||
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
|
||||
struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
|
||||
struct pipe_resource *pt = &mt->base.base;
|
||||
int ret;
|
||||
uint32_t tile_flags;
|
||||
|
||||
if (!mt)
|
||||
return NULL;
|
||||
|
||||
mt->base.vtbl = &nvc0_miptree_vtbl;
|
||||
*pt = *templ;
|
||||
pipe_reference_init(&pt->reference, 1);
|
||||
pt->screen = pscreen;
|
||||
|
||||
tile_flags = nvc0_mt_choose_storage_type(mt, TRUE);
|
||||
|
||||
if (!nvc0_miptree_init_ms_mode(mt)) {
|
||||
FREE(mt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) {
|
||||
nvc0_miptree_init_layout_tiled(mt);
|
||||
} else
|
||||
if (!nv50_miptree_init_layout_linear(mt)) {
|
||||
FREE(mt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 4096,
|
||||
mt->total_size,
|
||||
mt->level[0].tile_mode, tile_flags,
|
||||
&mt->base.bo);
|
||||
if (ret) {
|
||||
|
|
@ -230,45 +284,27 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
|
|||
return pt;
|
||||
}
|
||||
|
||||
struct pipe_resource *
|
||||
nvc0_miptree_from_handle(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *templ,
|
||||
struct winsys_handle *whandle)
|
||||
/* Offset of zslice @z from start of level @l. */
|
||||
INLINE unsigned
|
||||
nvc0_mt_zslice_offset(const struct nv50_miptree *mt, unsigned l, unsigned z)
|
||||
{
|
||||
struct nvc0_miptree *mt;
|
||||
unsigned stride;
|
||||
const struct pipe_resource *pt = &mt->base.base;
|
||||
|
||||
/* only supports 2D, non-mipmapped textures for the moment */
|
||||
if ((templ->target != PIPE_TEXTURE_2D &&
|
||||
templ->target != PIPE_TEXTURE_RECT) ||
|
||||
templ->last_level != 0 ||
|
||||
templ->depth0 != 1 ||
|
||||
templ->array_size > 1)
|
||||
return NULL;
|
||||
unsigned tds = NVC0_TILE_SHIFT_Z(mt->level[l].tile_mode);
|
||||
unsigned ths = NVC0_TILE_SHIFT_Y(mt->level[l].tile_mode);
|
||||
|
||||
mt = CALLOC_STRUCT(nvc0_miptree);
|
||||
if (!mt)
|
||||
return NULL;
|
||||
unsigned nby = util_format_get_nblocksy(pt->format,
|
||||
u_minify(pt->height0, l));
|
||||
|
||||
mt->base.bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride);
|
||||
if (mt->base.bo == NULL) {
|
||||
FREE(mt);
|
||||
return NULL;
|
||||
}
|
||||
/* to next 2D tile slice within a 3D tile */
|
||||
unsigned stride_2d = NVC0_TILE_SIZE_2D(mt->level[l].tile_mode);
|
||||
|
||||
mt->base.base = *templ;
|
||||
mt->base.vtbl = &nvc0_miptree_vtbl;
|
||||
pipe_reference_init(&mt->base.base.reference, 1);
|
||||
mt->base.base.screen = pscreen;
|
||||
mt->level[0].pitch = stride;
|
||||
mt->level[0].offset = 0;
|
||||
mt->level[0].tile_mode = mt->base.bo->tile_mode;
|
||||
/* to slice in the next (in z direction) 3D tile */
|
||||
unsigned stride_3d = (align(nby, (1 << ths)) * mt->level[l].pitch) << tds;
|
||||
|
||||
/* no need to adjust bo reference count */
|
||||
return &mt->base.base;
|
||||
return (z & (1 << (tds - 1))) * stride_2d + (z >> tds) * stride_3d;
|
||||
}
|
||||
|
||||
|
||||
/* Surface functions.
|
||||
*/
|
||||
|
||||
|
|
@ -277,43 +313,9 @@ nvc0_miptree_surface_new(struct pipe_context *pipe,
|
|||
struct pipe_resource *pt,
|
||||
const struct pipe_surface *templ)
|
||||
{
|
||||
struct nvc0_miptree *mt = nvc0_miptree(pt); /* guaranteed */
|
||||
struct nvc0_surface *ns;
|
||||
struct pipe_surface *ps;
|
||||
struct nvc0_miptree_level *lvl = &mt->level[templ->u.tex.level];
|
||||
|
||||
ns = CALLOC_STRUCT(nvc0_surface);
|
||||
struct nv50_surface *ns = nv50_surface_from_miptree(nv50_miptree(pt), templ);
|
||||
if (!ns)
|
||||
return NULL;
|
||||
ps = &ns->base;
|
||||
|
||||
pipe_reference_init(&ps->reference, 1);
|
||||
pipe_resource_reference(&ps->texture, pt);
|
||||
ps->context = pipe;
|
||||
ps->format = templ->format;
|
||||
ps->usage = templ->usage;
|
||||
ps->u.tex.level = templ->u.tex.level;
|
||||
ps->u.tex.first_layer = templ->u.tex.first_layer;
|
||||
ps->u.tex.last_layer = templ->u.tex.last_layer;
|
||||
|
||||
ns->width = u_minify(pt->width0, ps->u.tex.level);
|
||||
ns->height = u_minify(pt->height0, ps->u.tex.level);
|
||||
ns->depth = ps->u.tex.last_layer - ps->u.tex.first_layer + 1;
|
||||
ns->offset = lvl->offset;
|
||||
|
||||
/* comment says there are going to be removed, but they're used by the st */
|
||||
ps->width = ns->width;
|
||||
ps->height = ns->height;
|
||||
|
||||
return ps;
|
||||
}
|
||||
|
||||
void
|
||||
nvc0_miptree_surface_del(struct pipe_context *pipe, struct pipe_surface *ps)
|
||||
{
|
||||
struct nvc0_surface *s = nvc0_surface(ps);
|
||||
|
||||
pipe_resource_reference(&ps->texture, NULL);
|
||||
|
||||
FREE(s);
|
||||
ns->base.context = pipe;
|
||||
return &ns->base;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,10 +21,14 @@ nvc0_resource_from_handle(struct pipe_screen * screen,
|
|||
const struct pipe_resource *templ,
|
||||
struct winsys_handle *whandle)
|
||||
{
|
||||
if (templ->target == PIPE_BUFFER)
|
||||
if (templ->target == PIPE_BUFFER) {
|
||||
return NULL;
|
||||
else
|
||||
return nvc0_miptree_from_handle(screen, templ, whandle);
|
||||
} else {
|
||||
struct pipe_resource *res = nv50_miptree_from_handle(screen,
|
||||
templ, whandle);
|
||||
nv04_resource(res)->vtbl = &nvc0_miptree_vtbl;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -37,7 +41,7 @@ nvc0_init_resource_functions(struct pipe_context *pcontext)
|
|||
pcontext->transfer_destroy = u_transfer_destroy_vtbl;
|
||||
pcontext->transfer_inline_write = u_transfer_inline_write_vtbl;
|
||||
pcontext->create_surface = nvc0_miptree_surface_new;
|
||||
pcontext->surface_destroy = nvc0_miptree_surface_del;
|
||||
pcontext->surface_destroy = nv50_miptree_surface_del;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -2,13 +2,23 @@
|
|||
#ifndef __NVC0_RESOURCE_H__
|
||||
#define __NVC0_RESOURCE_H__
|
||||
|
||||
#include "util/u_transfer.h"
|
||||
#include "util/u_double_list.h"
|
||||
#define NOUVEAU_NVC0
|
||||
#include "nouveau/nouveau_winsys.h"
|
||||
#include "nouveau/nouveau_fence.h"
|
||||
#include "nouveau/nouveau_buffer.h"
|
||||
#undef NOUVEAU_NVC0
|
||||
#include "nv50/nv50_resource.h"
|
||||
|
||||
|
||||
#define NVC0_TILE_SHIFT_X(m) ((((m) >> 0) & 0xf) + 6)
|
||||
#define NVC0_TILE_SHIFT_Y(m) ((((m) >> 4) & 0xf) + 3)
|
||||
#define NVC0_TILE_SHIFT_Z(m) ((((m) >> 8) & 0xf) + 0)
|
||||
|
||||
#define NVC0_TILE_SIZE_X(m) (64 << (((m) >> 0) & 0xf))
|
||||
#define NVC0_TILE_SIZE_Y(m) ( 8 << (((m) >> 4) & 0xf))
|
||||
#define NVC0_TILE_SIZE_Z(m) ( 1 << (((m) >> 8) & 0xf))
|
||||
|
||||
/* it's ok to mask only in the end because max value is 3 * 5 */
|
||||
|
||||
#define NVC0_TILE_SIZE_2D(m) ((64 * 8) << (((m) + ((m) >> 4)) & 0xf))
|
||||
|
||||
#define NVC0_TILE_SIZE(m) ((64 * 8) << (((m) + ((m) >> 4) + ((m) >> 8)) & 0xf))
|
||||
|
||||
|
||||
void
|
||||
nvc0_init_resource_functions(struct pipe_context *pcontext);
|
||||
|
|
@ -16,60 +26,20 @@ nvc0_init_resource_functions(struct pipe_context *pcontext);
|
|||
void
|
||||
nvc0_screen_init_resource_functions(struct pipe_screen *pscreen);
|
||||
|
||||
#define NVC0_TILE_DIM_SHIFT(m, d) (((m) >> (d * 4)) & 0xf)
|
||||
|
||||
#define NVC0_TILE_PITCH(m) (64 << NVC0_TILE_DIM_SHIFT(m, 0))
|
||||
#define NVC0_TILE_HEIGHT(m) ( 8 << NVC0_TILE_DIM_SHIFT(m, 1))
|
||||
#define NVC0_TILE_DEPTH(m) ( 1 << NVC0_TILE_DIM_SHIFT(m, 2))
|
||||
|
||||
#define NVC0_TILE_SIZE_2D(m) (((64 * 8) << \
|
||||
NVC0_TILE_DIM_SHIFT(m, 0)) << \
|
||||
NVC0_TILE_DIM_SHIFT(m, 1))
|
||||
|
||||
#define NVC0_TILE_SIZE(m) (NVC0_TILE_SIZE_2D(m) << NVC0_TILE_DIM_SHIFT(m, 2))
|
||||
|
||||
struct nvc0_miptree_level {
|
||||
uint32_t offset;
|
||||
uint32_t pitch;
|
||||
uint32_t tile_mode;
|
||||
};
|
||||
|
||||
#define NVC0_MAX_TEXTURE_LEVELS 16
|
||||
|
||||
struct nvc0_miptree {
|
||||
struct nv04_resource base;
|
||||
struct nvc0_miptree_level level[NVC0_MAX_TEXTURE_LEVELS];
|
||||
uint32_t total_size;
|
||||
uint32_t layer_stride;
|
||||
boolean layout_3d; /* TRUE if layer count varies with mip level */
|
||||
};
|
||||
|
||||
static INLINE struct nvc0_miptree *
|
||||
nvc0_miptree(struct pipe_resource *pt)
|
||||
{
|
||||
return (struct nvc0_miptree *)pt;
|
||||
}
|
||||
|
||||
/* Internal functions:
|
||||
*/
|
||||
struct pipe_resource *
|
||||
nvc0_miptree_create(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *tmp);
|
||||
|
||||
struct pipe_resource *
|
||||
nvc0_miptree_from_handle(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *template,
|
||||
struct winsys_handle *whandle);
|
||||
const struct u_resource_vtbl nvc0_miptree_vtbl;
|
||||
|
||||
struct pipe_surface *
|
||||
nvc0_miptree_surface_new(struct pipe_context *,
|
||||
struct pipe_resource *,
|
||||
const struct pipe_surface *templ);
|
||||
|
||||
void
|
||||
nvc0_miptree_surface_del(struct pipe_context *, struct pipe_surface *);
|
||||
|
||||
uint32_t
|
||||
nvc0_miptree_zslice_offset(struct nvc0_miptree *, unsigned l, unsigned z);
|
||||
unsigned
|
||||
nvc0_mt_zslice_offset(const struct nv50_miptree *, unsigned l, unsigned z);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -437,7 +437,7 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
|
|||
BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1);
|
||||
OUT_RING (chan, NVC0_3D_MULTISAMPLE_MODE_1X);
|
||||
OUT_RING (chan, NVC0_3D_MULTISAMPLE_MODE_MS1);
|
||||
BEGIN_RING(chan, RING_3D(MULTISAMPLE_CTRL), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(LINE_WIDTH_SEPARATE), 1);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#define NOUVEAU_NVC0
|
||||
#include "nouveau/nouveau_screen.h"
|
||||
#include "nouveau/nouveau_mm.h"
|
||||
#include "nouveau/nouveau_fence.h"
|
||||
#undef NOUVEAU_NVC0
|
||||
#include "nvc0_winsys.h"
|
||||
#include "nvc0_stateobj.h"
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ nvc0_validate_zcull(struct nvc0_context *nvc0)
|
|||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
|
||||
struct nvc0_surface *sf = nvc0_surface(fb->zsbuf);
|
||||
struct nvc0_miptree *mt = nvc0_miptree(sf->base.texture);
|
||||
struct nv50_surface *sf = nv50_surface(fb->zsbuf);
|
||||
struct nv50_miptree *mt = nv50_miptree(sf->base.texture);
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
uint32_t size;
|
||||
uint32_t offset = align(mt->total_size, 1 << 17);
|
||||
|
|
@ -72,8 +72,8 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
|
|||
MARK_RING(chan, 9 * fb->nr_cbufs, 2 * fb->nr_cbufs);
|
||||
|
||||
for (i = 0; i < fb->nr_cbufs; ++i) {
|
||||
struct nvc0_miptree *mt = nvc0_miptree(fb->cbufs[i]->texture);
|
||||
struct nvc0_surface *sf = nvc0_surface(fb->cbufs[i]);
|
||||
struct nv50_miptree *mt = nv50_miptree(fb->cbufs[i]->texture);
|
||||
struct nv50_surface *sf = nv50_surface(fb->cbufs[i]);
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
uint32_t offset = sf->offset;
|
||||
|
||||
|
|
@ -100,8 +100,8 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
|
|||
}
|
||||
|
||||
if (fb->zsbuf) {
|
||||
struct nvc0_miptree *mt = nvc0_miptree(fb->zsbuf->texture);
|
||||
struct nvc0_surface *sf = nvc0_surface(fb->zsbuf);
|
||||
struct nv50_miptree *mt = nv50_miptree(fb->zsbuf->texture);
|
||||
struct nv50_surface *sf = nv50_surface(fb->zsbuf);
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
int unk = mt->base.base.target == PIPE_TEXTURE_2D;
|
||||
uint32_t offset = sf->offset;
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ nvc0_2d_format(enum pipe_format format)
|
|||
|
||||
static int
|
||||
nvc0_2d_texture_set(struct nouveau_channel *chan, int dst,
|
||||
struct nvc0_miptree *mt, unsigned level, unsigned layer)
|
||||
struct nv50_miptree *mt, unsigned level, unsigned layer)
|
||||
{
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
uint32_t width, height, depth;
|
||||
|
|
@ -103,7 +103,7 @@ nvc0_2d_texture_set(struct nouveau_channel *chan, int dst,
|
|||
depth = 1;
|
||||
} else
|
||||
if (!dst) {
|
||||
offset += nvc0_miptree_zslice_offset(mt, level, layer);
|
||||
offset += nvc0_mt_zslice_offset(mt, level, layer);
|
||||
layer = 0;
|
||||
}
|
||||
|
||||
|
|
@ -145,9 +145,9 @@ nvc0_2d_texture_set(struct nouveau_channel *chan, int dst,
|
|||
|
||||
static int
|
||||
nvc0_2d_texture_do_copy(struct nouveau_channel *chan,
|
||||
struct nvc0_miptree *dst, unsigned dst_level,
|
||||
struct nv50_miptree *dst, unsigned dst_level,
|
||||
unsigned dx, unsigned dy, unsigned dz,
|
||||
struct nvc0_miptree *src, unsigned src_level,
|
||||
struct nv50_miptree *src, unsigned src_level,
|
||||
unsigned sx, unsigned sy, unsigned sz,
|
||||
unsigned w, unsigned h)
|
||||
{
|
||||
|
|
@ -192,7 +192,7 @@ nvc0_setup_m2mf_rect(struct nvc0_m2mf_rect *rect,
|
|||
struct pipe_resource *restrict res, unsigned l,
|
||||
unsigned x, unsigned y, unsigned z)
|
||||
{
|
||||
struct nvc0_miptree *mt = nvc0_miptree(res);
|
||||
struct nv50_miptree *mt = nv50_miptree(res);
|
||||
const unsigned w = u_minify(res->width0, l);
|
||||
const unsigned h = u_minify(res->height0, l);
|
||||
|
||||
|
|
@ -257,15 +257,15 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
|
|||
for (i = 0; i < src_box->depth; ++i) {
|
||||
nvc0_m2mf_transfer_rect(&screen->base.base, &drect, &srect, nx, ny);
|
||||
|
||||
if (nvc0_miptree(dst)->layout_3d)
|
||||
if (nv50_miptree(dst)->layout_3d)
|
||||
drect.z++;
|
||||
else
|
||||
drect.base += nvc0_miptree(dst)->layer_stride;
|
||||
drect.base += nv50_miptree(dst)->layer_stride;
|
||||
|
||||
if (nvc0_miptree(src)->layout_3d)
|
||||
if (nv50_miptree(src)->layout_3d)
|
||||
srect.z++;
|
||||
else
|
||||
srect.base += nvc0_miptree(src)->layer_stride;
|
||||
srect.base += nv50_miptree(src)->layer_stride;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -275,9 +275,9 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
|
|||
|
||||
for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) {
|
||||
ret = nvc0_2d_texture_do_copy(screen->base.channel,
|
||||
nvc0_miptree(dst), dst_level,
|
||||
nv50_miptree(dst), dst_level,
|
||||
dstx, dsty, dst_layer,
|
||||
nvc0_miptree(src), src_level,
|
||||
nv50_miptree(src), src_level,
|
||||
src_box->x, src_box->y, src_layer,
|
||||
src_box->width, src_box->height);
|
||||
if (ret)
|
||||
|
|
@ -295,8 +295,8 @@ nvc0_clear_render_target(struct pipe_context *pipe,
|
|||
struct nvc0_context *nv50 = nvc0_context(pipe);
|
||||
struct nvc0_screen *screen = nv50->screen;
|
||||
struct nouveau_channel *chan = screen->base.channel;
|
||||
struct nvc0_miptree *mt = nvc0_miptree(dst->texture);
|
||||
struct nvc0_surface *sf = nvc0_surface(dst);
|
||||
struct nv50_miptree *mt = nv50_miptree(dst->texture);
|
||||
struct nv50_surface *sf = nv50_surface(dst);
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
|
||||
|
|
@ -347,8 +347,8 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe,
|
|||
struct nvc0_context *nv50 = nvc0_context(pipe);
|
||||
struct nvc0_screen *screen = nv50->screen;
|
||||
struct nouveau_channel *chan = screen->base.channel;
|
||||
struct nvc0_miptree *mt = nvc0_miptree(dst->texture);
|
||||
struct nvc0_surface *sf = nvc0_surface(dst);
|
||||
struct nv50_miptree *mt = nv50_miptree(dst->texture);
|
||||
struct nv50_surface *sf = nv50_surface(dst);
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
uint32_t mode = 0;
|
||||
int unk = mt->base.base.target == PIPE_TEXTURE_2D;
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
|
|||
uint32_t swz[4];
|
||||
uint32_t depth;
|
||||
struct nv50_tic_entry *view;
|
||||
struct nvc0_miptree *mt = nvc0_miptree(texture);
|
||||
struct nv50_miptree *mt = nv50_miptree(texture);
|
||||
boolean tex_int;
|
||||
|
||||
view = MALLOC_STRUCT(nv50_tic_entry);
|
||||
|
|
@ -189,7 +189,7 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s)
|
|||
OUT_RING (chan, (i << 1) | 0);
|
||||
continue;
|
||||
}
|
||||
res = &nvc0_miptree(tic->pipe.texture)->base;
|
||||
res = &nv50_miptree(tic->pipe.texture)->base;
|
||||
|
||||
if (tic->id < 0) {
|
||||
uint32_t offset = tic->tic[1];
|
||||
|
|
|
|||
|
|
@ -239,8 +239,8 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx,
|
|||
struct nvc0_context *nvc0 = nvc0_context(pctx);
|
||||
struct pipe_screen *pscreen = pctx->screen;
|
||||
struct nouveau_device *dev = nvc0->screen->base.device;
|
||||
struct nvc0_miptree *mt = nvc0_miptree(res);
|
||||
struct nvc0_miptree_level *lvl = &mt->level[level];
|
||||
struct nv50_miptree *mt = nv50_miptree(res);
|
||||
struct nv50_miptree_level *lvl = &mt->level[level];
|
||||
struct nvc0_transfer *tx;
|
||||
uint32_t size;
|
||||
uint32_t w, h, d, z, layer;
|
||||
|
|
@ -334,7 +334,7 @@ nvc0_miptree_transfer_del(struct pipe_context *pctx,
|
|||
{
|
||||
struct pipe_screen *pscreen = pctx->screen;
|
||||
struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
|
||||
struct nvc0_miptree *mt = nvc0_miptree(tx->base.resource);
|
||||
struct nv50_miptree *mt = nv50_miptree(tx->base.resource);
|
||||
unsigned i;
|
||||
|
||||
if (tx->base.usage & PIPE_TRANSFER_WRITE) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue