On 07/26/2015 06:56 AM, Ilia Mirkin wrote:
Apparently this is necessary in order for tess factors to work in a tess
eval program without a tess control program bound. Probably because it
uses the fake program's shader header to work out the number of patch
constants.

Fixes vs-tes-tessinner-tessouter-inputs

Signed-off-by: Ilia Mirkin <imir...@alum.mit.edu>
---
  src/gallium/drivers/nouveau/nvc0/nvc0_context.c      |  5 +++++
  src/gallium/drivers/nouveau/nvc0/nvc0_context.h      |  3 +++
  src/gallium/drivers/nouveau/nvc0/nvc0_program.c      | 17 +++++++++++++++++
  src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c |  6 +++++-
  4 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c 
b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
index 84f8db6..46970db 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
@@ -132,6 +132,9 @@ nvc0_context_unreference_resources(struct nvc0_context 
*nvc0)
        pipe_resource_reference(res, NULL);
     }
     util_dynarray_fini(&nvc0->global_residents);
+
+   if (nvc0->tcp_empty)
+      nvc0->base.pipe.delete_tcs_state(&nvc0->base.pipe, nvc0->tcp_empty);
  }
static void
@@ -326,6 +329,8 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
/* shader builtin library is per-screen, but we need a context for m2mf */
     nvc0_program_library_upload(nvc0);
+   nvc0_program_init_tcp_empty(nvc0);
+   nvc0->dirty |= NVC0_NEW_TCTLPROG;
/* add permanently resident buffers to bufctxts */ diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
index f449942..df1a891 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
@@ -128,6 +128,8 @@ struct nvc0_context {
     struct nvc0_program *fragprog;
     struct nvc0_program *compprog;
+ struct nvc0_program *tcp_empty;
+
     struct nvc0_constbuf constbuf[6][NVC0_MAX_PIPE_CONSTBUFS];
     uint16_t constbuf_dirty[6];
     uint16_t constbuf_valid[6];
@@ -227,6 +229,7 @@ void nvc0_program_destroy(struct nvc0_context *, struct 
nvc0_program *);
  void nvc0_program_library_upload(struct nvc0_context *);
  uint32_t nvc0_program_symbol_offset(const struct nvc0_program *,
                                      uint32_t label);
+void nvc0_program_init_tcp_empty(struct nvc0_context *);
/* nvc0_query.c */
  void nvc0_init_query_functions(struct nvc0_context *);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c 
b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
index 4941831..e9975ce 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
@@ -22,6 +22,8 @@
#include "pipe/p_defines.h" +#include "tgsi/tgsi_ureg.h"
+
  #include "nvc0/nvc0_context.h"
#include "codegen/nv50_ir_driver.h"
@@ -803,3 +805,18 @@ nvc0_program_symbol_offset(const struct nvc0_program 
*prog, uint32_t label)
           return prog->code_base + base + syms[i].offset;
     return prog->code_base; /* no symbols or symbol not found */
  }
+
+void
+nvc0_program_init_tcp_empty(struct nvc0_context *nvc0)
+{
+   struct ureg_program *ureg;
+
+   ureg = ureg_create(TGSI_PROCESSOR_TESS_CTRL);
+   if (!ureg)
+      return;
+
+   ureg_property(ureg, TGSI_PROPERTY_TCS_VERTICES_OUT, 1);
+   ureg_END(ureg);
+
+   nvc0->tcp_empty = ureg_create_shader_and_destroy(ureg, &nvc0->base.pipe);
+}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c 
b/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c
index 8aa127a..e21515f 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c
@@ -148,8 +148,12 @@ nvc0_tctlprog_validate(struct nvc0_context *nvc0)
        BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(2)), 1);
        PUSH_DATA (push, tp->num_gprs);
     } else {
-      BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 1);
+      tp = nvc0->tcp_empty;
+      if (!nvc0_program_validate(nvc0, tp))
+         assert(!"unable to validate empty tcp");
+      BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 2);
        PUSH_DATA (push, 0x20);
+      PUSH_DATA (push, tp->code_base);
     }

It would be good to check if tp is not NULL before trying to validate the program. And if the program can't be validated, I don't think we want to push tp->code_base, isn't it?

     nvc0_program_update_context_state(nvc0, tp, 1);
  }

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

Reply via email to