diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 3cb94ce7e90..2ae1efd15c6 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -5602,6 +5602,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 */ @@ -5660,6 +5666,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; @@ -5785,6 +5832,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 41e8a00d007..73741fa00bd 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -337,121 +337,12 @@ static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_ checkGLcall("glEnd and previous calls"); } -/* 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 6a105cba42c..ca1065fb86d 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1950,6 +1950,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 @@ -1959,6 +1960,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