st/nine: Improve fallback when driver doesn't support user buffers.
authorAxel Davy <axel.davy@ens.fr>
Sat, 3 Jan 2015 10:36:09 +0000 (11:36 +0100)
committerAxel Davy <axel.davy@ens.fr>
Fri, 21 Aug 2015 20:21:47 +0000 (22:21 +0200)
For now the path updated is only used by Amd drivers, but a later
patch will make it used by all drivers. Some drivers like llvmpipe
doesn't support the uploading of constants from user buffers, so improve
the path to work for all drivers

Inspired from the gl state tracker.

Signed-off-by: Axel Davy <axel.davy@ens.fr>
src/gallium/state_trackers/nine/device9.c
src/gallium/state_trackers/nine/device9.h
src/gallium/state_trackers/nine/nine_ff.c
src/gallium/state_trackers/nine/nine_state.c

index a327bf87e043b070df76192f9c3da93bfeb6cd53..1416a388315334ddc9ac56357da803c2b4f2d0d2 100644 (file)
@@ -129,23 +129,43 @@ NineDevice9_RestoreNonCSOState( struct NineDevice9 *This, unsigned mask )
     if (mask & 0x1) {
         struct pipe_constant_buffer cb;
         cb.buffer_offset = 0;
+        cb.buffer_size = This->vs_const_size;
 
         if (This->prefer_user_constbuf) {
             cb.buffer = NULL;
             cb.user_buffer = This->state.vs_const_f;
+            if (!This->driver_caps.user_cbufs) {
+                u_upload_data(This->constbuf_uploader,
+                              0,
+                              cb.buffer_size,
+                              cb.user_buffer,
+                              &cb.buffer_offset,
+                              &cb.buffer);
+                u_upload_unmap(This->constbuf_uploader);
+                cb.user_buffer = NULL;
+            }
         } else {
             cb.buffer = This->constbuf_vs;
             cb.user_buffer = NULL;
         }
-        cb.buffer_size = This->vs_const_size;
         pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &cb);
 
+        cb.buffer_size = This->ps_const_size;
         if (This->prefer_user_constbuf) {
             cb.user_buffer = This->state.ps_const_f;
+            if (!This->driver_caps.user_cbufs) {
+                u_upload_data(This->constbuf_uploader,
+                              0,
+                              cb.buffer_size,
+                              cb.user_buffer,
+                              &cb.buffer_offset,
+                              &cb.buffer);
+                u_upload_unmap(This->constbuf_uploader);
+                cb.user_buffer = NULL;
+            }
         } else {
             cb.buffer = This->constbuf_ps;
         }
-        cb.buffer_size = This->ps_const_size;
         pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &cb);
     }
 
@@ -412,16 +432,20 @@ NineDevice9_ctor( struct NineDevice9 *This,
     }
 
     /* Allocate upload helper for drivers that suck (from st pov ;). */
-    {
-        unsigned bind = 0;
 
-        This->driver_caps.user_vbufs = GET_PCAP(USER_VERTEX_BUFFERS);
-        This->driver_caps.user_ibufs = GET_PCAP(USER_INDEX_BUFFERS);
+    This->driver_caps.user_vbufs = GET_PCAP(USER_VERTEX_BUFFERS);
+    This->driver_caps.user_ibufs = GET_PCAP(USER_INDEX_BUFFERS);
+    This->driver_caps.user_cbufs = GET_PCAP(USER_CONSTANT_BUFFERS);
 
-        if (!This->driver_caps.user_vbufs) bind |= PIPE_BIND_VERTEX_BUFFER;
-        if (!This->driver_caps.user_ibufs) bind |= PIPE_BIND_INDEX_BUFFER;
-        if (bind)
-            This->upload = u_upload_create(This->pipe, 1 << 20, 4, bind);
+    if (!This->driver_caps.user_vbufs)
+        This->vertex_uploader = u_upload_create(This->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER);
+    if (!This->driver_caps.user_ibufs)
+        This->index_uploader = u_upload_create(This->pipe, 128 * 1024, 4, PIPE_BIND_INDEX_BUFFER);
+    if (!This->driver_caps.user_cbufs) {
+        unsigned alignment = GET_PCAP(CONSTANT_BUFFER_OFFSET_ALIGNMENT);
+
+        This->constbuf_uploader = u_upload_create(This->pipe, This->vs_const_size,
+                                                  alignment, PIPE_BIND_CONSTANT_BUFFER);
     }
 
     This->driver_caps.window_space_position_support = GET_PCAP(TGSI_VS_WINDOW_SPACE_POSITION);
@@ -454,8 +478,12 @@ NineDevice9_dtor( struct NineDevice9 *This )
     nine_ff_fini(This);
     nine_state_clear(&This->state, TRUE);
 
-    if (This->upload)
-        u_upload_destroy(This->upload);
+    if (This->vertex_uploader)
+        u_upload_destroy(This->vertex_uploader);
+    if (This->index_uploader)
+        u_upload_destroy(This->index_uploader);
+    if (This->constbuf_uploader)
+        u_upload_destroy(This->constbuf_uploader);
 
     nine_bind(&This->record, NULL);
 
@@ -2963,13 +2991,16 @@ NineDevice9_DrawPrimitiveUP( struct NineDevice9 *This,
     vtxbuf.buffer = NULL;
     vtxbuf.user_buffer = pVertexStreamZeroData;
 
-    if (!This->driver_caps.user_vbufs)
-        u_upload_data(This->upload,
+    if (!This->driver_caps.user_vbufs) {
+        u_upload_data(This->vertex_uploader,
                       0,
                       (info.max_index + 1) * VertexStreamZeroStride, /* XXX */
                       vtxbuf.user_buffer,
                       &vtxbuf.buffer_offset,
                       &vtxbuf.buffer);
+        u_upload_unmap(This->vertex_uploader);
+        vtxbuf.user_buffer = NULL;
+    }
 
     This->pipe->set_vertex_buffers(This->pipe, 0, 1, &vtxbuf);
 
@@ -3032,23 +3063,28 @@ NineDevice9_DrawIndexedPrimitiveUP( struct NineDevice9 *This,
 
     if (!This->driver_caps.user_vbufs) {
         const unsigned base = info.min_index * VertexStreamZeroStride;
-        u_upload_data(This->upload,
+        u_upload_data(This->vertex_uploader,
                       base,
                       (info.max_index -
                        info.min_index + 1) * VertexStreamZeroStride, /* XXX */
                       (const uint8_t *)vbuf.user_buffer + base,
                       &vbuf.buffer_offset,
                       &vbuf.buffer);
+        u_upload_unmap(This->vertex_uploader);
         /* Won't be used: */
         vbuf.buffer_offset -= base;
+        vbuf.user_buffer = NULL;
     }
-    if (!This->driver_caps.user_ibufs)
-        u_upload_data(This->upload,
+    if (!This->driver_caps.user_ibufs) {
+        u_upload_data(This->index_uploader,
                       0,
                       info.count * ibuf.index_size,
                       ibuf.user_buffer,
                       &ibuf.offset,
                       &ibuf.buffer);
+        u_upload_unmap(This->index_uploader);
+        ibuf.user_buffer = NULL;
+    }
 
     This->pipe->set_vertex_buffers(This->pipe, 0, 1, &vbuf);
     This->pipe->set_index_buffer(This->pipe, &ibuf);
index a5a5ab2391db8f7f61e5f43d0d05175230f70b96..8b955a7a7970f2ff3f8c7b3d919a340c91d245fa 100644 (file)
@@ -114,6 +114,7 @@ struct NineDevice9
     struct {
         boolean user_vbufs;
         boolean user_ibufs;
+        boolean user_cbufs;
         boolean window_space_position_support;
         boolean vs_integer;
         boolean ps_integer;
@@ -123,7 +124,9 @@ struct NineDevice9
         boolean buggy_barycentrics;
     } driver_bugs;
 
-    struct u_upload_mgr *upload;
+    struct u_upload_mgr *vertex_uploader;
+    struct u_upload_mgr *index_uploader;
+    struct u_upload_mgr *constbuf_uploader;
 
     struct nine_range_pool range_pool;
 
index 8a53f0d9038db7d50b51515dea3cd929aa58f8b6..ca768648dde566e1a67af3d25eb6f88b89e3f7d7 100644 (file)
@@ -22,6 +22,7 @@
 #include "tgsi/tgsi_dump.h"
 #include "util/u_box.h"
 #include "util/u_hash_table.h"
+#include "util/u_upload_mgr.h"
 
 #define NINE_TGSI_LAZY_DEVS 1
 
@@ -1802,6 +1803,17 @@ nine_ff_update(struct NineDevice9 *device)
             cb.buffer = NULL;
             cb.user_buffer = device->ff.vs_const;
             cb.buffer_size = NINE_FF_NUM_VS_CONST * 4 * sizeof(float);
+
+            if (!device->driver_caps.user_cbufs) {
+                u_upload_data(device->constbuf_uploader,
+                              0,
+                              cb.buffer_size,
+                              cb.user_buffer,
+                              &cb.buffer_offset,
+                              &cb.buffer);
+                u_upload_unmap(device->constbuf_uploader);
+                cb.user_buffer = NULL;
+            }
             pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &cb);
         } else {
             struct pipe_box box;
@@ -1833,6 +1845,17 @@ nine_ff_update(struct NineDevice9 *device)
             cb.buffer = NULL;
             cb.user_buffer = device->ff.ps_const;
             cb.buffer_size = NINE_FF_NUM_PS_CONST * 4 * sizeof(float);
+
+            if (!device->driver_caps.user_cbufs) {
+                u_upload_data(device->constbuf_uploader,
+                              0,
+                              cb.buffer_size,
+                              cb.user_buffer,
+                              &cb.buffer_offset,
+                              &cb.buffer);
+                u_upload_unmap(device->constbuf_uploader);
+                cb.user_buffer = NULL;
+            }
             pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &cb);
         } else {
             struct pipe_box box;
index b29556b56ee6a4615cf446afb2752dc6c0e23d1c..2fb2f7a845afaa7bf8ef3125dc6e8499940c77ac 100644 (file)
@@ -33,6 +33,7 @@
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
 #include "cso_cache/cso_context.h"
+#include "util/u_upload_mgr.h"
 #include "util/u_math.h"
 
 #define DBG_CHANNEL DBG_DEVICE
@@ -567,6 +568,17 @@ update_vs_constants_userbuf(struct NineDevice9 *device)
         cb.user_buffer = dst;
     }
 
+    if (!device->driver_caps.user_cbufs) {
+        u_upload_data(device->constbuf_uploader,
+                      0,
+                      cb.buffer_size,
+                      cb.user_buffer,
+                      &cb.buffer_offset,
+                      &cb.buffer);
+        u_upload_unmap(device->constbuf_uploader);
+        cb.user_buffer = NULL;
+    }
+
     pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &cb);
 
     if (device->state.changed.vs_const_f) {
@@ -615,6 +627,17 @@ update_ps_constants_userbuf(struct NineDevice9 *device)
         cb.user_buffer = device->state.ps_lconstf_temp;
     }
 
+    if (!device->driver_caps.user_cbufs) {
+        u_upload_data(device->constbuf_uploader,
+                      0,
+                      cb.buffer_size,
+                      cb.user_buffer,
+                      &cb.buffer_offset,
+                      &cb.buffer);
+        u_upload_unmap(device->constbuf_uploader);
+        cb.user_buffer = NULL;
+    }
+
     pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &cb);
 
     if (device->state.changed.ps_const_f) {