summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nvc0
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2013-04-06 14:52:05 +0200
committerChristoph Bumiller <[email protected]>2013-04-12 13:02:18 +0200
commit4da54c91d24da891c56957f29274e7821c8254f6 (patch)
tree8bd4fa434f7494a3bc9049d7304f49bb8dd7f264 /src/gallium/drivers/nvc0
parent71c1c8a9b89ca1ecca1857c53cd8c648c9c9a871 (diff)
nvc0: implement multisample textures
Diffstat (limited to 'src/gallium/drivers/nvc0')
-rw-r--r--src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp5
-rw-r--r--src/gallium/drivers/nvc0/nvc0_context.c46
-rw-r--r--src/gallium/drivers/nvc0/nvc0_miptree.c2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.c2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_surface.c1
-rw-r--r--src/gallium/drivers/nvc0/nvc0_tex.c36
6 files changed, 73 insertions, 19 deletions
diff --git a/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp
index c459d60759b..4d1d37281bc 100644
--- a/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp
+++ b/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp
@@ -662,6 +662,7 @@ NVC0LoweringPass::handleTEX(TexInstruction *i)
{
const int dim = i->tex.target.getDim() + i->tex.target.isCube();
const int arg = i->tex.target.getArgCount();
+ const int lyr = arg - (i->tex.target.isMS() ? 2 : 1);
if (prog->getTarget()->getChipset() >= NVISA_GK104_CHIPSET) {
if (i->tex.rIndirectSrc >= 0 || i->tex.sIndirectSrc >= 0) {
@@ -683,7 +684,7 @@ NVC0LoweringPass::handleTEX(TexInstruction *i)
}
if (i->tex.target.isArray()) {
LValue *layer = new_LValue(func, FILE_GPR);
- Value *src = i->getSrc(arg - 1);
+ Value *src = i->getSrc(lyr);
const int sat = (i->op == OP_TXF) ? 1 : 0;
DataType sTy = (i->op == OP_TXF) ? TYPE_U32 : TYPE_F32;
bld.mkCvt(OP_CVT, TYPE_U16, layer, sTy, src)->saturate = sat;
@@ -696,7 +697,7 @@ NVC0LoweringPass::handleTEX(TexInstruction *i)
if (dim != arg || i->tex.rIndirectSrc >= 0 || i->tex.sIndirectSrc >= 0) {
LValue *src = new_LValue(func, FILE_GPR); // 0xttxsaaaa
- Value *arrayIndex = i->tex.target.isArray() ? i->getSrc(arg - 1) : NULL;
+ Value *arrayIndex = i->tex.target.isArray() ? i->getSrc(lyr) : NULL;
for (int s = dim; s >= 1; --s)
i->setSrc(s, i->getSrc(s - 1));
i->setSrc(0, arrayIndex);
diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c
index 12b890d9c0d..10baab5b335 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nvc0/nvc0_context.c
@@ -214,6 +214,10 @@ nvc0_invalidate_resource_storage(struct nouveau_context *ctx,
return ref;
}
+static void
+nvc0_context_get_sample_position(struct pipe_context *, unsigned, unsigned,
+ float *);
+
struct pipe_context *
nvc0_create(struct pipe_screen *pscreen, void *priv)
{
@@ -259,6 +263,7 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
pipe->flush = nvc0_flush;
pipe->texture_barrier = nvc0_texture_barrier;
+ pipe->get_sample_position = nvc0_context_get_sample_position;
if (!screen->cur_ctx) {
screen->cur_ctx = nvc0;
@@ -353,3 +358,44 @@ nvc0_bufctx_fence(struct nvc0_context *nvc0, struct nouveau_bufctx *bufctx,
}
NOUVEAU_DRV_STAT(&nvc0->screen->base, resource_validate_count, count);
}
+
+static void
+nvc0_context_get_sample_position(struct pipe_context *pipe,
+ unsigned sample_count, unsigned sample_index,
+ float *xy)
+{
+ static const uint8_t ms1[1][2] = { { 0x8, 0x8 } };
+ static const uint8_t ms2[2][2] = {
+ { 0x4, 0x4 }, { 0xc, 0xc } }; /* surface coords (0,0), (1,0) */
+ static const uint8_t ms4[4][2] = {
+ { 0x6, 0x2 }, { 0xe, 0x6 }, /* (0,0), (1,0) */
+ { 0x2, 0xa }, { 0xa, 0xe } }; /* (0,1), (1,1) */
+ static const uint8_t ms8[8][2] = {
+ { 0x1, 0x7 }, { 0x5, 0x3 }, /* (0,0), (1,0) */
+ { 0x3, 0xd }, { 0x7, 0xb }, /* (0,1), (1,1) */
+ { 0x9, 0x5 }, { 0xf, 0x1 }, /* (2,0), (3,0) */
+ { 0xb, 0xf }, { 0xd, 0x9 } }; /* (2,1), (3,1) */
+#if 0
+ /* NOTE: there are alternative modes for MS2 and MS8, currently not used */
+ static const uint8_t ms8_alt[8][2] = {
+ { 0x9, 0x5 }, { 0x7, 0xb }, /* (2,0), (1,1) */
+ { 0xd, 0x9 }, { 0x5, 0x3 }, /* (3,1), (1,0) */
+ { 0x3, 0xd }, { 0x1, 0x7 }, /* (0,1), (0,0) */
+ { 0xb, 0xf }, { 0xf, 0x1 } }; /* (2,1), (3,0) */
+#endif
+
+ const uint8_t (*ptr)[2];
+
+ switch (sample_count) {
+ case 0:
+ case 1: ptr = ms1; break;
+ case 2: ptr = ms2; break;
+ case 4: ptr = ms4; break;
+ case 8: ptr = ms8; break;
+ default:
+ assert(0);
+ break;
+ }
+ xy[0] = ptr[sample_index][0] * 0.0625f;
+ xy[1] = ptr[sample_index][1] * 0.0625f;
+}
diff --git a/src/gallium/drivers/nvc0/nvc0_miptree.c b/src/gallium/drivers/nvc0/nvc0_miptree.c
index 3d50735c058..ec2ab5f38f9 100644
--- a/src/gallium/drivers/nvc0/nvc0_miptree.c
+++ b/src/gallium/drivers/nvc0/nvc0_miptree.c
@@ -197,6 +197,8 @@ nvc0_miptree_init_layout_tiled(struct nv50_miptree *mt)
*/
d = mt->layout_3d ? pt->depth0 : 1;
+ assert(!mt->ms_mode || !pt->last_level);
+
for (l = 0; l <= pt->last_level; ++l) {
struct nv50_miptree_level *lvl = &mt->level[l];
unsigned tsx, tsy, tsz;
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index f2dd65ba0ca..ccdf2cde84b 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -102,6 +102,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_SEAMLESS_CUBE_MAP:
case PIPE_CAP_CUBE_MAP_ARRAY:
case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
+ case PIPE_CAP_TEXTURE_MULTISAMPLE:
return 1;
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
@@ -170,7 +171,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
- case PIPE_CAP_TEXTURE_MULTISAMPLE:
return 0;
case PIPE_CAP_COMPUTE:
return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c
index 4e8bb36e18f..394f196241c 100644
--- a/src/gallium/drivers/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nvc0/nvc0_surface.c
@@ -636,6 +636,7 @@ nvc0_blit_set_src(struct nvc0_blitctx *ctx,
}
flags = res->last_level ? 0 : NV50_TEXVIEW_SCALED_COORDS;
+ flags |= NV50_TEXVIEW_ACCESS_RESOLVE;
if (filter && res->nr_samples == 8)
flags |= NV50_TEXVIEW_FILTER_MSAA8;
diff --git a/src/gallium/drivers/nvc0/nvc0_tex.c b/src/gallium/drivers/nvc0/nvc0_tex.c
index ffd285473a9..c11d3f791fe 100644
--- a/src/gallium/drivers/nvc0/nvc0_tex.c
+++ b/src/gallium/drivers/nvc0/nvc0_tex.c
@@ -78,6 +78,7 @@ nvc0_create_texture_view(struct pipe_context *pipe,
uint64_t address;
uint32_t *tic;
uint32_t swz[4];
+ uint32_t width, height;
uint32_t depth;
struct nv50_tic_entry *view;
struct nv50_miptree *mt;
@@ -168,7 +169,6 @@ nvc0_create_texture_view(struct pipe_context *pipe,
case PIPE_TEXTURE_1D:
tic[2] |= NV50_TIC_2_TARGET_1D;
break;
-/* case PIPE_TEXTURE_2D_MS: */
case PIPE_TEXTURE_2D:
tic[2] |= NV50_TIC_2_TARGET_2D;
break;
@@ -185,7 +185,6 @@ nvc0_create_texture_view(struct pipe_context *pipe,
case PIPE_TEXTURE_1D_ARRAY:
tic[2] |= NV50_TIC_2_TARGET_1D_ARRAY;
break;
-/* case PIPE_TEXTURE_2D_ARRAY_MS: */
case PIPE_TEXTURE_2D_ARRAY:
tic[2] |= NV50_TIC_2_TARGET_2D_ARRAY;
break;
@@ -194,30 +193,35 @@ nvc0_create_texture_view(struct pipe_context *pipe,
tic[2] |= NV50_TIC_2_TARGET_CUBE_ARRAY;
break;
default:
- NOUVEAU_ERR("invalid texture target: %d\n", mt->base.base.target);
+ NOUVEAU_ERR("unexpected/invalid texture target: %d\n",
+ mt->base.base.target);
return FALSE;
}
- if (mt->base.base.target == PIPE_BUFFER)
- tic[3] = mt->base.base.width0;
- else
- tic[3] = (flags & NV50_TEXVIEW_FILTER_MSAA8) ? 0x20000000 : 0x00300000;
+ tic[3] = (flags & NV50_TEXVIEW_FILTER_MSAA8) ? 0x20000000 : 0x00300000;
+
+ if (flags & NV50_TEXVIEW_ACCESS_RESOLVE) {
+ width = mt->base.base.width0 << mt->ms_x;
+ height = mt->base.base.height0 << mt->ms_y;
+ } else {
+ width = mt->base.base.width0;
+ height = mt->base.base.height0;
+ }
- tic[4] = (1 << 31) | (mt->base.base.width0 << mt->ms_x);
+ tic[4] = (1 << 31) | width;
- tic[5] = (mt->base.base.height0 << mt->ms_y) & 0xffff;
+ tic[5] = height & 0xffff;
tic[5] |= depth << 16;
tic[5] |= mt->base.base.last_level << 28;
- tic[6] = (mt->ms_x > 1) ? 0x88000000 : 0x03000000; /* sampling points */
+ /* sampling points: (?) */
+ if (flags & NV50_TEXVIEW_ACCESS_RESOLVE)
+ tic[6] = (mt->ms_x > 1) ? 0x88000000 : 0x03000000;
+ else
+ tic[6] = 0x03000000;
tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level;
-
- /*
- if (mt->base.base.target == PIPE_TEXTURE_2D_MS ||
- mt->base.base.target == PIPE_TEXTURE_2D_ARRAY_MS)
- tic[7] |= mt->ms_mode << 12;
- */
+ tic[7] |= mt->ms_mode << 12;
return &view->pipe;
}