gallium: add PIPE_SHADER_CAP_GLSL_16BIT_TEMPS for LowerPrecisionTemporaries
[mesa.git] / src / gallium / drivers / svga / svga_state_vdecl.c
index f531e22304874c2d0312337e6c99e0a18d553ea7..a49bcd0a2630ff631969cc53cf8b4953f7241d07 100644 (file)
 #include "svga_draw.h"
 #include "svga_tgsi.h"
 #include "svga_screen.h"
-#include "svga_screen_buffer.h"
-
+#include "svga_shader.h"
+#include "svga_resource_buffer.h"
 #include "svga_hw_reg.h"
 
 
-static int
-upload_user_buffers( struct svga_context *svga )
-{
-   enum pipe_error ret = PIPE_OK;
-   int i;
-   int nr;
-
-   if (0) 
-      debug_printf("%s: %d\n", __FUNCTION__, svga->curr.num_vertex_buffers);
-
-   nr = svga->curr.num_vertex_buffers;
-
-   for (i = 0; i < nr; i++) 
-   {
-      if (svga_buffer_is_user_buffer(svga->curr.vb[i].buffer))
-      {
-         struct svga_buffer *buffer = svga_buffer(svga->curr.vb[i].buffer);
-
-         if (!buffer->uploaded.buffer) {
-            ret = u_upload_buffer( svga->upload_vb,
-                                   0,
-                                   buffer->base.size,
-                                   &buffer->base,
-                                   &buffer->uploaded.offset,
-                                   &buffer->uploaded.buffer );
-            if (ret)
-               return ret;
-
-            if (0)
-               debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n",
-                            __FUNCTION__,
-                            i,
-                            buffer,
-                            buffer->uploaded.buffer,
-                            buffer->uploaded.offset,
-                            buffer->base.size);
-         }
-
-         pipe_buffer_reference( &svga->curr.vb[i].buffer, buffer->uploaded.buffer );
-         svga->curr.vb[i].buffer_offset = buffer->uploaded.offset;
-      }
-   }
-
-   if (0)
-      debug_printf("%s: DONE\n", __FUNCTION__);
-
-   return ret;
-}
-
-
-/***********************************************************************
- */
-
 
-static int emit_hw_vs_vdecl( struct svga_context *svga,
-                             unsigned dirty )
+static enum pipe_error
+emit_hw_vs_vdecl(struct svga_context *svga, uint64_t dirty)
 {
    const struct pipe_vertex_element *ve = svga->curr.velems->velem;
-   SVGA3dVertexDecl decl;
+   SVGA3dVertexDecl decls[SVGA3D_INPUTREG_MAX];
+   unsigned buffer_indexes[SVGA3D_INPUTREG_MAX];
    unsigned i;
+   unsigned neg_bias = 0;
 
    assert(svga->curr.velems->count >=
           svga->curr.vs->base.info.file_count[TGSI_FILE_INPUT]);
 
-   svga_hwtnl_reset_vdecl( svga->hwtnl, 
-                           svga->curr.velems->count );
+   /**
+    * We can't set the VDECL offset to something negative, so we
+    * must calculate a common negative additional index bias, and modify
+    * the VDECL offsets accordingly so they *all* end up positive.
+    *
+    * Note that the exact value of the negative index bias is not that
+    * important, since we compensate for it when we calculate the vertex
+    * buffer offset below. The important thing is that all vertex buffer
+    * offsets remain positive.
+    *
+    * Note that we use a negative bias variable in order to make the
+    * rounding maths more easy to follow, and to avoid int / unsigned
+    * confusion.
+    */
+
+   for (i = 0; i < svga->curr.velems->count; i++) {
+      const struct pipe_vertex_buffer *vb =
+         &svga->curr.vb[ve[i].vertex_buffer_index];
+      struct svga_buffer *buffer;
+      unsigned int offset = vb->buffer_offset + ve[i].src_offset;
+      unsigned tmp_neg_bias = 0;
+
+      if (!vb->buffer.resource)
+         continue;
+
+      buffer = svga_buffer(vb->buffer.resource);
+      if (buffer->uploaded.start > offset) {
+         tmp_neg_bias = buffer->uploaded.start - offset;
+         if (vb->stride)
+            tmp_neg_bias = (tmp_neg_bias + vb->stride - 1) / vb->stride;
+         neg_bias = MAX2(neg_bias, tmp_neg_bias);
+      }
+   }
 
    for (i = 0; i < svga->curr.velems->count; i++) {
-      const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index];
+      const struct pipe_vertex_buffer *vb =
+         &svga->curr.vb[ve[i].vertex_buffer_index];
       unsigned usage, index;
+      struct svga_buffer *buffer;
 
+      if (!vb->buffer.resource)
+         continue;
 
+      buffer = svga_buffer(vb->buffer.resource);
       svga_generate_vdecl_semantics( i, &usage, &index );
 
       /* SVGA_NEW_VELEMENT
        */
-      decl.identity.type = svga->state.sw.ve_format[i];
-      decl.identity.method = SVGA3D_DECLMETHOD_DEFAULT;
-      decl.identity.usage = usage;
-      decl.identity.usageIndex = index;
-      decl.array.stride = vb->stride;
-      decl.array.offset = (vb->buffer_offset +
-                           ve[i].src_offset);
-
-      svga_hwtnl_vdecl( svga->hwtnl,
-                        i,
-                        &decl,
-                        vb->buffer );
+      decls[i].identity.type = svga->curr.velems->decl_type[i];
+      decls[i].identity.method = SVGA3D_DECLMETHOD_DEFAULT;
+      decls[i].identity.usage = usage;
+      decls[i].identity.usageIndex = index;
+      decls[i].array.stride = vb->stride;
+
+      /* Compensate for partially uploaded vbo, and
+       * for the negative index bias.
+       */
+      decls[i].array.offset = (vb->buffer_offset
+                           + ve[i].src_offset
+                          + neg_bias * vb->stride
+                          - buffer->uploaded.start);
+
+      assert(decls[i].array.offset >= 0);
+
+      buffer_indexes[i] = ve[i].vertex_buffer_index;
+
+      assert(!buffer->uploaded.buffer);
    }
 
-   return 0;
+   svga_hwtnl_vertex_decls(svga->hwtnl,
+                           svga->curr.velems->count,
+                           decls,
+                           buffer_indexes,
+                           svga->curr.velems->id);
+
+   svga_hwtnl_vertex_buffers(svga->hwtnl,
+                             svga->curr.num_vertex_buffers,
+                             svga->curr.vb);
+
+   svga_hwtnl_set_index_bias( svga->hwtnl, -(int) neg_bias );
+   return PIPE_OK;
 }
 
 
-static int emit_hw_vdecl( struct svga_context *svga,
-                          unsigned dirty )
+static enum pipe_error
+emit_hw_vdecl(struct svga_context *svga, uint64_t dirty)
 {
-   int ret = 0;
-
    /* SVGA_NEW_NEED_SWTNL
     */
    if (svga->state.sw.need_swtnl)
-      return 0; /* Do not emit during swtnl */
-
-   /* If we get to here, we know that we're going to draw.  Upload
-    * userbuffers now and try to combine multiple userbuffers from
-    * multiple draw calls into a single host buffer for performance.
-    */
-   if (svga->curr.any_user_vertex_buffers &&
-       SVGA_COMBINE_USERBUFFERS)
-   {
-      ret = upload_user_buffers( svga );
-      if (ret)
-         return ret;
-
-      svga->curr.any_user_vertex_buffers = FALSE;
-   }
+      return PIPE_OK; /* Do not emit during swtnl */
 
    return emit_hw_vs_vdecl( svga, dirty );
 }
 
 
-struct svga_tracked_state svga_hw_vdecl = 
+struct svga_tracked_state svga_hw_vdecl =
 {
    "hw vertex decl state (hwtnl version)",
    ( SVGA_NEW_NEED_SWTNL |
@@ -171,9 +158,3 @@ struct svga_tracked_state svga_hw_vdecl =
      SVGA_NEW_VS ),
    emit_hw_vdecl
 };
-
-
-
-
-
-