Rico Schüller : d3d10: Improve constant buffer stride and size_unpacked calculation.

Alexandre Julliard julliard at winehq.org
Tue Nov 3 15:37:21 CST 2009


Module: wine
Branch: master
Commit: bd83a874b3261f3f990baaa4d18bd10344bc45d0
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bd83a874b3261f3f990baaa4d18bd10344bc45d0

Author: Rico Schüller <kgbricola at web.de>
Date:   Sun Nov  1 13:42:22 2009 +0100

d3d10: Improve constant buffer stride and size_unpacked calculation.

---

 dlls/d3d10/effect.c |   45 +++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c
index db66806..194f518 100644
--- a/dlls/d3d10/effect.c
+++ b/dlls/d3d10/effect.c
@@ -1156,6 +1156,7 @@ static HRESULT parse_fx10_local_buffer(struct d3d10_effect_variable *l, const ch
     DWORD offset;
     D3D10_CBUFFER_TYPE d3d10_cbuffer_type;
     HRESULT hr;
+    unsigned int stride = 0;
 
     /* Generate our own type, it isn't in the fx blob. */
     l->type = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*l->type));
@@ -1283,9 +1284,49 @@ static HRESULT parse_fx10_local_buffer(struct d3d10_effect_variable *l, const ch
         TRACE("Variable buffer offset: %u.\n", typem->buffer_offset);
 
         l->type->size_packed += v->type->size_packed;
-        l->type->size_unpacked += v->type->size_unpacked;
+
+        /*
+         * For the complete constantbuffer the size_unpacked = stride,
+         * the stride is calculated like this:
+         *
+         * 1) if the constant buffer variables are packed with packoffset
+         *    - stride = the highest used constant
+         *    - the complete stride has to be a multiple of 0x10
+         *
+         * 2) if the constant buffer variables are NOT packed with packoffset
+         *    - sum of unpacked size for all variables which fit in a 0x10 part
+         *    - if the size exceeds a 0x10 part, the rest of the old part is skipped
+         *      and a new part is started
+         *    - if the variable is a struct it is always used a new part
+         *    - the complete stride has to be a multiple of 0x10
+         *
+         *    e.g.:
+         *             0x4, 0x4, 0x4, 0x8, 0x4, 0x14, 0x4
+         *        part 0x10           0x10      0x20     -> 0x40
+         */
+        if (v->flag & D3D10_EFFECT_VARIABLE_EXPLICIT_BIND_POINT)
+        {
+            if ((v->type->size_unpacked + v->buffer_offset) > stride)
+            {
+                stride = v->type->size_unpacked + v->buffer_offset;
+            }
+        }
+        else
+        {
+            if (v->type->type_class == D3D10_SVC_STRUCT)
+            {
+                stride = (stride + 0xf) & ~0xf;
+            }
+
+            if ( ((stride & 0xf) + v->type->size_unpacked) > 0x10)
+            {
+                stride = (stride + 0xf) & ~0xf;
+            }
+
+            stride += v->type->size_unpacked;
+        }
     }
-    l->type->stride = l->type->size_unpacked = (l->type->size_unpacked + 0xf) & ~0xf;
+    l->type->stride = l->type->size_unpacked = (stride + 0xf) & ~0xf;
 
     TRACE("Constant buffer:\n");
     TRACE("\tType name: %s.\n", debugstr_a(l->type->name));




More information about the wine-cvs mailing list