[PATCH 3/6] wined3d: Use struct wined3d_ffp_attrib_ops for generic attributes as well.

Henri Verbeet hverbeet at codeweavers.com
Wed Apr 6 12:12:04 CDT 2016


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/wined3d/directx.c         |  80 ++++++++++++++++++++++++++++
 dlls/wined3d/drawprim.c        | 117 ++---------------------------------------
 dlls/wined3d/wined3d_private.h |   2 +
 3 files changed, 86 insertions(+), 113 deletions(-)

diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index c6af487..f3d19f4 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -5599,6 +5599,12 @@ static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data)
     DebugBreak();
 }
 
+static void WINE_GLAPI invalid_generic_attrib_func(GLuint idx, const void *data)
+{
+    ERR("Invalid attribute function called.\n");
+    DebugBreak();
+}
+
 /* Helper functions for providing vertex data to opengl. The arrays are initialized based on
  * the extension detection and are used in drawStridedSlow
  */
@@ -5657,6 +5663,47 @@ static void WINE_GLAPI warn_no_specular_func(const void *data)
     WARN("GL_EXT_secondary_color not supported\n");
 }
 
+static void WINE_GLAPI generic_d3dcolor(GLuint idx, const void *data)
+{
+    DWORD color = *((const DWORD *)data);
+
+    context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4Nub(idx,
+            D3DCOLOR_B_R(color), D3DCOLOR_B_G(color),
+            D3DCOLOR_B_B(color), D3DCOLOR_B_A(color));
+}
+
+static void WINE_GLAPI generic_short2n(GLuint idx, const void *data)
+{
+    const GLshort s[] = {((const GLshort *)data)[0], ((const GLshort *)data)[1], 0, 1};
+
+    context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4Nsv(idx, s);
+}
+
+static void WINE_GLAPI generic_ushort2n(GLuint idx, const void *data)
+{
+    const GLushort s[] = {((const GLushort *)data)[0], ((const GLushort *)data)[1], 0, 1};
+
+    context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4Nusv(idx, s);
+}
+
+static void WINE_GLAPI generic_float16_2(GLuint idx, const void *data)
+{
+    float x = float_16_to_32(((const unsigned short *)data) + 0);
+    float y = float_16_to_32(((const unsigned short *)data) + 1);
+
+    context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib2f(idx, x, y);
+}
+
+static void WINE_GLAPI generic_float16_4(GLuint idx, const void *data)
+{
+    float x = float_16_to_32(((const unsigned short *)data) + 0);
+    float y = float_16_to_32(((const unsigned short *)data) + 1);
+    float z = float_16_to_32(((const unsigned short *)data) + 2);
+    float w = float_16_to_32(((const unsigned short *)data) + 3);
+
+    context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4f(idx, x, y, z, w);
+}
+
 static void wined3d_adapter_init_ffp_attrib_ops(struct wined3d_adapter *adapter)
 {
     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
@@ -5782,6 +5829,39 @@ static void wined3d_adapter_init_ffp_attrib_ops(struct wined3d_adapter *adapter)
         ops->texcoord[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_texcoord_func;
     }
     ops->texcoord[WINED3D_FFP_EMIT_INVALID]   = invalid_texcoord_func;
+
+    ops->generic[WINED3D_FFP_EMIT_FLOAT1]     = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib1fv;
+    ops->generic[WINED3D_FFP_EMIT_FLOAT2]     = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib2fv;
+    ops->generic[WINED3D_FFP_EMIT_FLOAT3]     = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib3fv;
+    ops->generic[WINED3D_FFP_EMIT_FLOAT4]     = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4fv;
+    if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
+        ops->generic[WINED3D_FFP_EMIT_D3DCOLOR] = generic_d3dcolor;
+    else
+        ops->generic[WINED3D_FFP_EMIT_D3DCOLOR] =
+                (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nubv;
+    ops->generic[WINED3D_FFP_EMIT_UBYTE4]     = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4ubv;
+    ops->generic[WINED3D_FFP_EMIT_SHORT2]     = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib2sv;
+    ops->generic[WINED3D_FFP_EMIT_SHORT4]     = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4sv;
+    ops->generic[WINED3D_FFP_EMIT_UBYTE4N]    = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nubv;
+    ops->generic[WINED3D_FFP_EMIT_SHORT2N]    = generic_short2n;
+    ops->generic[WINED3D_FFP_EMIT_SHORT4N]    = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nsv;
+    ops->generic[WINED3D_FFP_EMIT_USHORT2N]   = generic_ushort2n;
+    ops->generic[WINED3D_FFP_EMIT_USHORT4N]   = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nusv;
+    ops->generic[WINED3D_FFP_EMIT_UDEC3]      = invalid_generic_attrib_func;
+    ops->generic[WINED3D_FFP_EMIT_DEC3N]      = invalid_generic_attrib_func;
+    if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM])
+    {
+        ops->generic[WINED3D_FFP_EMIT_FLOAT16_2] =
+                (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib2hvNV;
+        ops->generic[WINED3D_FFP_EMIT_FLOAT16_4] =
+                (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4hvNV;
+    }
+    else
+    {
+        ops->generic[WINED3D_FFP_EMIT_FLOAT16_2] = generic_float16_2;
+        ops->generic[WINED3D_FFP_EMIT_FLOAT16_4] = generic_float16_4;
+    }
+    ops->generic[WINED3D_FFP_EMIT_INVALID]    = invalid_generic_attrib_func;
 }
 
 static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc)
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 41e8a00..73741fa 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -338,120 +338,11 @@ static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_
 }
 
 /* Context activation is done by the caller. */
-static inline void send_attribute(const struct wined3d_gl_info *gl_info,
-        enum wined3d_format_id format, const UINT index, const void *ptr)
-{
-    switch(format)
-    {
-        case WINED3DFMT_R32_FLOAT:
-            GL_EXTCALL(glVertexAttrib1fv(index, ptr));
-            break;
-        case WINED3DFMT_R32G32_FLOAT:
-            GL_EXTCALL(glVertexAttrib2fv(index, ptr));
-            break;
-        case WINED3DFMT_R32G32B32_FLOAT:
-            GL_EXTCALL(glVertexAttrib3fv(index, ptr));
-            break;
-        case WINED3DFMT_R32G32B32A32_FLOAT:
-            GL_EXTCALL(glVertexAttrib4fv(index, ptr));
-            break;
-
-        case WINED3DFMT_R8G8B8A8_UINT:
-            GL_EXTCALL(glVertexAttrib4ubv(index, ptr));
-            break;
-        case WINED3DFMT_B8G8R8A8_UNORM:
-            if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
-            {
-                const DWORD *src = ptr;
-                DWORD c = *src & 0xff00ff00u;
-                c |= (*src & 0xff0000u) >> 16;
-                c |= (*src & 0xffu) << 16;
-                GL_EXTCALL(glVertexAttrib4Nubv(index, (GLubyte *)&c));
-                break;
-            }
-            /* else fallthrough */
-        case WINED3DFMT_R8G8B8A8_UNORM:
-            GL_EXTCALL(glVertexAttrib4Nubv(index, ptr));
-            break;
-
-        case WINED3DFMT_R16G16_SINT:
-            GL_EXTCALL(glVertexAttrib2sv(index, ptr));
-            break;
-        case WINED3DFMT_R16G16B16A16_SINT:
-            GL_EXTCALL(glVertexAttrib4sv(index, ptr));
-            break;
-
-        case WINED3DFMT_R16G16_SNORM:
-        {
-            GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
-            GL_EXTCALL(glVertexAttrib4Nsv(index, s));
-            break;
-        }
-        case WINED3DFMT_R16G16_UNORM:
-        {
-            GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
-            GL_EXTCALL(glVertexAttrib4Nusv(index, s));
-            break;
-        }
-        case WINED3DFMT_R16G16B16A16_SNORM:
-            GL_EXTCALL(glVertexAttrib4Nsv(index, ptr));
-            break;
-        case WINED3DFMT_R16G16B16A16_UNORM:
-            GL_EXTCALL(glVertexAttrib4Nusv(index, ptr));
-            break;
-
-        case WINED3DFMT_R10G10B10A2_UINT:
-            FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
-            /*glVertexAttrib3usvARB(instancedData[j], (GLushort *) ptr); Does not exist */
-            break;
-        case WINED3DFMT_R10G10B10A2_SNORM:
-            FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
-            /*glVertexAttrib3NusvARB(instancedData[j], (GLushort *) ptr); Does not exist */
-            break;
-
-        case WINED3DFMT_R16G16_FLOAT:
-            /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
-             * byte float according to the IEEE standard
-             */
-            if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM])
-            {
-                /* Not supported by GL_ARB_half_float_vertex */
-                GL_EXTCALL(glVertexAttrib2hvNV(index, ptr));
-            }
-            else
-            {
-                float x = float_16_to_32(((const unsigned short *)ptr) + 0);
-                float y = float_16_to_32(((const unsigned short *)ptr) + 1);
-                GL_EXTCALL(glVertexAttrib2f(index, x, y));
-            }
-            break;
-        case WINED3DFMT_R16G16B16A16_FLOAT:
-            if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM])
-            {
-                /* Not supported by GL_ARB_half_float_vertex */
-                GL_EXTCALL(glVertexAttrib4hvNV(index, ptr));
-            }
-            else
-            {
-                float x = float_16_to_32(((const unsigned short *)ptr) + 0);
-                float y = float_16_to_32(((const unsigned short *)ptr) + 1);
-                float z = float_16_to_32(((const unsigned short *)ptr) + 2);
-                float w = float_16_to_32(((const unsigned short *)ptr) + 3);
-                GL_EXTCALL(glVertexAttrib4f(index, x, y, z, w));
-            }
-            break;
-
-        default:
-            ERR("Unexpected attribute format: %s\n", debug_d3dformat(format));
-            break;
-    }
-}
-
-/* Context activation is done by the caller. */
 static void drawStridedSlowVs(struct wined3d_context *context, const struct wined3d_state *state,
         const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType,
         const void *idxData, UINT idxSize, UINT startIdx)
 {
+    const struct wined3d_ffp_attrib_ops *ops = &context->d3d_info->ffp_attrib_ops;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     LONG SkipnStrides = startIdx + state->load_base_vertex_index;
     const DWORD *pIdxBufL = NULL;
@@ -495,8 +386,7 @@ static void drawStridedSlowVs(struct wined3d_context *context, const struct wine
             if (!(si->use_map & (1u << i))) continue;
 
             ptr = si->elements[i].data.addr + si->elements[i].stride * SkipnStrides;
-
-            send_attribute(gl_info, si->elements[i].format->id, i, ptr);
+            ops->generic[si->elements[i].format->emit_idx](i, ptr);
         }
         SkipnStrides++;
     }
@@ -509,6 +399,7 @@ static void drawStridedInstanced(struct wined3d_context *context, const struct w
         const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType,
         const void *idxData, UINT idxSize, UINT startIdx, UINT base_vertex_index, UINT instance_count)
 {
+    const struct wined3d_ffp_attrib_ops *ops = &context->d3d_info->ffp_attrib_ops;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     int numInstancedAttribs = 0, j;
     UINT instancedData[sizeof(si->elements) / sizeof(*si->elements) /* 16 */];
@@ -550,7 +441,7 @@ static void drawStridedInstanced(struct wined3d_context *context, const struct w
                 ptr += (ULONG_PTR)buffer_get_sysmem(vb, context);
             }
 
-            send_attribute(gl_info, si->elements[instancedData[j]].format->id, instancedData[j], ptr);
+            ops->generic[si->elements[instancedData[j]].format->emit_idx](instancedData[j], ptr);
         }
 
         if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX])
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 2161c42..b86a8eb 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1949,6 +1949,7 @@ struct wined3d_d3d_limits
 
 typedef void (WINE_GLAPI *wined3d_ffp_attrib_func)(const void *data);
 typedef void (WINE_GLAPI *wined3d_ffp_texcoord_func)(GLenum unit, const void *data);
+typedef void (WINE_GLAPI *wined3d_generic_attrib_func)(GLuint idx, const void *data);
 extern wined3d_ffp_attrib_func specular_func_3ubv DECLSPEC_HIDDEN;
 
 struct wined3d_ffp_attrib_ops
@@ -1958,6 +1959,7 @@ struct wined3d_ffp_attrib_ops
     wined3d_ffp_attrib_func specular[WINED3D_FFP_EMIT_COUNT];
     wined3d_ffp_attrib_func normal[WINED3D_FFP_EMIT_COUNT];
     wined3d_ffp_texcoord_func texcoord[WINED3D_FFP_EMIT_COUNT];
+    wined3d_generic_attrib_func generic[WINED3D_FFP_EMIT_COUNT];
 };
 
 struct wined3d_d3d_info
-- 
2.1.4




More information about the wine-patches mailing list