summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlia Mirkin <imirkin@alum.mit.edu>2015-12-30 14:50:02 -0500
committerIlia Mirkin <imirkin@alum.mit.edu>2015-12-30 16:55:57 -0500
commit517a93b346e720082e22e358b63b5dbc5c42aa09 (patch)
tree70f55702a294779c01624c9dff9d0859ef9cf0a9
parent89bda9772d5b6f736d5f18e90a1ee4056438fe42 (diff)
nvc0: add ARB_shader_draw_parameters support
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
-rw-r--r--docs/relnotes/11.2.0.html1
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir.h3
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h4
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp10
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp11
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp3
-rw-r--r--src/gallium/drivers/nouveau/nouveau_compiler.c2
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_program.c2
-rw-r--r--src/gallium/drivers/nouveau/nvc0/mme/com9097.mme8
-rw-r--r--src/gallium/drivers/nouveau/nvc0/mme/com9097.mme.h18
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_program.c4
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_program.h1
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_screen.c2
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c20
14 files changed, 74 insertions, 15 deletions
diff --git a/docs/relnotes/11.2.0.html b/docs/relnotes/11.2.0.html
index 23bb31c6235..d31da8ba4a6 100644
--- a/docs/relnotes/11.2.0.html
+++ b/docs/relnotes/11.2.0.html
@@ -47,6 +47,7 @@ Note: some of the new features are only available with certain drivers.
<li>GL_ARB_base_instance on freedreno/a4xx</li>
<li>GL_ARB_compute_shader on i965</li>
<li>GL_ARB_copy_image on r600</li>
+<li>GL_ARB_shader_draw_parameters on i965, nvc0</li>
<li>GL_ARB_tessellation_shader on i965 and r600 (evergreen/cayman only)</li>
<li>GL_ARB_texture_buffer_object_rgb32 on freedreno/a4xx</li>
<li>GL_ARB_texture_buffer_range on freedreno/a4xx</li>
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir.h b/src/gallium/drivers/nouveau/codegen/nv50_ir.h
index d09a0ab0610..d1fdd75495f 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir.h
@@ -390,6 +390,9 @@ enum SVSemantic
SV_VERTEX_STRIDE,
SV_INVOCATION_INFO,
SV_THREAD_KILL,
+ SV_BASEVERTEX,
+ SV_BASEINSTANCE,
+ SV_DRAWID,
SV_UNDEFINED,
SV_LAST
};
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
index b49bf9d53bc..4504240ac5e 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
@@ -124,6 +124,7 @@ struct nv50_ir_prog_info
union {
struct {
uint32_t inputMask[4]; /* mask of attributes read (1 bit per scalar) */
+ bool usesDrawParameters;
} vp;
struct {
uint8_t inputPatchSize;
@@ -160,8 +161,9 @@ struct nv50_ir_prog_info
uint8_t clipDistances; /* number of clip distance outputs */
uint8_t cullDistances; /* number of cull distance outputs */
int8_t genUserClip; /* request user clip planes for ClipVertex */
+ uint8_t auxCBSlot; /* constant buffer index of UCP/draw data */
uint16_t ucpBase; /* base address for UCPs */
- uint8_t ucpCBSlot; /* constant buffer index of UCP data */
+ uint16_t drawInfoBase; /* base address for draw parameters */
uint8_t pointSize; /* output index for PointSize */
uint8_t instanceId; /* system value index of InstanceID */
uint8_t vertexId; /* system value index of VertexID */
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
index b23386040a7..beb67fe20f1 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
@@ -377,6 +377,9 @@ static nv50_ir::SVSemantic translateSysVal(uint sysval)
case TGSI_SEMANTIC_TESSINNER: return nv50_ir::SV_TESS_INNER;
case TGSI_SEMANTIC_VERTICESIN: return nv50_ir::SV_VERTEX_COUNT;
case TGSI_SEMANTIC_HELPER_INVOCATION: return nv50_ir::SV_THREAD_KILL;
+ case TGSI_SEMANTIC_BASEVERTEX: return nv50_ir::SV_BASEVERTEX;
+ case TGSI_SEMANTIC_BASEINSTANCE: return nv50_ir::SV_BASEINSTANCE;
+ case TGSI_SEMANTIC_DRAWID: return nv50_ir::SV_DRAWID;
default:
assert(0);
return nv50_ir::SV_CLOCK;
@@ -1128,6 +1131,11 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl)
case TGSI_SEMANTIC_SAMPLEPOS:
info->prop.fp.sampleInterp = 1;
break;
+ case TGSI_SEMANTIC_BASEVERTEX:
+ case TGSI_SEMANTIC_BASEINSTANCE:
+ case TGSI_SEMANTIC_DRAWID:
+ info->prop.vp.usesDrawParameters = true;
+ break;
default:
break;
}
@@ -3252,7 +3260,7 @@ Converter::handleUserClipPlanes()
for (c = 0; c < 4; ++c) {
for (i = 0; i < info->io.genUserClip; ++i) {
- Symbol *sym = mkSymbol(FILE_MEMORY_CONST, info->io.ucpCBSlot,
+ Symbol *sym = mkSymbol(FILE_MEMORY_CONST, info->io.auxCBSlot,
TYPE_F32, info->io.ucpBase + i * 16 + c * 4);
Value *ucp = mkLoadv(TYPE_F32, sym, NULL);
if (c == 0)
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
index e67bf3eca84..6530078b938 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
@@ -1576,6 +1576,17 @@ NVC0LoweringPass::handleRDSV(Instruction *i)
ld = bld.mkOp1(OP_PIXLD, TYPE_U32, i->getDef(0), bld.mkImm(0));
ld->subOp = NV50_IR_SUBOP_PIXLD_COVMASK;
break;
+ case SV_BASEVERTEX:
+ case SV_BASEINSTANCE:
+ case SV_DRAWID:
+ ld = bld.mkLoad(TYPE_U32, i->getDef(0),
+ bld.mkSymbol(FILE_MEMORY_CONST,
+ prog->driver->io.auxCBSlot,
+ TYPE_U32,
+ prog->driver->io.drawInfoBase +
+ 4 * (sv - SV_BASEVERTEX)),
+ NULL);
+ break;
default:
if (prog->getType() == Program::TYPE_TESSELLATION_EVAL && !i->perPatch)
vtx = bld.mkOp1v(OP_PFETCH, TYPE_U32, bld.getSSA(), bld.mkImm(0));
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
index 19637ce33f5..014c652eede 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
@@ -295,6 +295,9 @@ TargetNVC0::getSVAddress(DataFile shaderFile, const Symbol *sym) const
case SV_SAMPLE_INDEX: return 0;
case SV_SAMPLE_POS: return 0;
case SV_SAMPLE_MASK: return 0;
+ case SV_BASEVERTEX: return 0;
+ case SV_BASEINSTANCE: return 0;
+ case SV_DRAWID: return 0;
default:
return 0xffffffff;
}
diff --git a/src/gallium/drivers/nouveau/nouveau_compiler.c b/src/gallium/drivers/nouveau/nouveau_compiler.c
index 670b0c8b135..cd44aa1e1d9 100644
--- a/src/gallium/drivers/nouveau/nouveau_compiler.c
+++ b/src/gallium/drivers/nouveau/nouveau_compiler.c
@@ -112,7 +112,7 @@ nouveau_codegen(int chipset, int type, struct tgsi_token tokens[],
info.bin.sourceRep = NV50_PROGRAM_IR_TGSI;
info.bin.source = tokens;
- info.io.ucpCBSlot = 15;
+ info.io.auxCBSlot = 15;
info.io.ucpBase = NV50_CB_AUX_UCP_OFFSET;
info.io.resInfoCBSlot = 15;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_program.c b/src/gallium/drivers/nouveau/nv50/nv50_program.c
index a4b8ddfda95..b63584e0a09 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_program.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_program.c
@@ -335,7 +335,7 @@ nv50_program_translate(struct nv50_program *prog, uint16_t chipset,
info->bin.sourceRep = NV50_PROGRAM_IR_TGSI;
info->bin.source = (void *)prog->pipe.tokens;
- info->io.ucpCBSlot = 15;
+ info->io.auxCBSlot = 15;
info->io.ucpBase = NV50_CB_AUX_UCP_OFFSET;
info->io.genUserClip = prog->vp.clpd_nr;
diff --git a/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme b/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme
index b2060d1fa53..8c647d0c66c 100644
--- a/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme
+++ b/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme
@@ -241,8 +241,10 @@ locn_0f_ts:
parm $r2 /* instance_count */
parm $r4 maddr 0x5f7 /* INDEX_BATCH_FIRST, start */
parm $r4 send $r4 /* index_bias, send start */
+ maddr 0x8e4 /* CB_DATA */
braz $r2 #dei_end
- parm $r5 /* start_instance */
+ parm $r5 send $r4 /* start_instance, send index_bias */
+ send $r5 /* send start_instance */
read $r6 0x50d /* VB_ELEMENT_BASE */
read $r7 0x50e /* VB_INSTANCE_BASE */
maddr 0x150d /* VB_ELEMENT,INSTANCE_BASE */
@@ -283,8 +285,10 @@ dei_end:
parm $r2 /* count */
parm $r3 /* instance_count */
parm $r4 maddr 0x35d /* VERTEX_BUFFER_FIRST, start */
- parm $r4 send $r4 /* start_instance */
braz $r3 #dai_end
+ parm $r4 send $r4 /* start_instance */
+ maddrsend 0x8e4 /* CB_DATA, send 0 as base_vertex */
+ send $r4 /* send start_instance */
read $r6 0x50e /* VB_INSTANCE_BASE */
maddr 0x50e /* VB_INSTANCE_BASE */
mov $r5 0x1
diff --git a/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme.h b/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme.h
index bac9042c2df..acad303ce60 100644
--- a/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme.h
+++ b/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme.h
@@ -128,11 +128,13 @@ uint32_t mme9097_draw_elts_indirect[] = {
0x00000301,
0x00000201,
0x017dc451,
-/* 0x000e: dei_again */
0x00002431,
- 0x0005d007,
- 0x00000501,
-/* 0x001b: dei_end */
+/* 0x0010: dei_again */
+ 0x02390021,
+ 0x00061007,
+ 0x00002531,
+/* 0x001d: dei_end */
+ 0x00002841,
0x01434615,
0x01438715,
0x05434021,
@@ -161,11 +163,13 @@ uint32_t mme9097_draw_elts_indirect[] = {
uint32_t mme9097_draw_arrays_indirect[] = {
0x00000201,
0x00000301,
-/* 0x0009: dai_again */
+/* 0x000b: dai_again */
0x00d74451,
+ 0x00049807,
0x00002431,
-/* 0x0013: dai_end */
- 0x0003d807,
+/* 0x0015: dai_end */
+ 0x02390071,
+ 0x00002041,
0x01438615,
0x01438021,
0x00004511,
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
index 67a25acf778..730d6feac69 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
@@ -533,8 +533,9 @@ nvc0_program_translate(struct nvc0_program *prog, uint16_t chipset,
info->bin.source = (void *)prog->pipe.tokens;
info->io.genUserClip = prog->vp.num_ucps;
+ info->io.auxCBSlot = 15;
info->io.ucpBase = 256;
- info->io.ucpCBSlot = 15;
+ info->io.drawInfoBase = 256 + 128;
if (prog->type == PIPE_SHADER_COMPUTE) {
if (chipset >= NVISA_GK104_CHIPSET) {
@@ -583,6 +584,7 @@ nvc0_program_translate(struct nvc0_program *prog, uint16_t chipset,
prog->num_barriers = info->numBarriers;
prog->vp.need_vertex_id = info->io.vertexId < PIPE_MAX_SHADER_INPUTS;
+ prog->vp.need_draw_parameters = info->prop.vp.usesDrawParameters;
if (info->io.edgeFlagOut < PIPE_MAX_ATTRIBS)
info->out[info->io.edgeFlagOut].mask = 0; /* for headergen */
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.h b/src/gallium/drivers/nouveau/nvc0/nvc0_program.h
index 9c45e7b3e31..8b8d221edfc 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.h
@@ -42,6 +42,7 @@ struct nvc0_program {
uint8_t num_ucps; /* also set to max if ClipDistance is used */
uint8_t edgeflag; /* attribute index of edgeflag input */
bool need_vertex_id;
+ bool need_draw_parameters;
} vp;
struct {
uint8_t early_z;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index 500510a0870..f029d164436 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -184,6 +184,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
case PIPE_CAP_SHAREABLE_SHADERS:
case PIPE_CAP_CLEAR_TEXTURE:
+ case PIPE_CAP_DRAW_PARAMETERS:
return 1;
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
@@ -206,7 +207,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_VERTEXID_NOBASE:
case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
- case PIPE_CAP_DRAW_PARAMETERS:
return 0;
case PIPE_CAP_VENDOR_ID:
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
index 54443bdccc0..273451e638d 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
@@ -814,6 +814,14 @@ nvc0_draw_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
if (buf->fence_wr && !nouveau_fence_signalled(buf->fence_wr))
IMMED_NVC0(push, SUBC_3D(NV10_SUBCHAN_REF_CNT), 0);
+ /* Queue things up to let the macros write params to the driver constbuf */
+ BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
+ PUSH_DATA (push, 512);
+ PUSH_DATAh(push, nvc0->screen->uniform_bo->offset + (5 << 16) + (0 << 9));
+ PUSH_DATA (push, nvc0->screen->uniform_bo->offset + (5 << 16) + (0 << 9));
+ BEGIN_NVC0(push, NVC0_3D(CB_POS), 1);
+ PUSH_DATA (push, 256 + 128);
+
PUSH_SPACE(push, 8);
if (info->indexed) {
assert(nvc0->idxbuf.buffer);
@@ -901,6 +909,18 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
/* 8 as minimum to avoid immediate double validation of new buffers */
nvc0_state_validate(nvc0, ~0, 8);
+ if (nvc0->vertprog->vp.need_draw_parameters) {
+ BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
+ PUSH_DATA (push, 512);
+ PUSH_DATAh(push, nvc0->screen->uniform_bo->offset + (5 << 16) + (0 << 9));
+ PUSH_DATA (push, nvc0->screen->uniform_bo->offset + (5 << 16) + (0 << 9));
+ BEGIN_1IC0(push, NVC0_3D(CB_POS), 1 + 3);
+ PUSH_DATA (push, 256 + 128);
+ PUSH_DATA (push, info->index_bias);
+ PUSH_DATA (push, info->start_instance);
+ PUSH_DATA (push, info->drawid);
+ }
+
push->kick_notify = nvc0_draw_vbo_kick_notify;
/* TODO: Instead of iterating over all the buffer resources looking for