missing file
authorKeith Whitwell <keith@tungstengraphics.com>
Thu, 2 Nov 2006 08:37:17 +0000 (08:37 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Thu, 2 Nov 2006 08:37:17 +0000 (08:37 +0000)
src/mesa/tnl/t_draw.c [new file with mode: 0644]

diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c
new file mode 100644 (file)
index 0000000..be811ef
--- /dev/null
@@ -0,0 +1,305 @@
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ *
+ * 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.
+ *
+ * Authors:
+ *    Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "context.h"
+#include "imports.h"
+#include "state.h"
+#include "mtypes.h"
+#include "macros.h"
+
+#include "t_context.h"
+#include "t_pipeline.h"
+#include "t_vp_build.h"
+#include "t_vertex.h"
+#include "tnl.h"
+
+#define CONVERT( TYPE, MACRO ) do {            \
+   GLuint i, j;                                        \
+   for (i = 0; i < count; i++) {               \
+      const TYPE *in = (TYPE *)ptr;                    \
+      for (j = 0; j < sz; j++) {               \
+        *fptr++ = MACRO(*in);                  \
+        in++;                                  \
+      }                                                \
+      ptr += input->StrideB;                   \
+   }                                           \
+} while (0)
+
+
+static GLfloat *get_space(GLcontext *ctx, GLuint bytes)
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   GLubyte *space = _mesa_malloc(bytes);
+   
+   tnl->block[tnl->nr_blocks++] = space;
+   return (GLfloat *)space;
+}
+
+
+static void free_space(GLcontext *ctx)
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   GLuint i;
+   for (i = 0; i < tnl->nr_blocks; i++)
+      _mesa_free(tnl->block[i]);
+   tnl->nr_blocks = 0;
+}
+
+
+/* Adjust pointer to point at first requested element, convert to
+ * floating point, populate VB->AttribPtr[].
+ */
+static void _tnl_import_array( GLcontext *ctx,
+                              GLuint attrib,
+                              GLuint start,
+                              GLuint end,
+                              const struct gl_client_array *input,
+                              const char *ptr )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct vertex_buffer *VB = &tnl->vb;
+   const GLuint count = end - start;
+   GLuint stride = input->StrideB;
+
+   ptr += start * stride;
+
+   if (input->Type != GL_FLOAT) {
+      const GLuint sz = input->Size;
+      GLfloat *fptr = get_space(ctx, count * sz * sizeof(GLfloat));
+
+      switch (input->Type) {
+      case GL_BYTE: 
+        CONVERT(GLbyte, BYTE_TO_FLOAT); 
+        break;
+      case GL_UNSIGNED_BYTE: 
+        CONVERT(GLubyte, UBYTE_TO_FLOAT); 
+        break;
+      case GL_SHORT: 
+        CONVERT(GLshort, SHORT_TO_FLOAT); 
+        break;
+      case GL_UNSIGNED_SHORT: 
+        CONVERT(GLushort, USHORT_TO_FLOAT); 
+        break;
+      case GL_INT: 
+        CONVERT(GLint, INT_TO_FLOAT); 
+        break;
+      case GL_UNSIGNED_INT: 
+        CONVERT(GLuint, UINT_TO_FLOAT); 
+        break;
+      case GL_DOUBLE: 
+        CONVERT(GLdouble, (GLfloat)); 
+        break;
+      default:
+        assert(0);
+        break;
+      }
+
+      ptr = (const char *)fptr;
+      stride = sz * sizeof(GLfloat);
+   }
+
+   VB->AttribPtr[attrib] = &tnl->tmp_inputs[attrib];
+   VB->AttribPtr[attrib]->data = (GLfloat (*)[4])ptr;
+   VB->AttribPtr[attrib]->start = (GLfloat *)ptr;
+   VB->AttribPtr[attrib]->count = count;
+   VB->AttribPtr[attrib]->stride = stride;
+   VB->AttribPtr[attrib]->size = input->Size;
+
+   /* This should die, but so should the whole GLvector4f concept: 
+    */
+   VB->AttribPtr[attrib]->flags = (((1<<input->Size)-1) | 
+                                  VEC_NOT_WRITEABLE |
+                                  (stride == 4*sizeof(GLfloat) ? 0 : VEC_BAD_STRIDE));
+   
+   VB->AttribPtr[attrib]->storage = NULL;
+}
+
+
+static void bind_inputs( GLcontext *ctx, 
+                        const struct gl_client_array *inputs[],
+                        GLint start, GLint end,
+                        struct gl_buffer_object **bo,
+                        GLuint *nr_bo )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct vertex_buffer *VB = &tnl->vb;
+   GLuint i;
+
+   /* Map all the VBOs
+    */
+   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+      const void *ptr;
+
+      if (inputs[i]->BufferObj->Name) { 
+        if (!inputs[i]->BufferObj->Pointer) {
+           bo[*nr_bo] = inputs[i]->BufferObj;
+           *nr_bo++;
+           ctx->Driver.MapBuffer(ctx, 
+                                 GL_ARRAY_BUFFER,
+                                 GL_READ_ONLY_ARB,
+                                 inputs[i]->BufferObj);
+           
+           assert(inputs[i]->BufferObj->Pointer);
+        }
+        
+        ptr = ADD_POINTERS(inputs[i]->BufferObj->Pointer,
+                           inputs[i]->Ptr);
+      }
+      else
+        ptr = inputs[i]->Ptr;
+
+      /* Just make sure the array is floating point, otherwise convert to
+       * temporary storage.  Rebase arrays so that 'start' becomes
+       * element zero.
+       *
+       * XXX: remove the GLvector4f type at some stage and just use
+       * client arrays.
+       */
+      _tnl_import_array(ctx, i, start, end, inputs[i], ptr);
+   }
+
+   /* Legacy pointers -- remove one day.
+    */
+   VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS];
+   VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL];
+   VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0];
+   VB->ColorPtr[1] = NULL;
+   VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX];
+   VB->IndexPtr[1] = NULL;
+   VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1];
+   VB->SecondaryColorPtr[1] = NULL;
+   VB->FogCoordPtr = VB->AttribPtr[_TNL_ATTRIB_FOG];
+
+   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
+      VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i];
+   }
+
+#if 0
+   /* odd-ball vertex attribute 
+    */
+   if (ctx->Polygon.FrontMode != GL_FILL ||
+       ctx->Polygon.BackMode != GL_FILL)
+   {
+      VB->EdgeFlag = _tnl_import_edgeflag( ctx, VB->AttribPtr[_TNL_ATTRIB_EDGEFLAG]);
+   }
+#endif
+
+}
+
+
+/* Translate indices to GLuints and store in VB->Elts.
+ */
+static void bind_indicies( GLcontext *ctx,
+                          const struct _mesa_index_buffer *ib,
+                          struct gl_buffer_object **bo,
+                          GLuint *nr_bo)
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct vertex_buffer *VB = &tnl->vb;
+
+   if (!ib)
+      return;
+
+   if (ib->obj->Name && !ib->obj->Pointer) {
+      bo[*nr_bo] = ib->obj;
+      *nr_bo++;
+      ctx->Driver.MapBuffer(ctx, 
+                           GL_ELEMENT_ARRAY_BUFFER,
+                           GL_READ_ONLY_ARB,
+                           ib->obj);
+
+      assert(ib->obj->Pointer);
+   }
+
+   VB->Elts = (GLuint *)ADD_POINTERS(ib->obj->Pointer, 
+                                    ib->ptr);
+   
+   VB->Elts += ib->rebase;
+
+   switch (ib->type) {
+   case GL_UNSIGNED_INT:
+      return;
+   case GL_UNSIGNED_SHORT:
+      break;
+   case GL_UNSIGNED_BYTE:
+      break;
+   }
+}
+
+static void unmap_vbos( GLcontext *ctx,
+                       struct gl_buffer_object **bo,
+                       GLuint nr_bo )
+{
+   GLuint i;
+   for (i = 0; i < nr_bo; i++) { 
+      ctx->Driver.UnmapBuffer(ctx, 
+                             0, /* target -- I don't see why this would be needed */
+                             bo[i]);
+   }
+}
+
+
+
+/* This is the main entrypoint into the slimmed-down software tnl
+ * module.  In a regular swtnl driver, this can be plugged straight
+ * into the vbo->Driver.DrawPrims() callback.
+ */
+void _tnl_draw_prims( GLcontext *ctx,
+                     const struct gl_client_array *arrays[],
+                     const struct _mesa_prim *prim,
+                     GLuint nr_prims,
+                     const struct _mesa_index_buffer *ib,
+                     GLuint min_index,
+                     GLuint max_index)
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct vertex_buffer *VB = &tnl->vb;
+
+   /* May need to map a vertex buffer object for every attribute plus
+    * one for the index buffer.
+    */
+   struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1];
+   GLuint nr_bo = 0;
+
+   /* Binding inputs may imply mapping some vertex buffer objects.
+    * They will need to be unmapped below.
+    */
+   bind_inputs(ctx, arrays, min_index, max_index, bo, &nr_bo);
+   bind_indicies(ctx, ib, bo, &nr_bo);
+
+   VB->Primitive = prim;
+   VB->PrimitiveCount = nr_prims;
+   VB->Count = max_index - min_index;
+
+   TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);
+
+   unmap_vbos(ctx, bo, nr_bo);
+   free_space(ctx);
+}
+