gallium: add PIPE_SHADER_CAP_GLSL_16BIT_TEMPS for LowerPrecisionTemporaries
[mesa.git] / src / gallium / drivers / svga / svga_state_vdecl.c
index c534308f50307464f681be6cec47a11e3f8d2972..a49bcd0a2630ff631969cc53cf8b4953f7241d07 100644 (file)
@@ -23,7 +23,7 @@
  *
  **********************************************************/
 
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
 #include "pipe/p_defines.h"
 #include "util/u_math.h"
 #include "util/u_upload_mgr.h"
 #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 pipe_buffer *upload_buffer = NULL;
-         unsigned offset = /*svga->curr.vb[i].buffer_offset*/ 0;
-         unsigned size = svga->curr.vb[i].buffer->size /*- offset*/;
-         unsigned upload_offset;
-
-         ret = u_upload_buffer( svga->upload_vb,
-                                offset,
-                                size,
-                                svga->curr.vb[i].buffer,
-                                &upload_offset,
-                                &upload_buffer );
-         if (ret)
-            return ret;
-
-         if (0)
-            debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n", 
-                         __FUNCTION__, 
-                         i,
-                         svga->curr.vb[i].buffer,
-                         upload_buffer, upload_offset, size);
-
-         /* Make sure we release the old buffer and end up with the
-          * correct refcount on the uploaded buffer.
-          */
-         pipe_buffer_reference( &svga->curr.vb[i].buffer, NULL );
-         svga->curr.vb[i].buffer = upload_buffer;
-         svga->curr.vb[i].buffer_offset = upload_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.ve;
-   SVGA3dVertexDecl decl;
+   const struct pipe_vertex_element *ve = svga->curr.velems->velem;
+   SVGA3dVertexDecl decls[SVGA3D_INPUTREG_MAX];
+   unsigned buffer_indexes[SVGA3D_INPUTREG_MAX];
    unsigned i;
+   unsigned neg_bias = 0;
 
-   assert(svga->curr.num_vertex_elements >=
+   assert(svga->curr.velems->count >=
           svga->curr.vs->base.info.file_count[TGSI_FILE_INPUT]);
 
-   svga_hwtnl_reset_vdecl( svga->hwtnl, 
-                           svga->curr.num_vertex_elements );
+   /**
+    * 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.num_vertex_elements; i++) {
-      const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index];
+   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];
       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 |
@@ -174,9 +158,3 @@ struct svga_tracked_state svga_hw_vdecl =
      SVGA_NEW_VS ),
    emit_hw_vdecl
 };
-
-
-
-
-
-