From b1812c690c52c568222963da77a9c427b704197e Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 8 Jan 2009 10:19:17 +0100 Subject: [PATCH] wined3d: Add support for EXT_vertex_array_bgra. This allows us to skip BGRA->RGBA color conversion for vertex attributes if this extension is present. --- dlls/wined3d/directx.c | 1 + dlls/wined3d/drawprim.c | 5 +++- dlls/wined3d/state.c | 26 ++++++++++---------- dlls/wined3d/utils.c | 44 ++++++++++++++++++++-------------- dlls/wined3d/vertexbuffer.c | 5 ++-- dlls/wined3d/wined3d_gl.h | 2 ++ dlls/wined3d/wined3d_private.h | 1 + 7 files changed, 50 insertions(+), 34 deletions(-) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index e505ec0f1c7..456aa07e328 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -114,6 +114,7 @@ static const struct { {"GL_EXT_texture_filter_anisotropic", EXT_TEXTURE_FILTER_ANISOTROPIC, 0 }, {"GL_EXT_texture_lod", EXT_TEXTURE_LOD, 0 }, {"GL_EXT_texture_lod_bias", EXT_TEXTURE_LOD_BIAS, 0 }, + {"GL_EXT_vertex_array_bgra", EXT_VERTEX_ARRAY_BGRA, 0 }, {"GL_EXT_vertex_shader", EXT_VERTEX_SHADER, 0 }, {"GL_EXT_gpu_program_parameters", EXT_GPU_PROGRAM_PARAMETERS, 0 }, diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index 70ba80b1af3..40d008a5ba0 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -235,7 +235,10 @@ void primitiveDeclarationConvertToStridedData( strided->u.input[idx].dwStride = stride; strided->u.input[idx].VBO = streamVBO; strided->u.input[idx].streamNo = element->Stream; - if (element->Type == WINED3DDECLTYPE_D3DCOLOR) strided->swizzle_map |= 1 << idx; + if (!GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) && element->Type == WINED3DDECLTYPE_D3DCOLOR) + { + strided->swizzle_map |= 1 << idx; + } strided->use_map |= 1 << idx; } } diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 7258ed3acb3..5c999b88d80 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3114,7 +3114,7 @@ static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, const WineDirect3D /* The coords to supply depend completely on the fvf / vertex shader */ glTexCoordPointer( - WINED3D_ATR_SIZE(sd->u.s.texCoords[coordIdx].dwType), + WINED3D_ATR_FORMAT(sd->u.s.texCoords[coordIdx].dwType), WINED3D_ATR_GLTYPE(sd->u.s.texCoords[coordIdx].dwType), sd->u.s.texCoords[coordIdx].dwStride, sd->u.s.texCoords[coordIdx].lpData + stateblock->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride + offset[sd->u.s.texCoords[coordIdx].streamNo]); @@ -3934,7 +3934,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, shift_index = ((DWORD_PTR) strided->u.input[i].lpData + offset[strided->u.input[i].streamNo]); shift_index = shift_index % strided->u.input[i].dwStride; GL_EXTCALL(glVertexAttribPointerARB(i, - WINED3D_ATR_SIZE(strided->u.input[i].dwType), + WINED3D_ATR_FORMAT(strided->u.input[i].dwType), WINED3D_ATR_GLTYPE(strided->u.input[i].dwType), WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType), vb->conv_stride, @@ -3945,7 +3945,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, } else { GL_EXTCALL(glVertexAttribPointerARB(i, - WINED3D_ATR_SIZE(strided->u.input[i].dwType), + WINED3D_ATR_FORMAT(strided->u.input[i].dwType), WINED3D_ATR_GLTYPE(strided->u.input[i].dwType), WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType), strided->u.input[i].dwStride, @@ -4066,16 +4066,16 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3 (sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO) ) { if (GL_SUPPORT(ARB_VERTEX_BLEND)) { - TRACE("Blend %d %p %d\n", WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType), + TRACE("Blend %d %p %d\n", WINED3D_ATR_FORMAT(sd->u.s.blendWeights.dwType), sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]); glEnableClientState(GL_WEIGHT_ARRAY_ARB); checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)"); - GL_EXTCALL(glVertexBlendARB(WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) + 1)); + GL_EXTCALL(glVertexBlendARB(WINED3D_ATR_FORMAT(sd->u.s.blendWeights.dwType) + 1)); VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n", - WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) , + WINED3D_ATR_FORMAT(sd->u.s.blendWeights.dwType) , sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo])); @@ -4086,7 +4086,7 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3 } GL_EXTCALL(glWeightPointerARB)( - WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType), + WINED3D_ATR_FORMAT(sd->u.s.blendWeights.dwType), WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType), sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]); @@ -4138,7 +4138,7 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3 curVBO = sd->u.s.position.VBO; } - /* min(WINED3D_ATR_SIZE(position),3) to Disable RHW mode as 'w' coord + /* min(WINED3D_ATR_FORMAT(position),3) to Disable RHW mode as 'w' coord handling for rhw mode should not impact screen position whereas in GL it does. This may result in very slightly distorted textures in rhw mode. There's always the other option of fixing the view matrix to @@ -4147,12 +4147,12 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3 This only applies to user pointer sources, in VBOs the vertices are fixed up */ if(sd->u.s.position.VBO == 0) { - glVertexPointer(3 /* min(WINED3D_ATR_SIZE(sd->u.s.position.dwType),3) */, + glVertexPointer(3 /* min(WINED3D_ATR_FORMAT(sd->u.s.position.dwType),3) */, WINED3D_ATR_GLTYPE(sd->u.s.position.dwType), sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]); } else { glVertexPointer( - WINED3D_ATR_SIZE(sd->u.s.position.dwType), + WINED3D_ATR_FORMAT(sd->u.s.position.dwType), WINED3D_ATR_GLTYPE(sd->u.s.position.dwType), sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]); } @@ -4206,7 +4206,7 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3 curVBO = sd->u.s.diffuse.VBO; } - glColorPointer(WINED3D_ATR_SIZE(sd->u.s.diffuse.dwType), + glColorPointer(WINED3D_ATR_FORMAT(sd->u.s.diffuse.dwType), WINED3D_ATR_GLTYPE(sd->u.s.diffuse.dwType), sd->u.s.diffuse.dwStride, sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride + offset[sd->u.s.diffuse.streamNo]); @@ -4232,7 +4232,7 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3 checkGLcall("glBindBufferARB"); curVBO = sd->u.s.specular.VBO; } - GL_EXTCALL(glSecondaryColorPointerEXT)(WINED3D_ATR_SIZE(sd->u.s.specular.dwType), + GL_EXTCALL(glSecondaryColorPointerEXT)(WINED3D_ATR_FORMAT(sd->u.s.specular.dwType), WINED3D_ATR_GLTYPE(sd->u.s.specular.dwType), sd->u.s.specular.dwStride, sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride + offset[sd->u.s.specular.streamNo]); @@ -4331,7 +4331,7 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo load_numbered = TRUE; device->useDrawStridedSlow = FALSE; } - } else if (fixup || + } else if (fixup || GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) || (dataLocations->u.s.pSize.lpData == NULL && dataLocations->u.s.diffuse.lpData == NULL && dataLocations->u.s.specular.lpData == NULL)) { diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 67ab32b7c17..0acd3b46d18 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -482,27 +482,35 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info) } /* NOTE: Make sure these are in the correct numerical order. (see /include/wined3d_types.h) */ -static WINED3DGLTYPE const glTypeLookupTemplate[WINED3DDECLTYPE_UNUSED] = { - {WINED3DDECLTYPE_FLOAT1, 1, GL_FLOAT , GL_FALSE ,sizeof(float)}, - {WINED3DDECLTYPE_FLOAT2, 2, GL_FLOAT , GL_FALSE ,sizeof(float)}, - {WINED3DDECLTYPE_FLOAT3, 3, GL_FLOAT , GL_FALSE ,sizeof(float)}, - {WINED3DDECLTYPE_FLOAT4, 4, GL_FLOAT , GL_FALSE ,sizeof(float)}, - {WINED3DDECLTYPE_D3DCOLOR, 4, GL_UNSIGNED_BYTE , GL_TRUE ,sizeof(BYTE)}, - {WINED3DDECLTYPE_UBYTE4, 4, GL_UNSIGNED_BYTE , GL_FALSE ,sizeof(BYTE)}, - {WINED3DDECLTYPE_SHORT2, 2, GL_SHORT , GL_FALSE ,sizeof(short int)}, - {WINED3DDECLTYPE_SHORT4, 4, GL_SHORT , GL_FALSE ,sizeof(short int)}, - {WINED3DDECLTYPE_UBYTE4N, 4, GL_UNSIGNED_BYTE , GL_TRUE ,sizeof(BYTE)}, - {WINED3DDECLTYPE_SHORT2N, 2, GL_SHORT , GL_TRUE ,sizeof(short int)}, - {WINED3DDECLTYPE_SHORT4N, 4, GL_SHORT , GL_TRUE ,sizeof(short int)}, - {WINED3DDECLTYPE_USHORT2N, 2, GL_UNSIGNED_SHORT , GL_TRUE ,sizeof(short int)}, - {WINED3DDECLTYPE_USHORT4N, 4, GL_UNSIGNED_SHORT , GL_TRUE ,sizeof(short int)}, - {WINED3DDECLTYPE_UDEC3, 3, GL_UNSIGNED_SHORT , GL_FALSE ,sizeof(short int)}, - {WINED3DDECLTYPE_DEC3N, 3, GL_SHORT , GL_TRUE ,sizeof(short int)}, - {WINED3DDECLTYPE_FLOAT16_2, 2, GL_HALF_FLOAT_NV , GL_FALSE ,sizeof(GLhalfNV)}, - {WINED3DDECLTYPE_FLOAT16_4, 4, GL_HALF_FLOAT_NV , GL_FALSE ,sizeof(GLhalfNV)}}; +static WINED3DGLTYPE const glTypeLookupTemplate[WINED3DDECLTYPE_UNUSED] = +{ + {WINED3DDECLTYPE_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)}, + {WINED3DDECLTYPE_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)}, + {WINED3DDECLTYPE_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)}, + {WINED3DDECLTYPE_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)}, + {WINED3DDECLTYPE_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)}, + {WINED3DDECLTYPE_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)}, + {WINED3DDECLTYPE_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)}, + {WINED3DDECLTYPE_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)}, + {WINED3DDECLTYPE_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)}, + {WINED3DDECLTYPE_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)}, + {WINED3DDECLTYPE_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)}, + {WINED3DDECLTYPE_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)}, + {WINED3DDECLTYPE_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)}, + {WINED3DDECLTYPE_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)}, + {WINED3DDECLTYPE_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)}, + {WINED3DDECLTYPE_FLOAT16_2, 2, GL_HALF_FLOAT_NV, 2, GL_FALSE, sizeof(GLhalfNV)}, + {WINED3DDECLTYPE_FLOAT16_4, 4, GL_HALF_FLOAT_NV, 4, GL_FALSE, sizeof(GLhalfNV)} +}; void init_type_lookup(WineD3D_GL_Info *gl_info) { memcpy(gl_info->glTypeLookup, glTypeLookupTemplate, sizeof(glTypeLookupTemplate)); + + if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA)) + { + gl_info->glTypeLookup[WINED3DDECLTYPE_D3DCOLOR].format = GL_BGRA; + } + if(!GL_SUPPORT(NV_HALF_FLOAT)) { /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though. * It is the job of the vertex buffer code to make sure that the vbos have the right format diff --git a/dlls/wined3d/vertexbuffer.c b/dlls/wined3d/vertexbuffer.c index b0a6296b731..0408819122c 100644 --- a/dlls/wined3d/vertexbuffer.c +++ b/dlls/wined3d/vertexbuffer.c @@ -364,10 +364,11 @@ static inline BOOL IWineD3DVertexBufferImpl_FindDecl(IWineD3DVertexBufferImpl *T * FLOAT16s if not supported. Also, we can't iterate over the array, so use macros to generate code for all * the attributes that our current fixed function pipeline implementation cares for. */ + BOOL support_d3dcolor = GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA); ret = check_attribute(This, &device->strided_streams.u.s.position, TRUE, TRUE, FALSE, &stride_this_run, &float16_used) || ret; ret = check_attribute(This, &device->strided_streams.u.s.normal, TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = check_attribute(This, &device->strided_streams.u.s.diffuse, TRUE, FALSE, TRUE, &stride_this_run, &float16_used) || ret; - ret = check_attribute(This, &device->strided_streams.u.s.specular, TRUE, FALSE, TRUE, &stride_this_run, &float16_used) || ret; + ret = check_attribute(This, &device->strided_streams.u.s.diffuse, !support_d3dcolor, FALSE, TRUE, &stride_this_run, &float16_used) || ret; + ret = check_attribute(This, &device->strided_streams.u.s.specular, !support_d3dcolor, FALSE, TRUE, &stride_this_run, &float16_used) || ret; ret = check_attribute(This, &device->strided_streams.u.s.texCoords[0], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; ret = check_attribute(This, &device->strided_streams.u.s.texCoords[1], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; ret = check_attribute(This, &device->strided_streams.u.s.texCoords[2], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index 5fccf9a9168..09080a45eb1 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -3383,6 +3383,7 @@ typedef enum _GL_SupportedExt { EXT_TEXTURE_SRGB, EXT_TEXTURE_SWIZZLE, EXT_GPU_PROGRAM_PARAMETERS, + EXT_VERTEX_ARRAY_BGRA, /* NVIDIA */ NV_HALF_FLOAT, NV_FOG_DISTANCE, @@ -3852,6 +3853,7 @@ typedef struct _WINED3DGLTYPE { int d3dType; GLint size; GLenum glType; + GLint format; GLboolean normalized; int typesize; } WINED3DGLTYPE; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 89c5d7769b1..43b1ae0c09c 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -213,6 +213,7 @@ void init_type_lookup(WineD3D_GL_Info *gl_info); #define WINED3D_ATR_TYPE(type) GLINFO_LOCATION.glTypeLookup[type].d3dType #define WINED3D_ATR_SIZE(type) GLINFO_LOCATION.glTypeLookup[type].size #define WINED3D_ATR_GLTYPE(type) GLINFO_LOCATION.glTypeLookup[type].glType +#define WINED3D_ATR_FORMAT(type) GLINFO_LOCATION.glTypeLookup[type].format #define WINED3D_ATR_NORMALIZED(type) GLINFO_LOCATION.glTypeLookup[type].normalized #define WINED3D_ATR_TYPESIZE(type) GLINFO_LOCATION.glTypeLookup[type].typesize