wined3d: Use struct wined3d_ffp_attrib_ops for generic attributes as well.

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
oldstable
Henri Verbeet 2016-04-06 19:12:04 +02:00 committed by Alexandre Julliard
parent e686b5a62f
commit eeac4013cd
3 changed files with 86 additions and 113 deletions

View File

@ -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)

View File

@ -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])

View File

@ -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