mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-07 05:40:39 +02:00
nvc0: adapt to array textures interface change
This commit is contained in:
parent
0f68236a24
commit
ca5deb0c35
9 changed files with 250 additions and 200 deletions
|
|
@ -130,7 +130,11 @@ nvc0_context(struct pipe_context *pipe)
|
|||
}
|
||||
|
||||
struct nvc0_surface {
|
||||
struct pipe_surface pipe;
|
||||
struct pipe_surface base;
|
||||
uint32_t offset;
|
||||
uint32_t width;
|
||||
uint16_t height;
|
||||
uint16_t depth;
|
||||
};
|
||||
|
||||
static INLINE struct nvc0_surface *
|
||||
|
|
|
|||
|
|
@ -60,12 +60,12 @@ get_tile_dims(unsigned nx, unsigned ny, unsigned nz)
|
|||
static INLINE unsigned
|
||||
get_zslice_offset(uint32_t tile_mode, unsigned z, unsigned pitch, unsigned nbh)
|
||||
{
|
||||
unsigned tile_h = NVC0_TILE_H(tile_mode);
|
||||
unsigned tile_d = NVC0_TILE_D(tile_mode);
|
||||
unsigned tile_h = NVC0_TILE_HEIGHT(tile_mode);
|
||||
unsigned tile_d = NVC0_TILE_DEPTH(tile_mode);
|
||||
|
||||
/* pitch_2d == to next slice within this volume tile */
|
||||
/* pitch_3d == size (in bytes) of a volume tile */
|
||||
unsigned pitch_2d = tile_h * 64;
|
||||
unsigned pitch_2d = tile_h * NVC0_TILE_PITCH(tile_mode);
|
||||
unsigned pitch_3d = tile_d * align(nbh, tile_h) * pitch;
|
||||
|
||||
return (z % tile_d) * pitch_2d + (z / tile_d) * pitch_3d;
|
||||
|
|
@ -75,10 +75,6 @@ static void
|
|||
nvc0_miptree_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt)
|
||||
{
|
||||
struct nvc0_miptree *mt = nvc0_miptree(pt);
|
||||
unsigned l;
|
||||
|
||||
for (l = 0; l <= pt->last_level; ++l)
|
||||
FREE(mt->level[l].image_offset);
|
||||
|
||||
nouveau_screen_bo_release(pscreen, mt->base.bo);
|
||||
|
||||
|
|
@ -125,8 +121,8 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
|
|||
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, i;
|
||||
unsigned w, h, d, l, image_alignment, alloc_size;
|
||||
int ret;
|
||||
unsigned w, h, d, l, alloc_size;
|
||||
uint32_t tile_flags;
|
||||
|
||||
if (!mt)
|
||||
|
|
@ -137,9 +133,11 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
|
|||
pipe_reference_init(&pt->reference, 1);
|
||||
pt->screen = pscreen;
|
||||
|
||||
mt->layout_3d = pt->target == PIPE_TEXTURE_3D;
|
||||
|
||||
w = pt->width0;
|
||||
h = pt->height0;
|
||||
d = pt->depth0;
|
||||
d = mt->layout_3d ? pt->depth0 : 1;
|
||||
|
||||
switch (pt->format) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
|
|
@ -180,47 +178,32 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
|
|||
break;
|
||||
}
|
||||
|
||||
/* XXX: texture arrays */
|
||||
mt->image_nr = (pt->target == PIPE_TEXTURE_CUBE) ? 6 : 1;
|
||||
|
||||
for (l = 0; l <= pt->last_level; l++) {
|
||||
/* For 3D textures, a mipmap is spanned by all the layers, for array
|
||||
* textures and cube maps, each layer contains its own mipmaps.
|
||||
*/
|
||||
for (l = 0; l <= pt->last_level; ++l) {
|
||||
struct nvc0_miptree_level *lvl = &mt->level[l];
|
||||
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->image_offset = CALLOC(mt->image_nr, sizeof(int));
|
||||
lvl->pitch = align(util_format_get_stride(pt->format, w), 64);
|
||||
lvl->tile_mode = get_tile_dims(w, nby, d);
|
||||
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));
|
||||
|
||||
w = u_minify(w, 1);
|
||||
h = u_minify(h, 1);
|
||||
d = u_minify(d, 1);
|
||||
}
|
||||
|
||||
image_alignment = NVC0_TILE_H(mt->level[0].tile_mode) * 64;
|
||||
image_alignment *= NVC0_TILE_D(mt->level[0].tile_mode);
|
||||
|
||||
/* NOTE the distinction between arrays of mip-mapped 2D textures and
|
||||
* mip-mapped 3D textures. We can't use image_nr == depth for 3D mip.
|
||||
*/
|
||||
for (i = 0; i < mt->image_nr; i++) {
|
||||
for (l = 0; l <= pt->last_level; l++) {
|
||||
struct nvc0_miptree_level *lvl = &mt->level[l];
|
||||
int size;
|
||||
unsigned tile_h = NVC0_TILE_H(lvl->tile_mode);
|
||||
unsigned tile_d = NVC0_TILE_D(lvl->tile_mode);
|
||||
|
||||
h = u_minify(pt->height0, l);
|
||||
d = u_minify(pt->depth0, l);
|
||||
|
||||
size = lvl->pitch;
|
||||
size *= align(util_format_get_nblocksy(pt->format, h), tile_h);
|
||||
size *= align(d, tile_d);
|
||||
|
||||
lvl->image_offset[i] = mt->total_size;
|
||||
|
||||
mt->total_size += size;
|
||||
}
|
||||
mt->total_size = align(mt->total_size, image_alignment);
|
||||
if (pt->array_size > 1) {
|
||||
mt->layer_stride = align(mt->total_size,
|
||||
NVC0_TILE_SIZE(mt->level[0].tile_mode));
|
||||
mt->total_size = mt->layer_stride * pt->array_size;
|
||||
}
|
||||
|
||||
alloc_size = mt->total_size;
|
||||
|
|
@ -231,11 +214,10 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
|
|||
mt->level[0].tile_mode, tile_flags,
|
||||
&mt->base.bo);
|
||||
if (ret) {
|
||||
for (l = 0; l <= pt->last_level; ++l)
|
||||
FREE(mt->level[l].image_offset);
|
||||
FREE(mt);
|
||||
return NULL;
|
||||
}
|
||||
mt->base.domain = NOUVEAU_BO_VRAM;
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
|
@ -248,11 +230,12 @@ nvc0_miptree_from_handle(struct pipe_screen *pscreen,
|
|||
struct nvc0_miptree *mt;
|
||||
unsigned stride;
|
||||
|
||||
/* only supports 2D, non-mip mapped textures for the moment */
|
||||
/* 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->depth0 != 1 ||
|
||||
templ->array_size > 1)
|
||||
return NULL;
|
||||
|
||||
mt = CALLOC_STRUCT(nvc0_miptree);
|
||||
|
|
@ -269,9 +252,8 @@ nvc0_miptree_from_handle(struct pipe_screen *pscreen,
|
|||
mt->base.vtbl = &nvc0_miptree_vtbl;
|
||||
pipe_reference_init(&mt->base.base.reference, 1);
|
||||
mt->base.base.screen = pscreen;
|
||||
mt->image_nr = 1;
|
||||
mt->level[0].pitch = stride;
|
||||
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
|
||||
mt->level[0].offset = 0;
|
||||
mt->level[0].tile_mode = mt->base.bo->tile_mode;
|
||||
|
||||
/* no need to adjust bo reference count */
|
||||
|
|
@ -283,41 +265,52 @@ nvc0_miptree_from_handle(struct pipe_screen *pscreen,
|
|||
*/
|
||||
|
||||
struct pipe_surface *
|
||||
nvc0_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
|
||||
unsigned face, unsigned level, unsigned zslice,
|
||||
unsigned flags)
|
||||
nvc0_miptree_surface_new(struct pipe_context *pipe,
|
||||
struct pipe_resource *pt,
|
||||
const struct pipe_surface *templ)
|
||||
{
|
||||
struct nvc0_miptree *mt = nvc0_miptree(pt);
|
||||
struct nvc0_miptree_level *lvl = &mt->level[level];
|
||||
struct nvc0_miptree *mt = nvc0_miptree(pt); /* guaranteed */
|
||||
struct nvc0_surface *ns;
|
||||
struct pipe_surface *ps;
|
||||
unsigned img = 0;
|
||||
struct nvc0_miptree_level *lvl = &mt->level[templ->u.tex.level];
|
||||
|
||||
if (pt->target == PIPE_TEXTURE_CUBE)
|
||||
img = face;
|
||||
|
||||
ps = CALLOC_STRUCT(pipe_surface);
|
||||
if (!ps)
|
||||
ns = CALLOC_STRUCT(nvc0_surface);
|
||||
if (!ns)
|
||||
return NULL;
|
||||
pipe_resource_reference(&ps->texture, pt);
|
||||
ps->format = pt->format;
|
||||
ps->width = u_minify(pt->width0, level);
|
||||
ps->height = u_minify(pt->height0, level);
|
||||
ps->usage = flags;
|
||||
pipe_reference_init(&ps->reference, 1);
|
||||
ps->face = face;
|
||||
ps->level = level;
|
||||
ps->zslice = zslice;
|
||||
ps->offset = lvl->image_offset[img];
|
||||
ps = &ns->base;
|
||||
|
||||
if (pt->target == PIPE_TEXTURE_3D)
|
||||
ps->offset += get_zslice_offset(lvl->tile_mode, zslice, lvl->pitch,
|
||||
pipe_reference_init(&ps->reference, 1);
|
||||
pipe_resource_reference(&ps->texture, pt);
|
||||
ps->context = pipe;
|
||||
ps->format = pt->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;
|
||||
|
||||
if (mt->layout_3d) {
|
||||
ns->offset += get_zslice_offset(lvl->tile_mode, ps->u.tex.first_layer,
|
||||
lvl->pitch,
|
||||
util_format_get_nblocksy(pt->format,
|
||||
ps->height));
|
||||
ns->height));
|
||||
} else {
|
||||
ns->offset += mt->layer_stride * ps->u.tex.first_layer;
|
||||
}
|
||||
|
||||
return ps;
|
||||
}
|
||||
|
||||
void
|
||||
nvc0_miptree_surface_del(struct pipe_surface *ps)
|
||||
nvc0_miptree_surface_del(struct pipe_context *pipe, struct pipe_surface *ps)
|
||||
{
|
||||
struct nvc0_surface *s = nvc0_surface(ps);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
static unsigned
|
||||
nvc0_resource_is_referenced(struct pipe_context *pipe,
|
||||
struct pipe_resource *resource,
|
||||
unsigned face, unsigned level)
|
||||
unsigned face, int layer)
|
||||
{
|
||||
struct nvc0_resource *res = nvc0_resource(resource);
|
||||
unsigned flags = 0;
|
||||
|
|
@ -56,6 +56,8 @@ 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->is_resource_referenced = nvc0_resource_is_referenced;
|
||||
pcontext->create_surface = nvc0_miptree_surface_new;
|
||||
pcontext->surface_destroy = nvc0_miptree_surface_del;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -66,6 +68,4 @@ nvc0_screen_init_resource_functions(struct pipe_screen *pscreen)
|
|||
pscreen->resource_get_handle = u_resource_get_handle_vtbl;
|
||||
pscreen->resource_destroy = u_resource_destroy_vtbl;
|
||||
pscreen->user_buffer_create = nvc0_user_buffer_create;
|
||||
pscreen->get_tex_surface = nvc0_miptree_surface_new;
|
||||
pscreen->tex_surface_destroy = nvc0_miptree_surface_del;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,11 +66,15 @@ nvc0_resource_unmap(struct nvc0_resource *res)
|
|||
nouveau_bo_unmap(res->bo);
|
||||
}
|
||||
|
||||
#define NVC0_TILE_H(m) (8 << ((m >> 4) & 0xf))
|
||||
#define NVC0_TILE_D(m) (1 << (m >> 8))
|
||||
#define NVC0_TILE_PITCH(m) (64 << ((m) & 0xf))
|
||||
#define NVC0_TILE_HEIGHT(m) (8 << (((m) >> 4) & 0xf))
|
||||
#define NVC0_TILE_DEPTH(m) (1 << ((m) >> 8))
|
||||
|
||||
#define NVC0_TILE_SIZE(m) \
|
||||
(NVC0_TILE_PITCH(m) * NVC0_TILE_HEIGHT(m) * NVC0_TILE_DEPTH(m))
|
||||
|
||||
struct nvc0_miptree_level {
|
||||
int *image_offset;
|
||||
uint32_t offset;
|
||||
uint32_t pitch;
|
||||
uint32_t tile_mode;
|
||||
};
|
||||
|
|
@ -80,8 +84,9 @@ struct nvc0_miptree_level {
|
|||
struct nvc0_miptree {
|
||||
struct nvc0_resource base;
|
||||
struct nvc0_miptree_level level[NVC0_MAX_TEXTURE_LEVELS];
|
||||
int image_nr;
|
||||
int total_size;
|
||||
uint32_t total_size;
|
||||
uint32_t layer_stride;
|
||||
boolean layout_3d; /* TRUE if layer count varies with mip level */
|
||||
};
|
||||
|
||||
static INLINE struct nvc0_miptree *
|
||||
|
|
@ -132,12 +137,12 @@ nvc0_user_buffer_create(struct pipe_screen *screen,
|
|||
|
||||
|
||||
struct pipe_surface *
|
||||
nvc0_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
|
||||
unsigned face, unsigned level, unsigned zslice,
|
||||
unsigned flags);
|
||||
nvc0_miptree_surface_new(struct pipe_context *,
|
||||
struct pipe_resource *,
|
||||
const struct pipe_surface *templ);
|
||||
|
||||
void
|
||||
nvc0_miptree_surface_del(struct pipe_surface *ps);
|
||||
nvc0_miptree_surface_del(struct pipe_context *, struct pipe_surface *);
|
||||
|
||||
struct nvc0_context;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,15 @@ nvc0_validate_zcull(struct nvc0_context *nvc0)
|
|||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
|
||||
struct nvc0_miptree *mt = nvc0_miptree(fb->zsbuf->texture);
|
||||
struct nvc0_surface *sf = nvc0_surface(fb->zsbuf);
|
||||
struct nvc0_miptree *mt = nvc0_miptree(sf->base.texture);
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
uint32_t size;
|
||||
uint32_t offset = align(mt->total_size, 1 << 17);
|
||||
unsigned width, height;
|
||||
|
||||
assert(mt->base.base.depth0 == 1 && mt->base.base.array_size < 2);
|
||||
|
||||
size = mt->total_size * 2;
|
||||
|
||||
height = align(fb->height, 32);
|
||||
|
|
@ -65,18 +68,20 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
|
|||
|
||||
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 nouveau_bo *bo = mt->base.bo;
|
||||
unsigned offset = fb->cbufs[i]->offset;
|
||||
uint32_t offset = sf->offset;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(i)), 8);
|
||||
OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RING (chan, fb->cbufs[i]->width);
|
||||
OUT_RING (chan, fb->cbufs[i]->height);
|
||||
OUT_RING (chan, nvc0_format_table[fb->cbufs[i]->format].rt);
|
||||
OUT_RING (chan, mt->level[fb->cbufs[i]->level].tile_mode);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, sf->width);
|
||||
OUT_RING (chan, sf->height);
|
||||
OUT_RING (chan, nvc0_format_table[sf->base.format].rt);
|
||||
OUT_RING (chan, (mt->layout_3d << 16) |
|
||||
mt->level[sf->base.u.tex.level].tile_mode);
|
||||
OUT_RING (chan, sf->depth);
|
||||
OUT_RING (chan, mt->layer_stride);
|
||||
|
||||
nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base,
|
||||
NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
|
|
@ -84,21 +89,23 @@ 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 nouveau_bo *bo = mt->base.bo;
|
||||
unsigned offset = fb->zsbuf->offset;
|
||||
int unk = mt->base.base.target == PIPE_TEXTURE_2D;
|
||||
uint32_t offset = sf->offset;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
|
||||
OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RING (chan, nvc0_format_table[fb->zsbuf->format].rt);
|
||||
OUT_RING (chan, mt->level[fb->zsbuf->level].tile_mode);
|
||||
OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
|
||||
OUT_RING (chan, fb->zsbuf->width);
|
||||
OUT_RING (chan, fb->zsbuf->height);
|
||||
OUT_RING (chan, (1 << 16) | 1);
|
||||
OUT_RING (chan, sf->width);
|
||||
OUT_RING (chan, sf->height);
|
||||
OUT_RING (chan, (unk << 16) | sf->depth);
|
||||
|
||||
nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base,
|
||||
NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
|
|
|
|||
|
|
@ -78,75 +78,90 @@ nvc0_2d_format(enum pipe_format format)
|
|||
}
|
||||
|
||||
static int
|
||||
nvc0_surface_set(struct nvc0_screen *screen, struct pipe_surface *ps, int dst)
|
||||
nvc0_2d_texture_set(struct nouveau_channel *chan, int dst,
|
||||
struct nvc0_miptree *mt, unsigned level, unsigned layer)
|
||||
{
|
||||
struct nvc0_miptree *mt = nvc0_miptree(ps->texture);
|
||||
struct nouveau_channel *chan = screen->base.channel;
|
||||
struct nouveau_bo *bo = nvc0_miptree(ps->texture)->base.bo;
|
||||
int format, mthd = dst ? NVC0_2D_DST_FORMAT : NVC0_2D_SRC_FORMAT;
|
||||
int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
uint32_t width, height, depth;
|
||||
uint32_t format;
|
||||
uint32_t mthd = dst ? NVC0_2D_DST_FORMAT : NVC0_2D_SRC_FORMAT;
|
||||
uint32_t flags = mt->base.domain | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
|
||||
uint32_t offset = mt->level[level].offset;
|
||||
|
||||
format = nvc0_2d_format(ps->format);
|
||||
format = nvc0_2d_format(mt->base.base.format);
|
||||
if (!format) {
|
||||
NOUVEAU_ERR("invalid/unsupported surface format: %s\n",
|
||||
util_format_name(ps->format));
|
||||
util_format_name(mt->base.base.format));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!bo->tile_flags) {
|
||||
width = u_minify(mt->base.base.width0, level);
|
||||
height = u_minify(mt->base.base.height0, level);
|
||||
|
||||
offset = mt->level[level].offset;
|
||||
if (!mt->layout_3d) {
|
||||
offset += mt->layer_stride * layer;
|
||||
depth = 1;
|
||||
layer = 0;
|
||||
} else {
|
||||
depth = u_minify(mt->base.base.depth0, level);
|
||||
}
|
||||
|
||||
if (!(bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK)) {
|
||||
BEGIN_RING(chan, RING_2D_(mthd), 2);
|
||||
OUT_RING (chan, format);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_2D_(mthd + 0x14), 5);
|
||||
OUT_RING (chan, mt->level[ps->level].pitch);
|
||||
OUT_RING (chan, ps->width);
|
||||
OUT_RING (chan, ps->height);
|
||||
OUT_RELOCh(chan, bo, ps->offset, flags);
|
||||
OUT_RELOCl(chan, bo, ps->offset, flags);
|
||||
OUT_RING (chan, mt->level[level].pitch);
|
||||
OUT_RING (chan, width);
|
||||
OUT_RING (chan, height);
|
||||
OUT_RELOCh(chan, bo, offset, flags);
|
||||
OUT_RELOCl(chan, bo, offset, flags);
|
||||
} else {
|
||||
BEGIN_RING(chan, RING_2D_(mthd), 5);
|
||||
OUT_RING (chan, format);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, mt->level[ps->level].tile_mode);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, mt->level[level].tile_mode);
|
||||
OUT_RING (chan, depth);
|
||||
OUT_RING (chan, layer);
|
||||
BEGIN_RING(chan, RING_2D_(mthd + 0x18), 4);
|
||||
OUT_RING (chan, ps->width);
|
||||
OUT_RING (chan, ps->height);
|
||||
OUT_RELOCh(chan, bo, ps->offset, flags);
|
||||
OUT_RELOCl(chan, bo, ps->offset, flags);
|
||||
OUT_RING (chan, width);
|
||||
OUT_RING (chan, height);
|
||||
OUT_RELOCh(chan, bo, offset, flags);
|
||||
OUT_RELOCl(chan, bo, offset, flags);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
if (dst) {
|
||||
BEGIN_RING(chan, RING_2D_(NVC0_2D_CLIP_X), 4);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, surf->width);
|
||||
OUT_RING (chan, surf->height);
|
||||
OUT_RING (chan, width);
|
||||
OUT_RING (chan, height);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nvc0_surface_do_copy(struct nvc0_screen *screen,
|
||||
struct pipe_surface *dst, int dx, int dy,
|
||||
struct pipe_surface *src, int sx, int sy,
|
||||
int w, int h)
|
||||
nvc0_2d_texture_do_copy(struct nouveau_channel *chan,
|
||||
struct nvc0_miptree *dst, unsigned dst_level,
|
||||
unsigned dx, unsigned dy, unsigned dz,
|
||||
struct nvc0_miptree *src, unsigned src_level,
|
||||
unsigned sx, unsigned sy, unsigned sz,
|
||||
unsigned w, unsigned h)
|
||||
{
|
||||
struct nouveau_channel *chan = screen->base.channel;
|
||||
int ret;
|
||||
|
||||
ret = MARK_RING(chan, 2*16 + 32, 4);
|
||||
ret = MARK_RING(chan, 2 * 16 + 32, 4);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nvc0_surface_set(screen, dst, 1);
|
||||
ret = nvc0_2d_texture_set(chan, 1, dst, dst_level, dz);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nvc0_surface_set(screen, src, 0);
|
||||
ret = nvc0_2d_texture_set(chan, 0, src, src_level, sz);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -173,44 +188,44 @@ nvc0_surface_do_copy(struct nvc0_screen *screen,
|
|||
}
|
||||
|
||||
static void
|
||||
nvc0_surface_copy(struct pipe_context *pipe,
|
||||
struct pipe_resource *dest, struct pipe_subresource subdst,
|
||||
unsigned destx, unsigned desty, unsigned destz,
|
||||
struct pipe_resource *src, struct pipe_subresource subsrc,
|
||||
unsigned srcx, unsigned srcy, unsigned srcz,
|
||||
unsigned width, unsigned height)
|
||||
nvc0_resource_copy_region(struct pipe_context *pipe,
|
||||
struct pipe_resource *dst, unsigned dst_level,
|
||||
unsigned dstx, unsigned dsty, unsigned dstz,
|
||||
struct pipe_resource *src, unsigned src_level,
|
||||
const struct pipe_box *src_box)
|
||||
{
|
||||
struct nvc0_context *nv50 = nvc0_context(pipe);
|
||||
struct nvc0_screen *screen = nv50->screen;
|
||||
struct pipe_surface *ps_dst, *ps_src;
|
||||
struct nvc0_screen *screen = nvc0_context(pipe)->screen;
|
||||
int ret;
|
||||
unsigned dst_layer = dstz, src_layer = src_box->z;
|
||||
|
||||
assert((src->format == dest->format) ||
|
||||
assert((src->format == dst->format) ||
|
||||
(nvc0_2d_format_faithful(src->format) &&
|
||||
nvc0_2d_format_faithful(dest->format)));
|
||||
nvc0_2d_format_faithful(dst->format)));
|
||||
|
||||
ps_src = nvc0_miptree_surface_new(pipe->screen, src, subsrc.face,
|
||||
subsrc.level, srcz, 0 /* bind flags */);
|
||||
ps_dst = nvc0_miptree_surface_new(pipe->screen, dest, subdst.face,
|
||||
subdst.level, destz, 0 /* bind flags */);
|
||||
|
||||
nvc0_surface_do_copy(screen, ps_dst, destx, desty, ps_src, srcx,
|
||||
srcy, width, height);
|
||||
|
||||
nvc0_miptree_surface_del(ps_src);
|
||||
nvc0_miptree_surface_del(ps_dst);
|
||||
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,
|
||||
dstx, dsty, dst_layer,
|
||||
nvc0_miptree(src), src_level,
|
||||
src_box->x, src_box->y, src_layer,
|
||||
src_box->width, src_box->height);
|
||||
if (ret)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_clear_render_target(struct pipe_context *pipe,
|
||||
struct pipe_surface *dst,
|
||||
const float *rgba,
|
||||
unsigned dstx, unsigned dsty,
|
||||
unsigned width, unsigned height)
|
||||
struct pipe_surface *dst,
|
||||
const float *rgba,
|
||||
unsigned dstx, unsigned dsty,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
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 nouveau_bo *bo = mt->base.bo;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
|
||||
|
|
@ -225,12 +240,12 @@ nvc0_clear_render_target(struct pipe_context *pipe,
|
|||
BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(0)), 8);
|
||||
OUT_RELOCh(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RING (chan, dst->width);
|
||||
OUT_RING (chan, dst->height);
|
||||
OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RING (chan, sf->width);
|
||||
OUT_RING (chan, sf->height);
|
||||
OUT_RING (chan, nvc0_format_table[dst->format].rt);
|
||||
OUT_RING (chan, mt->level[dst->level].tile_mode);
|
||||
OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RING (chan, 0);
|
||||
|
||||
|
|
@ -259,6 +274,7 @@ nvc0_clear_depth_stencil(struct pipe_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 nouveau_bo *bo = mt->base.bo;
|
||||
uint32_t mode = 0;
|
||||
|
||||
|
|
@ -278,16 +294,16 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe,
|
|||
return;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
|
||||
OUT_RELOCh(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RING (chan, nvc0_format_table[dst->format].rt);
|
||||
OUT_RING (chan, mt->level[dst->level].tile_mode);
|
||||
OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
|
||||
OUT_RING (chan, dst->width);
|
||||
OUT_RING (chan, dst->height);
|
||||
OUT_RING (chan, sf->width);
|
||||
OUT_RING (chan, sf->height);
|
||||
OUT_RING (chan, (1 << 16) | 1);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
|
||||
|
|
@ -353,7 +369,7 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers,
|
|||
void
|
||||
nvc0_init_surface_functions(struct nvc0_context *nvc0)
|
||||
{
|
||||
nvc0->pipe.resource_copy_region = nvc0_surface_copy;
|
||||
nvc0->pipe.resource_copy_region = nvc0_resource_copy_region;
|
||||
nvc0->pipe.clear_render_target = nvc0_clear_render_target;
|
||||
nvc0->pipe.clear_depth_stencil = nvc0_clear_depth_stencil;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
|
|||
const struct util_format_description *desc;
|
||||
uint32_t *tic;
|
||||
uint32_t swz[4];
|
||||
uint32_t depth;
|
||||
struct nvc0_tic_entry *view;
|
||||
struct nvc0_miptree *mt = nvc0_miptree(texture);
|
||||
|
||||
|
|
@ -101,7 +102,9 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
|
|||
|
||||
tic[2] |=
|
||||
((mt->base.bo->tile_mode & 0x0f0) << (22 - 4)) |
|
||||
((mt->base.bo->tile_mode & 0xf00) << (21 - 4));
|
||||
((mt->base.bo->tile_mode & 0xf00) << (25 - 8));
|
||||
|
||||
depth = MAX2(mt->base.base.array_size, mt->base.base.depth0);
|
||||
|
||||
switch (mt->base.base.target) {
|
||||
case PIPE_TEXTURE_1D:
|
||||
|
|
@ -117,7 +120,17 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
|
|||
tic[2] |= NV50_TIC_2_TARGET_3D;
|
||||
break;
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
tic[2] |= NV50_TIC_2_TARGET_CUBE;
|
||||
depth /= 6;
|
||||
if (depth > 1)
|
||||
tic[2] |= NV50_TIC_2_TARGET_CUBE_ARRAY;
|
||||
else
|
||||
tic[2] |= NV50_TIC_2_TARGET_CUBE;
|
||||
break;
|
||||
case PIPE_TEXTURE_1D_ARRAY:
|
||||
tic[2] |= NV50_TIC_2_TARGET_1D_ARRAY;
|
||||
break;
|
||||
case PIPE_TEXTURE_2D_ARRAY:
|
||||
tic[2] |= NV50_TIC_2_TARGET_2D_ARRAY;
|
||||
break;
|
||||
case PIPE_BUFFER:
|
||||
tic[2] |= NV50_TIC_2_TARGET_BUFFER | /* NV50_TIC_2_LINEAR */ (1 << 18);
|
||||
|
|
@ -134,12 +147,12 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
|
|||
tic[4] = (1 << 31) | mt->base.base.width0;
|
||||
|
||||
tic[5] = mt->base.base.height0 & 0xffff;
|
||||
tic[5] |= mt->base.base.depth0 << 16;
|
||||
tic[5] |= depth << 16;
|
||||
tic[5] |= mt->base.base.last_level << 28;
|
||||
|
||||
tic[6] = 0x03000000;
|
||||
|
||||
tic[7] = (view->pipe.last_level << 4) | view->pipe.first_level;
|
||||
tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level;
|
||||
|
||||
return &view->pipe;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ nvc0_m2mf_push_rect(struct pipe_screen *pscreen,
|
|||
struct pipe_transfer *
|
||||
nvc0_miptree_transfer_new(struct pipe_context *pctx,
|
||||
struct pipe_resource *res,
|
||||
struct pipe_subresource sr,
|
||||
unsigned level,
|
||||
unsigned usage,
|
||||
const struct pipe_box *box)
|
||||
{
|
||||
|
|
@ -239,16 +239,21 @@ nvc0_miptree_transfer_new(struct pipe_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[sr.level];
|
||||
struct nvc0_miptree_level *lvl = &mt->level[level];
|
||||
struct nvc0_transfer *tx;
|
||||
uint32_t image;
|
||||
uint32_t w, h, z;
|
||||
uint32_t size;
|
||||
uint32_t w, h, d, z, layer;
|
||||
int ret;
|
||||
|
||||
if (res->target == PIPE_TEXTURE_CUBE)
|
||||
image = sr.face;
|
||||
else
|
||||
image = 0;
|
||||
if (mt->layout_3d) {
|
||||
z = box->z;
|
||||
d = u_minify(res->depth0, level);
|
||||
layer = 0;
|
||||
} else {
|
||||
z = 0;
|
||||
d = 1;
|
||||
layer = box->z;
|
||||
}
|
||||
|
||||
tx = CALLOC_STRUCT(nvc0_transfer);
|
||||
if (!tx)
|
||||
|
|
@ -256,7 +261,7 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx,
|
|||
|
||||
pipe_resource_reference(&tx->base.resource, res);
|
||||
|
||||
tx->base.sr = sr;
|
||||
tx->base.level = level;
|
||||
tx->base.usage = usage;
|
||||
tx->base.box = *box;
|
||||
|
||||
|
|
@ -265,30 +270,27 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx,
|
|||
|
||||
tx->base.stride = tx->nblocksx * util_format_get_blocksize(res->format);
|
||||
|
||||
w = u_minify(res->width0, sr.level);
|
||||
h = u_minify(res->height0, sr.level);
|
||||
w = u_minify(res->width0, level);
|
||||
h = u_minify(res->height0, level);
|
||||
|
||||
tx->rect[0].cpp = tx->rect[1].cpp = util_format_get_blocksize(res->format);
|
||||
|
||||
tx->rect[0].bo = mt->base.bo;
|
||||
tx->rect[0].base = lvl->image_offset[image];
|
||||
tx->rect[0].base = lvl->offset + layer * mt->layer_stride;
|
||||
tx->rect[0].tile_mode = lvl->tile_mode;
|
||||
tx->rect[0].x = util_format_get_nblocksx(res->format, box->x);
|
||||
tx->rect[0].y = util_format_get_nblocksx(res->format, box->y);
|
||||
tx->rect[0].z = box->z;
|
||||
tx->rect[0].y = util_format_get_nblocksy(res->format, box->y);
|
||||
tx->rect[0].z = z;
|
||||
tx->rect[0].width = util_format_get_nblocksx(res->format, w);
|
||||
tx->rect[0].height = util_format_get_nblocksx(res->format, h);
|
||||
tx->rect[0].depth = res->depth0;
|
||||
tx->rect[0].height = util_format_get_nblocksy(res->format, h);
|
||||
tx->rect[0].depth = d;
|
||||
tx->rect[0].pitch = lvl->pitch;
|
||||
tx->rect[0].domain = NOUVEAU_BO_VRAM;
|
||||
|
||||
if (!(usage & PIPE_TRANSFER_READ) &&
|
||||
(res->depth0 == 1) && (tx->nblocksy * tx->base.stride < 512 * 4)) {
|
||||
/* don't allocate scratch buffer, upload through FIFO */
|
||||
}
|
||||
size = tx->nblocksy * tx->base.stride;
|
||||
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
|
||||
tx->nblocksy * tx->base.stride, &tx->rect[1].bo);
|
||||
size * tx->base.box.depth, &tx->rect[1].bo);
|
||||
if (ret) {
|
||||
FREE(tx);
|
||||
return NULL;
|
||||
|
|
@ -296,18 +298,23 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx,
|
|||
|
||||
tx->rect[1].width = tx->nblocksx;
|
||||
tx->rect[1].height = tx->nblocksy;
|
||||
tx->rect[1].depth = box->depth;
|
||||
tx->rect[1].depth = 1;
|
||||
tx->rect[1].pitch = tx->base.stride;
|
||||
tx->rect[1].domain = NOUVEAU_BO_GART;
|
||||
|
||||
if (usage & PIPE_TRANSFER_READ) {
|
||||
for (z = 0; z < box->depth; ++z) {
|
||||
unsigned i;
|
||||
for (i = 0; i < box->depth; ++i) {
|
||||
nvc0_m2mf_transfer_rect(pscreen, &tx->rect[1], &tx->rect[0],
|
||||
tx->nblocksx, tx->nblocksy);
|
||||
tx->rect[0].z++;
|
||||
if (mt->layout_3d)
|
||||
tx->rect[0].z++;
|
||||
else
|
||||
tx->rect[0].base += mt->layer_stride;
|
||||
tx->rect[1].base += size;
|
||||
}
|
||||
}
|
||||
tx->rect[0].z = box->z;
|
||||
tx->rect[0].z = z;
|
||||
|
||||
return &tx->base;
|
||||
}
|
||||
|
|
@ -318,13 +325,18 @@ nvc0_miptree_transfer_del(struct pipe_context *pctx,
|
|||
{
|
||||
struct pipe_screen *pscreen = pctx->screen;
|
||||
struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
|
||||
unsigned z;
|
||||
struct nvc0_miptree *mt = nvc0_miptree(tx->base.resource);
|
||||
unsigned i;
|
||||
|
||||
if (tx->base.usage & PIPE_TRANSFER_WRITE) {
|
||||
for (z = 0; z < tx->base.box.depth; ++z) {
|
||||
for (i = 0; i < tx->base.box.depth; ++i) {
|
||||
nvc0_m2mf_transfer_rect(pscreen, &tx->rect[0], &tx->rect[1],
|
||||
tx->nblocksx, tx->nblocksy);
|
||||
tx->rect[0].z++;
|
||||
if (mt->layout_3d)
|
||||
tx->rect[0].z++;
|
||||
else
|
||||
tx->rect[0].base += mt->layer_stride;
|
||||
tx->rect[1].base += tx->nblocksy * tx->base.stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
struct pipe_transfer *
|
||||
nvc0_miptree_transfer_new(struct pipe_context *pcontext,
|
||||
struct pipe_resource *pt,
|
||||
struct pipe_subresource sr,
|
||||
unsigned level,
|
||||
unsigned usage,
|
||||
const struct pipe_box *box);
|
||||
void
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue