[Mesa-dev] [PATCH 3/3] nv50: add support for geometry shaders

Bryan Cain bryancain3 at gmail.com
Wed Apr 17 13:55:47 PDT 2013


Layer output probably doesn't work yet, but other than that everything seems
to be working.
---
 .../drivers/nv50/codegen/nv50_ir_emit_nv50.cpp     |   25 +++++++++++++++-----
 src/gallium/drivers/nv50/nv50_program.c            |   17 +++++++++++++
 src/gallium/drivers/nv50/nv50_shader_state.c       |    2 ++
 src/gallium/drivers/nv50/nv50_tex.c                |    2 ++
 4 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_emit_nv50.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_emit_nv50.cpp
index 67b6298..d1d8b52 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir_emit_nv50.cpp
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir_emit_nv50.cpp
@@ -493,7 +493,12 @@ CodeEmitterNV50::emitForm_MAD(const Instruction *i)
    setSrc(i, 1, 1);
    setSrc(i, 2, 2);
 
-   setAReg16(i, 1);
+   if (i->getIndirect(0, 0)) {
+      assert(!i->getIndirect(1, 0));
+      setAReg16(i, 0);
+   }
+   else
+      setAReg16(i, 1);
 }
 
 // like default form, but 2nd source in slot 2, and no 3rd source
@@ -512,7 +517,12 @@ CodeEmitterNV50::emitForm_ADD(const Instruction *i)
    setSrc(i, 0, 0);
    setSrc(i, 1, 2);
 
-   setAReg16(i, 1);
+   if (i->getIndirect(0, 0)) {
+      assert(!i->getIndirect(1, 0));
+      setAReg16(i, 0);
+   }
+   else
+      setAReg16(i, 1);
 }
 
 // default short form (rr, ar, rc, gr)
@@ -602,8 +612,11 @@ CodeEmitterNV50::emitLOAD(const Instruction *i)
 
    switch (sf) {
    case FILE_SHADER_INPUT:
-      // use 'mov' where we can
-      code[0] = i->src(0).isIndirect(0) ? 0x00000001 : 0x10000001;
+      if(progType == Program::TYPE_GEOMETRY)
+         code[0] = 0x11800001;
+      else
+         // use 'mov' where we can
+         code[0] = i->src(0).isIndirect(0) ? 0x00000001 : 0x10000001;
       code[1] = 0x00200000 | (i->lanes << 14);
       if (typeSizeof(i->dType) == 4)
          code[1] |= 0x04000000;
@@ -1399,8 +1412,8 @@ CodeEmitterNV50::emitShift(const Instruction *i)
 void
 CodeEmitterNV50::emitOUT(const Instruction *i)
 {
-   code[0] = (i->op == OP_EMIT) ? 0xf0000200 : 0xf0000400;
-   code[1] = 0xc0000001;
+   code[0] = (i->op == OP_EMIT) ? 0xf0000201 : 0xf0000401;
+   code[1] = 0xc0000000;
 
    emitFlagsRd(i);
 }
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index c17ffdc..1229002 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -359,6 +359,23 @@ nv50_program_translate(struct nv50_program *prog, uint16_t chipset)
       if (info->prop.fp.usesDiscard)
          prog->fp.flags[0] |= NV50_3D_FP_CONTROL_USES_KIL;
    }
+   else if (prog->type == PIPE_SHADER_GEOMETRY) {
+      switch(info->prop.gp.outputPrim) {
+      case PIPE_PRIM_POINTS:
+         prog->gp.prim_type = NV50_3D_GP_OUTPUT_PRIMITIVE_TYPE_POINTS;
+         break;
+      case PIPE_PRIM_LINE_STRIP:
+         prog->gp.prim_type = NV50_3D_GP_OUTPUT_PRIMITIVE_TYPE_LINE_STRIP;
+         break;
+      case PIPE_PRIM_TRIANGLE_STRIP:
+         prog->gp.prim_type = NV50_3D_GP_OUTPUT_PRIMITIVE_TYPE_TRIANGLE_STRIP;
+         break;
+      default:
+         assert(0);
+         break;
+      }
+      prog->gp.vert_count = info->prop.gp.maxVertices;
+   }
 
    if (prog->pipe.stream_output.num_outputs)
       prog->so = nv50_program_create_strmout_state(info,
diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c
index 7f05243..613d257 100644
--- a/src/gallium/drivers/nv50/nv50_shader_state.c
+++ b/src/gallium/drivers/nv50/nv50_shader_state.c
@@ -193,6 +193,8 @@ nv50_gmtyprog_validate(struct nv50_context *nv50)
    struct nv50_program *gp = nv50->gmtyprog;
 
    if (gp) {
+      if(!nv50_program_validate(nv50, gp))
+         return;
       BEGIN_NV04(push, NV50_3D(GP_REG_ALLOC_TEMP), 1);
       PUSH_DATA (push, gp->max_gpr);
       BEGIN_NV04(push, NV50_3D(GP_REG_ALLOC_RESULT), 1);
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index 40b264d..be70fda 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -293,6 +293,7 @@ void nv50_validate_textures(struct nv50_context *nv50)
    boolean need_flush;
 
    need_flush  = nv50_validate_tic(nv50, 0);
+   need_flush  = nv50_validate_tic(nv50, 1);
    need_flush |= nv50_validate_tic(nv50, 2);
 
    if (need_flush) {
@@ -343,6 +344,7 @@ void nv50_validate_samplers(struct nv50_context *nv50)
    boolean need_flush;
 
    need_flush  = nv50_validate_tsc(nv50, 0);
+   need_flush  = nv50_validate_tsc(nv50, 1);
    need_flush |= nv50_validate_tsc(nv50, 2);
 
    if (need_flush) {
-- 
1.7.9.5



More information about the mesa-dev mailing list