aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2011-07-14 12:40:04 +0200
committerChristoph Bumiller <[email protected]>2011-07-14 12:51:06 +0200
commitcad17554c4b121c03e188dd0281718a52d603a15 (patch)
treef22e0d7feb5ac3323a659465cef71a16e83705e4 /src
parentebeec1d43a7c7b2542ed76326dd3b1814ca47dc8 (diff)
nv50,nvc0: unify nvc0_miptree and nv50_miptree structs
Share some functions and restructure miptree creation a little. Prepare for multi-sample resources.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h14
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c350
-rw-r--r--src/gallium/drivers/nv50/nv50_resource.h65
-rw-r--r--src/gallium/drivers/nvc0/nvc0_3d.xml.h18
-rw-r--r--src/gallium/drivers/nvc0/nvc0_context.h14
-rw-r--r--src/gallium/drivers/nvc0/nvc0_miptree.c368
-rw-r--r--src/gallium/drivers/nvc0/nvc0_resource.c12
-rw-r--r--src/gallium/drivers/nvc0/nvc0_resource.h64
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.c2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.h1
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state_validate.c12
-rw-r--r--src/gallium/drivers/nvc0/nvc0_surface.c30
-rw-r--r--src/gallium/drivers/nvc0/nvc0_tex.c4
-rw-r--r--src/gallium/drivers/nvc0/nvc0_transfer.c6
14 files changed, 535 insertions, 425 deletions
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index b4af24f6bce..4e141a6c1e5 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -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 *);
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index 486b368ae98..0a1fcbc3e92 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -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;
+
+ if (mt->base.base.bind & PIPE_BIND_CURSOR)
+ return NOUVEAU_BO_TILE_SCANOUT;
- return (z & (tile_d - 1)) * stride_2d + (z >> tile_d_shift) * stride_3d;
+ 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)
{
- 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;
-
- mt->base.vtbl = &nv50_miptree_vtbl;
- *pt = *templ;
- pipe_reference_init(&pt->reference, 1);
- pt->screen = pscreen;
-
- 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;
+ 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 PIPE_FORMAT_Z24X8_UNORM:
- case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
- tile_flags = 0x2800;
+ case 4:
+ mt->ms_mode = NV50_3D_MULTISAMPLE_MODE_MS4;
+ mt->ms_x = 1;
+ mt->ms_y = 1;
break;
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- case PIPE_FORMAT_R32G32B32_FLOAT:
- tile_flags = 0x7400;
+ case 2:
+ mt->ms_mode = NV50_3D_MULTISAMPLE_MODE_MS2;
+ mt->ms_x = 1;
break;
- case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
- tile_flags = 0x6000;
+ case 1:
+ case 0:
+ mt->ms_mode = NV50_3D_MULTISAMPLE_MODE_MS1;
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;
+ NOUVEAU_ERR("invalid nr_samples: %u\n", mt->base.base.nr_samples);
+ return FALSE;
}
- if (pt->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_CURSOR))
- tile_flags |= NOUVEAU_BO_TILE_SCANOUT;
+ return TRUE;
+}
+
+boolean
+nv50_miptree_init_layout_linear(struct nv50_miptree *mt)
+{
+ struct pipe_resource *pt = &mt->base.base;
+
+ if (util_format_is_depth_or_stencil(pt->format))
+ return FALSE;
+
+ 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 << 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;
}
+}
+
+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;
+
+ 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;
+ }
- alloc_size = mt->total_size;
+ 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, 256, alloc_size,
+ 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;
+
+ return ns;
+}
+
+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;
- /* 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);
+ if (mt->layout_3d) {
+ ns->offset += nv50_mt_zslice_offset(mt, l, z);
- 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;
+ 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
diff --git a/src/gallium/drivers/nv50/nv50_resource.h b/src/gallium/drivers/nv50/nv50_resource.h
index 0e9f0a2557e..a771edf4095 100644
--- a/src/gallium/drivers/nv50/nv50_resource.h
+++ b/src/gallium/drivers/nv50/nv50_resource.h
@@ -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_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__ */
-#define NV50_TILE_SIZE_2D(m) ((64 * 4) << \
- NV50_TILE_DIM_SHIFT(m, 0))
+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__ */
diff --git a/src/gallium/drivers/nvc0/nvc0_3d.xml.h b/src/gallium/drivers/nvc0/nvc0_3d.xml.h
index 2ca0bc23836..6fba20cd2db 100644
--- a/src/gallium/drivers/nvc0/nvc0_3d.xml.h
+++ b/src/gallium/drivers/nvc0/nvc0_3d.xml.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
diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h
index b05cc337d5d..e59209176e0 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nvc0/nvc0_context.h
@@ -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 *);
diff --git a/src/gallium/drivers/nvc0/nvc0_miptree.c b/src/gallium/drivers/nvc0/nvc0_miptree.c
index bced3245524..5da73df2d9b 100644
--- a/src/gallium/drivers/nvc0/nvc0_miptree.c
+++ b/src/gallium/drivers/nvc0/nvc0_miptree.c
@@ -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,66 +57,182 @@ 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 */
+ uint32_t tile_flags;
- unsigned tile_d_shift = NVC0_TILE_DIM_SHIFT(mt->level[l].tile_mode, 2);
- unsigned tile_d = 1 << tile_d_shift;
+ compressed = FALSE; /* not yet supported */
- nblocksy = util_format_get_nblocksy(mt->base.base.format,
- u_minify(mt->base.base.height0, l));
+ if (mt->base.base.bind & PIPE_BIND_CURSOR)
+ return NOUVEAU_BO_TILE_SCANOUT;
- nblocksy = align(nblocksy, NVC0_TILE_HEIGHT(mt->level[l].tile_mode));
+ switch (mt->base.base.format) {
+ case PIPE_FORMAT_Z16_UNORM:
+ if (compressed)
+ tile_flags = 0x0200 + (ms << 8);
+ else
+ tile_flags = 0x0100;
+ break;
+ case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
+ if (compressed)
+ tile_flags = 0x5100 + (ms << 8);
+ else
+ tile_flags = 0x4600;
+ break;
+ case PIPE_FORMAT_Z24X8_UNORM:
+ case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+ if (compressed)
+ tile_flags = 0x1700 + (ms << 8);
+ else
+ tile_flags = 0x1100;
+ break;
+ case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
+ if (compressed)
+ tile_flags = 0xce00 + (ms << 8);
+ else
+ tile_flags = 0xc300;
+ break;
+ default:
+ 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;
+ }
- stride_2d = NVC0_TILE_SIZE_2D(mt->level[l].tile_mode);
+ if (mt->base.base.bind & PIPE_BIND_SCANOUT)
+ tile_flags |= NOUVEAU_BO_TILE_SCANOUT;
- stride_3d = (nblocksy * mt->level[l].pitch) << tile_d_shift;
+ return tile_flags;
+}
- return (z & (tile_d - 1)) * stride_2d + (z >> tile_d_shift) * stride_3d;
+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_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt)
+nvc0_miptree_init_layout_tiled(struct nv50_miptree *mt)
{
- struct nvc0_miptree *mt = nvc0_miptree(pt);
+ struct pipe_resource *pt = &mt->base.base;
+ unsigned w, h, d, l;
+ const unsigned blocksize = util_format_get_blocksize(pt->format);
- nouveau_screen_bo_release(pscreen, mt->base.bo);
+ mt->layout_3d = pt->target == PIPE_TEXTURE_3D;
- FREE(mt);
-}
+ w = pt->width0 << mt->ms_x;
+ h = pt->height0 << mt->ms_y;
-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;
+ /* 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;
- if (!mt || !mt->base.bo)
- return FALSE;
+ 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);
+
+ lvl->offset = mt->total_size;
+
+ 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);
- stride = util_format_get_stride(mt->base.base.format,
- mt->base.base.width0);
+ mt->total_size += lvl->pitch * align(nby, tsy) * align(d, tsz);
- return nouveau_screen_bo_get_handle(pscreen,
- mt->base.bo,
- stride,
- whandle);
+ w = u_minify(w, 1);
+ h = u_minify(h, 1);
+ d = u_minify(d, 1);
+ }
+
+ 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;
+ }
}
const struct u_resource_vtbl nvc0_miptree_vtbl =
{
- nvc0_miptree_get_handle, /* get_handle */
- nvc0_miptree_destroy, /* resource_destroy */
+ 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 */
+ 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 */
@@ -127,10 +243,9 @@ 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 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)
@@ -141,84 +256,23 @@ 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 = mt->layout_3d ? pt->depth0 : 1;
+ tile_flags = nvc0_mt_choose_storage_type(mt, TRUE);
- switch (pt->format) {
- case PIPE_FORMAT_Z16_UNORM:
- tile_flags = 0x0700; /* COMPRESSED */
- tile_flags = 0x0100; /* NORMAL */
- break;
- case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
- tile_flags = 0x5300; /* MSAA 4, COMPRESSED */
- tile_flags = 0x4600; /* NORMAL */
- 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 */
- 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 */
- 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 */
- break;
- }
-
- /* 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->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);
+ if (!nvc0_miptree_init_ms_mode(mt)) {
+ FREE(mt);
+ return NULL;
}
- 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;
+ 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;
}
- alloc_size = mt->total_size;
- if (tile_flags == 0x1700)
- alloc_size *= 3; /* HiZ, XXX: correct size */
-
- ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 256, alloc_size,
+ 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,44 +284,26 @@ 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;
-
- /* 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;
+ const struct pipe_resource *pt = &mt->base.base;
- mt = CALLOC_STRUCT(nvc0_miptree);
- if (!mt)
- 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->base.bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride);
- if (mt->base.bo == NULL) {
- FREE(mt);
- return NULL;
- }
+ unsigned nby = util_format_get_nblocksy(pt->format,
+ u_minify(pt->height0, l));
- 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;
-
- /* no need to adjust bo reference count */
- return &mt->base.base;
-}
+ /* to next 2D tile slice within a 3D tile */
+ unsigned stride_2d = NVC0_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.
*/
@@ -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;
}
diff --git a/src/gallium/drivers/nvc0/nvc0_resource.c b/src/gallium/drivers/nvc0/nvc0_resource.c
index 44e66314e7e..a0289728ee9 100644
--- a/src/gallium/drivers/nvc0/nvc0_resource.c
+++ b/src/gallium/drivers/nvc0/nvc0_resource.c
@@ -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
diff --git a/src/gallium/drivers/nvc0/nvc0_resource.h b/src/gallium/drivers/nvc0/nvc0_resource.h
index f1c445b5152..d699895729d 100644
--- a/src/gallium/drivers/nvc0/nvc0_resource.h
+++ b/src/gallium/drivers/nvc0/nvc0_resource.h
@@ -2,53 +2,29 @@
#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"
-void
-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_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_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_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))
-#define NVC0_TILE_SIZE_2D(m) (((64 * 8) << \
- NVC0_TILE_DIM_SHIFT(m, 0)) << \
- NVC0_TILE_DIM_SHIFT(m, 1))
+/* it's ok to mask only in the end because max value is 3 * 5 */
-#define NVC0_TILE_SIZE(m) (NVC0_TILE_SIZE_2D(m) << NVC0_TILE_DIM_SHIFT(m, 2))
+#define NVC0_TILE_SIZE_2D(m) ((64 * 8) << (((m) + ((m) >> 4)) & 0xf))
-struct nvc0_miptree_level {
- uint32_t offset;
- uint32_t pitch;
- uint32_t tile_mode;
-};
+#define NVC0_TILE_SIZE(m) ((64 * 8) << (((m) + ((m) >> 4) + ((m) >> 8)) & 0xf))
-#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 */
-};
+void
+nvc0_init_resource_functions(struct pipe_context *pcontext);
-static INLINE struct nvc0_miptree *
-nvc0_miptree(struct pipe_resource *pt)
-{
- return (struct nvc0_miptree *)pt;
-}
+void
+nvc0_screen_init_resource_functions(struct pipe_screen *pscreen);
/* Internal functions:
*/
@@ -56,20 +32,14 @@ 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
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index 1bd7fa9f0ea..a2e45b16745 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -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);
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h b/src/gallium/drivers/nvc0/nvc0_screen.h
index 015807e2f5d..a3133b28876 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nvc0/nvc0_screen.h
@@ -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"
diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c
index f300f37fb7b..bd40a231cde 100644
--- a/src/gallium/drivers/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c
@@ -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;
diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c
index 6be3702bddc..e1e4c303b12 100644
--- a/src/gallium/drivers/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nvc0/nvc0_surface.c
@@ -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;
diff --git a/src/gallium/drivers/nvc0/nvc0_tex.c b/src/gallium/drivers/nvc0/nvc0_tex.c
index 24850b19986..4b82fdf05f9 100644
--- a/src/gallium/drivers/nvc0/nvc0_tex.c
+++ b/src/gallium/drivers/nvc0/nvc0_tex.c
@@ -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];
diff --git a/src/gallium/drivers/nvc0/nvc0_transfer.c b/src/gallium/drivers/nvc0/nvc0_transfer.c
index 0509113e005..1170f12da13 100644
--- a/src/gallium/drivers/nvc0/nvc0_transfer.c
+++ b/src/gallium/drivers/nvc0/nvc0_transfer.c
@@ -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) {