[PATCH 2/5] wined3d: Don't try to resolve vertex buffer locations in context_stream_info_from_declaration().

Henri Verbeet hverbeet at codeweavers.com
Mon Jul 14 03:04:22 CDT 2014


---
 dlls/wined3d/context.c |   99 ++++++++++++++++++++++--------------------------
 dlls/wined3d/device.c  |   18 +++++----
 2 files changed, 55 insertions(+), 62 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index e8423f4..622cca1 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -2725,7 +2725,6 @@ static BOOL fixed_get_input(BYTE usage, BYTE usage_idx, unsigned int *regnum)
     return TRUE;
 }
 
-/* FIXME: Separate buffer loading from declaration decoding */
 /* Context activation is done by the caller. */
 void context_stream_info_from_declaration(struct wined3d_context *context,
         const struct wined3d_state *state, struct wined3d_stream_info *stream_info)
@@ -2734,11 +2733,9 @@ void context_stream_info_from_declaration(struct wined3d_context *context,
     struct wined3d_vertex_declaration *declaration = state->vertex_declaration;
     BOOL use_vshader = use_vs(state);
     unsigned int i;
-    WORD map;
 
     stream_info->use_map = 0;
     stream_info->swizzle_map = 0;
-    stream_info->all_vbo = 1;
     stream_info->position_transformed = declaration->position_transformed;
 
     /* Translate the declaration into strided data. */
@@ -2746,38 +2743,14 @@ void context_stream_info_from_declaration(struct wined3d_context *context,
     {
         const struct wined3d_vertex_declaration_element *element = &declaration->elements[i];
         const struct wined3d_stream_state *stream = &state->streams[element->input_slot];
-        struct wined3d_buffer *buffer = stream->buffer;
-        struct wined3d_bo_address data;
         BOOL stride_used;
         unsigned int idx;
-        DWORD stride;
 
         TRACE("%p Element %p (%u of %u).\n", declaration->elements,
                 element, i + 1, declaration->element_count);
 
-        if (!buffer) continue;
-
-        stride = stream->stride;
-        TRACE("Stream %u in buffer %p.\n", element->input_slot, buffer);
-        buffer_get_memory(buffer, context, &data);
-
-        /* Can't use vbo's if the base vertex index is negative. OpenGL doesn't accept negative offsets
-         * (or rather offsets bigger than the vbo, because the pointer is unsigned), so use system memory
-         * sources. In most sane cases the pointer - offset will still be > 0, otherwise it will wrap
-         * around to some big value. Hope that with the indices, the driver wraps it back internally. If
-         * not, drawStridedSlow is needed, including a vertex buffer path. */
-        if (state->load_base_vertex_index < 0)
-        {
-            WARN_(d3d_perf)("load_base_vertex_index is < 0 (%d), not using VBOs.\n",
-                    state->load_base_vertex_index);
-            data.buffer_object = 0;
-            data.addr = buffer_get_sysmem(buffer, context);
-            if ((UINT_PTR)data.addr < -state->load_base_vertex_index * stride)
-            {
-                FIXME("System memory vertex data load offset is negative!\n");
-            }
-        }
-        data.addr += element->offset;
+        if (!stream->buffer)
+            continue;
 
         TRACE("offset %u input_slot %u usage_idx %d.\n", element->offset, element->input_slot, element->usage_idx);
 
@@ -2814,16 +2787,15 @@ void context_stream_info_from_declaration(struct wined3d_context *context,
         if (stride_used)
         {
             TRACE("Load %s array %u [usage %s, usage_idx %u, "
-                    "input_slot %u, offset %u, stride %u, format %s, buffer_object %u].\n",
+                    "input_slot %u, offset %u, stride %u, format %s].\n",
                     use_vshader ? "shader": "fixed function", idx,
                     debug_d3ddeclusage(element->usage), element->usage_idx, element->input_slot,
-                    element->offset, stride, debug_d3dformat(element->format->id), data.buffer_object);
-
-            data.addr += stream->offset;
+                    element->offset, stream->stride, debug_d3dformat(element->format->id));
 
             stream_info->elements[idx].format = element->format;
-            stream_info->elements[idx].data = data;
-            stream_info->elements[idx].stride = stride;
+            stream_info->elements[idx].data.buffer_object = 0;
+            stream_info->elements[idx].data.addr = (BYTE *)stream->offset + element->offset;
+            stream_info->elements[idx].stride = stream->stride;
             stream_info->elements[idx].stream_idx = element->input_slot;
 
             if (!context->gl_info->supported[ARB_VERTEX_ARRAY_BGRA]
@@ -2834,12 +2806,26 @@ void context_stream_info_from_declaration(struct wined3d_context *context,
             stream_info->use_map |= 1 << idx;
         }
     }
+}
 
-    /* Preload the vertex buffers. */
+/* Context activation is done by the caller. */
+static void context_update_stream_info(struct wined3d_context *context, const struct wined3d_state *state)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+    struct wined3d_stream_info *stream_info = &context->stream_info;
+    DWORD prev_all_vbo = stream_info->all_vbo;
+    unsigned int i;
+    WORD map;
+
+    context_stream_info_from_declaration(context, state, stream_info);
+
+    stream_info->all_vbo = 1;
     context->num_buffer_queries = 0;
     for (i = 0, map = stream_info->use_map; map; map >>= 1, ++i)
     {
         struct wined3d_stream_info_element *element;
+        struct wined3d_bo_address data;
         struct wined3d_buffer *buffer;
 
         if (!(map & 1))
@@ -2847,34 +2833,39 @@ void context_stream_info_from_declaration(struct wined3d_context *context,
 
         element = &stream_info->elements[i];
         buffer = state->streams[element->stream_idx].buffer;
-        buffer_internal_preload(buffer, context, state);
 
-        /* If the preload dropped the buffer object, update the stream info. */
-        if (buffer->buffer_object != element->data.buffer_object)
+        /* We can't use VBOs if the base vertex index is negative. OpenGL
+         * doesn't accept negative offsets (or rather offsets bigger than the
+         * VBO, because the pointer is unsigned), so use system memory
+         * sources. In most sane cases the pointer - offset will still be > 0,
+         * otherwise it will wrap around to some big value. Hope that with the
+         * indices the driver wraps it back internally. If not,
+         * drawStridedSlow is needed, including a vertex buffer path. */
+        if (state->load_base_vertex_index < 0)
         {
+            WARN_(d3d_perf)("load_base_vertex_index is < 0 (%d), not using VBOs.\n",
+                    state->load_base_vertex_index);
             element->data.buffer_object = 0;
-            element->data.addr = buffer_get_sysmem(buffer, context)
-                    + (ptrdiff_t)element->data.addr;
+            element->data.addr += (ULONG_PTR)buffer_get_sysmem(buffer, context);
+            if ((UINT_PTR)element->data.addr < -state->load_base_vertex_index * element->stride)
+                FIXME("System memory vertex data load offset is negative!\n");
+        }
+        else
+        {
+            buffer_internal_preload(buffer, context, state);
+            buffer_get_memory(buffer, context, &data);
+            element->data.buffer_object = data.buffer_object;
+            element->data.addr += (ULONG_PTR)data.addr;
         }
 
-        if (!buffer->buffer_object)
+        if (!element->data.buffer_object)
             stream_info->all_vbo = 0;
 
         if (buffer->query)
             context->buffer_queries[context->num_buffer_queries++] = buffer->query;
-    }
-}
-
-/* Context activation is done by the caller. */
-static void context_update_stream_info(struct wined3d_context *context, const struct wined3d_state *state)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    const struct wined3d_d3d_info *d3d_info = context->d3d_info;
-    struct wined3d_stream_info *stream_info = &context->stream_info;
-    DWORD prev_all_vbo = stream_info->all_vbo;
 
-    TRACE("============================= Vertex Declaration =============================\n");
-    context_stream_info_from_declaration(context, state, stream_info);
+        TRACE("Load array %u {%#x:%p}.\n", i, element->data.buffer_object, element->data.addr);
+    }
 
     if (use_vs(state))
     {
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 65f4ad7..4aacf1d 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -2870,6 +2870,7 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device,
     struct wined3d_shader *vs;
     unsigned int i;
     HRESULT hr;
+    WORD map;
 
     TRACE("device %p, src_start_idx %u, dst_idx %u, vertex_count %u, "
             "dst_buffer %p, declaration %p, flags %#x, dst_fvf %#x.\n",
@@ -2893,21 +2894,22 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device,
      * VBOs in those buffers and fix up the stream_info structure.
      *
      * Also apply the start index. */
-    for (i = 0; i < (sizeof(stream_info.elements) / sizeof(*stream_info.elements)); ++i)
+    for (i = 0, map = stream_info.use_map; map; map >>= 1, ++i)
     {
         struct wined3d_stream_info_element *e;
+        struct wined3d_buffer *buffer;
 
-        if (!(stream_info.use_map & (1 << i)))
+        if (!(map & 1))
             continue;
 
         e = &stream_info.elements[i];
-        if (e->data.buffer_object)
+        buffer = state->streams[e->stream_idx].buffer;
+        e->data.buffer_object = 0;
+        e->data.addr += (ULONG_PTR)buffer_get_sysmem(buffer, context);
+        if (buffer->buffer_object)
         {
-            struct wined3d_buffer *vb = state->streams[e->stream_idx].buffer;
-            e->data.buffer_object = 0;
-            e->data.addr = (BYTE *)((ULONG_PTR)e->data.addr + (ULONG_PTR)buffer_get_sysmem(vb, context));
-            GL_EXTCALL(glDeleteBuffersARB(1, &vb->buffer_object));
-            vb->buffer_object = 0;
+            GL_EXTCALL(glDeleteBuffersARB(1, &buffer->buffer_object));
+            buffer->buffer_object = 0;
         }
         if (e->data.addr)
             e->data.addr += e->stride * src_start_idx;
-- 
1.7.10.4




More information about the wine-patches mailing list