[Mesa-dev] [PATCH 9/9] gallium : st_glsl_to_tgsi handles UBO

Vincent Lejeune vljn at ovi.com
Thu Dec 1 07:35:38 PST 2011


---
 src/mesa/main/ubo.c                        |  268 ----------------------------
 src/mesa/state_tracker/st_atom_constbuf.c  |    8 +
 src/mesa/state_tracker/st_extensions.c     |    4 +
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp |   92 +++++-----
 4 files changed, 59 insertions(+), 313 deletions(-)
 delete mode 100644 src/mesa/main/ubo.c

diff --git a/src/mesa/main/ubo.c b/src/mesa/main/ubo.c
deleted file mode 100644
index 1e31df8..0000000
--- a/src/mesa/main/ubo.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2004-2011  Brian Paul   All Rights Reserved.
- * Copyright (C) 2009-2011  VMware, Inc.  All Rights Reserved.
- * Copyright © 2010-2011 Intel Corporation
- * Copyright (C) 2011 Vincent Lejeune.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * API implementation of GL_ARB_uniform_buffer_object.
- *
- * Every uniform (in an UBO or not) is given an index that identifies it when
- * calling one of these functions. Strictly speaking, such an index doesn't
- * need to match location for classic uniform ; others drivers however use this
- * approach so we're also matching them for compatibility purpose.
- */
-
-#include <stdint.h>
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/dispatch.h"
-#include "main/image.h"
-#include "main/mfeatures.h"
-#include "main/mtypes.h"
-#include "main/shaderapi.h"
-#include "main/shaderobj.h"
-#include "main/uniforms.h"
-#include "main/hash.h"
-#include "program/prog_parameter.h"
-#include "program/prog_statevars.h"
-#include "program/prog_uniform.h"
-#include "program/prog_instruction.h"
-#include "main/ubo.h"
-#include "main/bufferobj.h"
-
-static void
-get_ubo_info (struct gl_context *ctx,
-		   struct gl_shader_program *shProg, GLint ubo_index,
-		   GLenum query, int *data)
-{
-  if (ubo_index > shProg->UBOCount || ubo_index < 0)
-    _mesa_error (ctx, GL_INVALID_VALUE,
-		 "glGetActiveUniformBlock(uniformBlockIndex)");
-
-  struct gl_uniform_buffer_object current_ubo =
-    shProg->UniformBufferObject[ubo_index];
-
-  switch (query)
-    {
-    case GL_UNIFORM_BLOCK_BINDING:
-      //*data = current_ubo.BoundBuffer;
-      break;
-    case GL_UNIFORM_BLOCK_DATA_SIZE:
-      //*data = 0;
-      break;
-    case GL_UNIFORM_BLOCK_NAME_LENGTH:
-      *data = strlen (current_ubo.Name);
-      break;
-    case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
-      *data = current_ubo.NumberOfVariables;
-      break;
-    case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
-    case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER:
-    case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
-      //*data = 0;
-      break;
-    default:
-      break;
-    }
-}
-
-static GLuint
-get_indice (const struct gl_shader_program *prog, const char *name)
-{
-  void* index =
-    hash_table_find (prog->Uniforms->NamedAccessUBOVariables, name);
-  if (index) {
-     uintptr_t faked_index = (uintptr_t) index;
-     return faked_index - 1;
-  }
-
-  return GL_INVALID_INDEX;
-}
-
-/**
- * This function checks if it can copy source into dest.
- * If it cannot, it returns 1, otherwise it returns 0 and
- * write size to *length if non NULL
- */
-static int
-copy_char_buffer (const char *source, char *dest, unsigned destsize,
-		  int *length)
-{
-  unsigned sourcesize = strlen (source);
-  if (sourcesize > destsize + 1)
-    {
-      return -1;
-    }
-  memcpy (dest, source, sourcesize);
-  dest[sourcesize] = '0';
-  if (length)
-    *length = sourcesize;
-  return 0;
-}
-
-static void
-get_ubo_name (struct gl_context *ctx, struct gl_shader_program *shProg,
-	      GLint index, GLsizei bufsize, GLsizei * length, char *buffer)
-{
-  if (index >= shProg->UBOCount || index < 0)
-    {
-      _mesa_error (ctx, GL_INVALID_VALUE,
-		   "GetActiveUniformBlockName(uniformBlockIndex)");
-      return;
-    }
-
-  struct gl_uniform_buffer_object current_ubo =
-    shProg->UniformBufferObject[index];
-
-  if (copy_char_buffer (current_ubo.Name, buffer, bufsize, length))
-    {
-      _mesa_error (ctx, GL_INVALID_VALUE,
-		   "GetActiveUniformBlockName(bufSize)");
-      return;
-    }
-  return;
-}
-
-static void
-get_uniform_variable_name (struct gl_context *ctx,
-			   struct gl_shader_program *sh, GLuint index,
-			   GLsizei bufsize, GLsizei * length,
-			   char *uniformName)
-{
-  const char *name = sh->Uniforms->Uniforms[index].Name;
-  if (copy_char_buffer (name, uniformName, bufsize, length))
-    {
-      _mesa_error (ctx, GL_INVALID_VALUE, "GetActiveUniformName(bufSize)");
-      return;
-    }
-  return;
-}
-
-static GLint
-get_uniform_variable_info (struct gl_shader_program *sh, GLuint index,
-			   GLenum pname)
-{
-  uint n = sh->Uniforms->NumUniforms;
-  if (index >= n)
-    {
-      struct gl_program_ubo_variable *var =
-	sh->Uniforms->IndexedUBOVariables[index - n];
-      switch (pname)
-	{
-	case GL_UNIFORM_TYPE:
-	  return var->Type;
-	case GL_UNIFORM_SIZE:
-	  return 1;
-	case GL_UNIFORM_BLOCK_NAME_LENGTH:
-	case GL_UNIFORM_BLOCK_INDEX:
-	  return var->UBO->Index;
-	case GL_UNIFORM_OFFSET:
-	  return var->Offset;
-	case GL_UNIFORM_ARRAY_STRIDE:
-	case GL_UNIFORM_MATRIX_STRIDE:
-	  return var->Stride;
-	case GL_UNIFORM_IS_ROW_MAJOR:
-	  return sh->UniformBufferObject[var->UBO->Index].MatrixLayout ==
-	    UBO_MATRIX_LAYOUT_ROW_MAJOR;
-	}
-    }
-
-  return GL_INVALID_VALUE;
-}
-
-void GLAPIENTRY
-_mesa_GetActiveUniformBlockInfo (GLuint program, GLuint ubo_index,
-				 GLenum pname, GLint * params)
-{
-  GET_CURRENT_CONTEXT (ctx);
-  struct gl_shader_program *shProg =
-    _mesa_lookup_shader_program_err (ctx, program, "GetActiveUniformBlockiv");
-  get_ubo_info (ctx, shProg, ubo_index, pname, params);
-}
-
-void GLAPIENTRY
-_mesa_GetActiveUniformBlockName (GLuint program, GLuint ubo_index,
-				 GLsizei bufsize, GLint * length, char *name)
-{
-  GET_CURRENT_CONTEXT (ctx);
-  struct gl_shader_program *shProg =
-    _mesa_lookup_shader_program_err (ctx, program,
-				     "GetActiveUniformBlockName");
-  get_ubo_name (ctx, shProg, ubo_index, bufsize, length, name);
-}
-
-void GLAPIENTRY
-_mesa_GetUniformIndices (GLuint program, GLsizei number_of_variables,
-			 const char **names, GLuint * indices)
-{
-  unsigned i;
-  GET_CURRENT_CONTEXT (ctx);
-
-  struct gl_shader_program *shProg =
-    _mesa_lookup_shader_program_err (ctx, program, "GetUniformIndices");
-  for (i = 0; i < number_of_variables; i++)
-    {
-      indices[i] = get_indice (shProg, names[i]);
-    }
-}
-
-void GLAPIENTRY
-_mesa_GetActiveUniformName (GLuint program, GLuint index, GLsizei bufsize,
-			    GLsizei * length, char *uniformName)
-{
-  GET_CURRENT_CONTEXT (ctx);
-  struct gl_shader_program *shProg =
-    _mesa_lookup_shader_program_err (ctx, program, "GetActiveUniformName");
-  get_uniform_variable_name (ctx, shProg, index, bufsize, length,
-			     uniformName);
-
-}
-
-void GLAPIENTRY
-_mesa_GetActiveUniformsiv (GLuint program, GLsizei uniformCount,
-			   const GLuint * uniformIndices, GLenum pname,
-			   GLint * param)
-{
-  unsigned k;
-  GET_CURRENT_CONTEXT (ctx);
-  struct gl_shader_program *shProg =
-    _mesa_lookup_shader_program_err (ctx, program, "GetActiveUniformsiv");
-
-
-  for (k = 0; k < uniformCount; k++)
-    {
-      param[k] = get_uniform_variable_info (shProg, uniformIndices[k], pname);
-    }
-}
-
-void
-_mesa_init_shader_uniform_buffer_objects (struct _glapi_table *exec)
-{
-/* GL_ARB_Uniform_Buffer_Object */
-  SET_GetActiveUniformBlockiv (exec, _mesa_GetActiveUniformBlockInfo);
-  SET_GetActiveUniformBlockName (exec, _mesa_GetActiveUniformBlockName);
-  SET_GetUniformIndices (exec, _mesa_GetUniformIndices);
-  SET_GetActiveUniformName (exec, _mesa_GetActiveUniformName);
-  SET_GetActiveUniformsiv (exec, _mesa_GetActiveUniformsiv);
-}
diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c
index 05667a7..8061347 100644
--- a/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/src/mesa/state_tracker/st_atom_constbuf.c
@@ -45,6 +45,8 @@
 #include "st_atom_constbuf.h"
 #include "st_program.h"
 
+#include "st_cb_bufferobjects.h"
+
 
 /**
  * Pass the given program parameters to the graphics pipe as a
@@ -55,6 +57,7 @@ void st_upload_constants( struct st_context *st,
                           struct gl_program_parameter_list *params,
                           unsigned shader_type)
 {
+   unsigned i;
    struct pipe_context *pipe = st->pipe;
 
    assert(shader_type == PIPE_SHADER_VERTEX ||
@@ -100,6 +103,11 @@ void st_upload_constants( struct st_context *st,
       st->state.constants[shader_type].size = 0;
       st->pipe->set_constant_buffer(st->pipe, shader_type, 0, NULL);
    }
+
+   for (i = 0; i < params->NumUBO; i++) {
+      struct st_buffer_object* buf = st_buffer_object(st->ctx->UniformBufferObject.BindingPoint[i]);
+      st->pipe->set_constant_buffer(st->pipe,shader_type,i+1,buf->buffer);
+   }
 }
 
 
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index c741d13..93f6bc6 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -670,4 +670,8 @@ void st_init_extensions(struct st_context *st)
                                    PIPE_BIND_SAMPLER_VIEW))
        ctx->Extensions.ARB_texture_rgb10_a2ui = GL_TRUE;
 
+#if FEATURE_ARB_uniform_buffer_object
+   if (screen->get_param(screen,PIPE_SHADER_CAP_MAX_CONST_BUFFERS) > 1)
+      ctx->Extensions.ARB_uniform_buffer_object = GL_TRUE;
+#endif
 }
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 5e68b80..eaf8de7 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -299,6 +299,8 @@ public:
 
    struct gl_context *ctx;
    struct gl_program *prog;
+   struct gl_program_ubo_variable **indexed_uniforms;
+   unsigned starting_index;
    struct gl_shader_program *shader_program;
    struct gl_shader_compiler_options *options;
 
@@ -326,6 +328,8 @@ public:
    st_src_reg st_src_reg_for_int(int val);
    st_src_reg st_src_reg_for_type(int type, int val);
 
+   st_src_reg generate_ubo_access_src_reg(const ir_variable *);
+
    /**
     * \name Visit methods
     *
@@ -1042,6 +1046,7 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir)
 
       variable_storage *storage;
       st_dst_reg dst;
+
       if (i == ir->num_state_slots) {
          /* We'll set the index later. */
          storage = new(mem_ctx) variable_storage(ir, PROGRAM_STATE_VAR, -1);
@@ -1894,6 +1899,31 @@ glsl_to_tgsi_visitor::visit(ir_swizzle *ir)
    this->result = src;
 }
 
+struct st_src_reg
+glsl_to_tgsi_visitor::generate_ubo_access_src_reg(const ir_variable *var)
+{
+   int index,index2d;
+   struct gl_program_ubo_variable* ubovar = indexed_uniforms[var->location - starting_index];
+   index = ubovar->Offset / 16;
+   index2d = ubovar->UBO->Index + 1;
+
+   st_src_reg result = st_src_reg(PROGRAM_UNIFORM,index,var->type,index2d);
+   switch(ubovar->Offset - (index / 16) * 16) {
+   case 12:
+      result.swizzle = SWIZZLE_W;
+   case 8:
+      result.swizzle = SWIZZLE_Z;
+   case 4:
+      result.swizzle = SWIZZLE_Y;
+   default:
+      result.swizzle = SWIZZLE_XYZW;
+
+   }
+
+
+   return result;
+}
+
 void
 glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
 {
@@ -1948,6 +1978,11 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
       }
    }
 
+   if(var->mode == ir_var_uniform && var->is_ubo_variable) {
+      this->result = generate_ubo_access_src_reg(var);
+      return;
+   }
+
    this->result = st_src_reg(entry->file, entry->index, var->type);
    if (!native_integers)
       this->result.type = GLSL_TYPE_FLOAT;
@@ -4069,10 +4104,11 @@ dst_register(struct st_translate *t,
  */
 static struct ureg_src
 src_register(struct st_translate *t,
-             gl_register_file file,
-             GLuint index)
+             const st_src_reg* src_reg)
 {
-   switch(file) {
+   int index = src_reg->index;
+   int index2d = src_reg->index2d;
+   switch(src_reg->file) {
    case PROGRAM_UNDEFINED:
       return ureg_src_undef();
 
@@ -4088,13 +4124,11 @@ src_register(struct st_translate *t,
    case PROGRAM_LOCAL_PARAM:
    case PROGRAM_UNIFORM:
       assert(index >= 0);
-      return t->constants[index];
+      return ureg_src_register2d(TGSI_FILE_CONSTANT,index,index2d);
    case PROGRAM_STATE_VAR:
    case PROGRAM_CONSTANT:       /* ie, immediate */
-      if (index < 0)
-         return ureg_DECL_constant(t->ureg, 0);
-      else
-         return t->constants[index];
+      assert(index >= 0);
+      return ureg_src_register(TGSI_FILE_CONSTANT,index);
 
    case PROGRAM_IMMEDIATE:
       return t->immediates[index];
@@ -4149,7 +4183,7 @@ translate_dst(struct st_translate *t,
 static struct ureg_src
 translate_src(struct st_translate *t, const st_src_reg *src_reg)
 {
-   struct ureg_src src = src_register(t, src_reg->file, src_reg->index);
+   struct ureg_src src = src_register(t, src_reg);
 
    src = ureg_swizzle(src,
                       GET_SWZ(src_reg->swizzle, 0) & 0x3,
@@ -4684,45 +4718,11 @@ st_translate_program(
       }
    }
 
-   /* Emit constants and uniforms.  TGSI uses a single index space for these, 
+   /* Emit constants and uniforms.  TGSI uses a single index space for these,
     * so we put all the translated regs in t->constants.
     */
    if (proginfo->Parameters) {
-      t->constants = (struct ureg_src *)CALLOC(proginfo->Parameters->NumParameters * sizeof(t->constants[0]));
-      if (t->constants == NULL) {
-         ret = PIPE_ERROR_OUT_OF_MEMORY;
-         goto out;
-      }
-
-      for (i = 0; i < proginfo->Parameters->NumParameters; i++) {
-         switch (proginfo->Parameters->Parameters[i].Type) {
-         case PROGRAM_ENV_PARAM:
-         case PROGRAM_LOCAL_PARAM:
-         case PROGRAM_STATE_VAR:
-         case PROGRAM_NAMED_PARAM:
-         case PROGRAM_UNIFORM:
-            t->constants[i] = ureg_DECL_constant(ureg, i);
-            break;
-
-         /* Emit immediates for PROGRAM_CONSTANT only when there's no indirect
-          * addressing of the const buffer.
-          * FIXME: Be smarter and recognize param arrays:
-          * indirect addressing is only valid within the referenced
-          * array.
-          */
-         case PROGRAM_CONSTANT:
-            if (program->indirect_addr_consts)
-               t->constants[i] = ureg_DECL_constant(ureg, i);
-            else
-               t->constants[i] = emit_immediate(t,
-                                                proginfo->Parameters->ParameterValues[i],
-                                                proginfo->Parameters->Parameters[i].DataType,
-                                                4);
-            break;
-         default:
-            break;
-         }
-      }
+      ureg_DECL_constant2D(t->ureg,0,proginfo->Parameters->NumParameters,0);
    }
    
    /* Emit immediate values.
@@ -4806,6 +4806,8 @@ get_mesa_program(struct gl_context *ctx,
         	 struct gl_shader *shader)
 {
    glsl_to_tgsi_visitor* v = new glsl_to_tgsi_visitor();
+   v->indexed_uniforms = shader_program->IndexedUBOVariables;
+   v->starting_index = shader_program->NumUserUniformStorage;
    struct gl_program *prog;
    struct pipe_screen * screen = st_context(ctx)->pipe->screen;
    unsigned pipe_shader_type;
-- 
1.7.7



More information about the mesa-dev mailing list