diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index c6a2af5..b374585 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -943,7 +943,7 @@ static HRESULT WINAPI IWineD3DDeviceImp IWineD3DSurfaceImpl *object; /*NOTE: impl ref allowed since this is a create function */ unsigned int pow2Width, pow2Height; unsigned int Size = 1; - const PixelFormatDesc *tableEntry = getFormatDescEntry(Format); + const PixelFormatDesc *tableEntry = getFormatDescEntry(This->stateBlock, Format); TRACE("(%p) Create surface\n",This); /** FIXME: Check ranges on the inputs are valid @@ -1290,7 +1290,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DVolumeImpl *object; /** NOTE: impl ref allowed since this is a create function **/ - const PixelFormatDesc *formatDesc = getFormatDescEntry(Format); + const PixelFormatDesc *formatDesc = getFormatDescEntry(This->stateBlock, Format); D3DCREATERESOURCEOBJECTINSTANCE(object, Volume, WINED3DRTYPE_VOLUME, ((Width * formatDesc->bpp) * Height * Depth)) @@ -2192,7 +2192,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl DEVMODEW DevModeW; int i; - const PixelFormatDesc *formatDesc = getFormatDescEntry(pixelformat); + const PixelFormatDesc *formatDesc = getFormatDescEntry(This->stateBlock, pixelformat); TRACE("(%p)->(%lx,%d,%d,%d,%p,%p)\n", This, Flags, Width, Height, pixelformat, context, callback); @@ -2215,7 +2215,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl DEVMODEW devmode; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; LONG ret; - const PixelFormatDesc *formatDesc = getFormatDescEntry(pMode->Format); + const PixelFormatDesc *formatDesc = getFormatDescEntry(This->stateBlock, pMode->Format); TRACE("(%p)->(%d,%p) Mode=%dx%dx@%d, %s\n", This, iSwapChain, pMode, pMode->Width, pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format)); @@ -4560,8 +4560,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl case WINED3DRS_SRGBWRITEENABLE : { - if(Value) - ERR("(%p)->(%s,%ld) not yet implemented\n", This, debug_d3drenderstate(State), Value); + TRACE("(%p)->(%s,%ld)\n", This, debug_d3drenderstate(State), Value); break; } diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index c413175..196ff0b 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -671,6 +671,9 @@ #undef USE_GL_FUNC } else if (strcmp(ThisExtn, "GL_EXT_texture_env_dot3") == 0) { TRACE_(d3d_caps)(" FOUND: EXT Dot3 support\n"); gl_info->supported[EXT_TEXTURE_ENV_DOT3] = TRUE; + } else if (strcmp(ThisExtn, "GL_EXT_texture_sRGB") == 0) { + TRACE_(d3d_caps)(" FOUND: EXT sRGB support\n"); + gl_info->supported[EXT_TEXTURE_SRGB] = TRUE; } else if (strcmp(ThisExtn, "GL_EXT_texture_filter_anisotropic") == 0) { gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] = TRUE; glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max); @@ -1660,6 +1663,30 @@ static HRESULT WINAPI IWineD3DImpl_Check } } + if (GL_SUPPORT(EXT_TEXTURE_SRGB)) { + switch (CheckFormat) { + case WINED3DFMT_A8R8G8B8: + case WINED3DFMT_X8R8G8B8: + case WINED3DFMT_A8: + case WINED3DFMT_A8B8G8R8: + case WINED3DFMT_X8B8G8R8: + /* Luminance formats */ + case WINED3DFMT_L8: + case WINED3DFMT_A8L8: + /* Compressed formats */ + case D3DFMT_DXT1: + case D3DFMT_DXT2: + case D3DFMT_DXT3: + case D3DFMT_DXT4: + case D3DFMT_DXT5: + TRACE_(d3d_caps)("[OK]\n"); + return WINED3D_OK; + default: + break; + } + } + + /* This format is nothing special and it is supported perfectly. * However, ati and nvidia driver on windows do not mark this format * supported(tested with the dxCapsViewer) and pretending to diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 0e0e6dd..1979e1f 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1221,7 +1221,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetDC DWORD *masks; HRESULT hr; RGBQUAD col[256]; - const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.format); + const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.wineD3DDevice->stateBlock, This->resource.format); TRACE("(%p)->(%p)\n",This,pHDC); @@ -1449,7 +1449,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_Relea HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp) { BOOL colorkey_active = need_alpha_ck && (This->CKeyFlags & DDSD_CKSRCBLT); - const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.format); + const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.wineD3DDevice->stateBlock, This->resource.format); /* Default values: From the surface */ *format = formatEntry->glFormat; @@ -2214,7 +2214,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SetCo HRESULT WINAPI IWineD3DSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORMAT format) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - const PixelFormatDesc *formatEntry = getFormatDescEntry(format); + const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.wineD3DDevice->stateBlock, format); if (This->resource.format != WINED3DFMT_UNKNOWN) { FIXME("(%p) : The foramt of the surface must be WINED3DFORMAT_UNKNOWN\n", This); diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c index 9609ebd..7ebfde8 100644 --- a/dlls/wined3d/surface_gdi.c +++ b/dlls/wined3d/surface_gdi.c @@ -534,7 +534,7 @@ #endif dfmt = This->resource.format; slock = dlock; sfmt = dfmt; - sEntry = getFormatDescEntry(sfmt); + sEntry = getFormatDescEntry(Src->resource.wineD3DDevice->stateBlock, sfmt); dEntry = sEntry; } else @@ -544,9 +544,9 @@ #endif IWineD3DSurface_LockRect(SrcSurface, &slock, NULL, D3DLOCK_READONLY); sfmt = Src->resource.format; } - sEntry = getFormatDescEntry(sfmt); + sEntry = getFormatDescEntry(Src->resource.wineD3DDevice->stateBlock, sfmt); dfmt = This->resource.format; - dEntry = getFormatDescEntry(dfmt); + dEntry = getFormatDescEntry(This->resource.wineD3DDevice->stateBlock, dfmt); IWineD3DSurface_LockRect(iface, &dlock,NULL,0); } @@ -1215,7 +1215,7 @@ IWineGDISurfaceImpl_BltFast(IWineD3DSurf assert(This->resource.allocatedMemory != NULL); sbuf = (BYTE *)This->resource.allocatedMemory + lock_src.top * pitch + lock_src.left * bpp; dbuf = (BYTE *)This->resource.allocatedMemory + lock_dst.top * pitch + lock_dst.left * bpp; - sEntry = getFormatDescEntry(Src->resource.format); + sEntry = getFormatDescEntry(Src->resource.wineD3DDevice->stateBlock, Src->resource.format); dEntry = sEntry; } else @@ -1229,8 +1229,8 @@ IWineGDISurfaceImpl_BltFast(IWineD3DSurf dbuf = dlock.pBits; TRACE("Dst is at %p, Src is at %p\n", dbuf, sbuf); - sEntry = getFormatDescEntry(Src->resource.format); - dEntry = getFormatDescEntry(This->resource.format); + sEntry = getFormatDescEntry(Src->resource.wineD3DDevice->stateBlock, Src->resource.format); + dEntry = getFormatDescEntry(This->resource.wineD3DDevice->stateBlock, This->resource.format); } /* Handle first the FOURCC surfaces... */ @@ -1408,7 +1408,7 @@ const char* filename) IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; static char *output = NULL; static int size = 0; - const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.format); + const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.wineD3DDevice->stateBlock, This->resource.format); if (This->pow2Width > size) { output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pow2Width * 3); @@ -1516,7 +1516,7 @@ IWineGDISurfaceImpl_PrivateSetup(IWineD3 This->resource.allocatedMemory = NULL; /* We don't mind the nonpow2 stuff in GDI */ - This->resource.size = This->currentDesc.Width * getFormatDescEntry(This->resource.format)->bpp * This->currentDesc.Width; + This->resource.size = This->currentDesc.Width * getFormatDescEntry(This->resource.wineD3DDevice->stateBlock, This->resource.format)->bpp * This->currentDesc.Width; This->pow2Size = This->resource.size; This->pow2Width = This->currentDesc.Width; This->pow2Height = This->currentDesc.Height; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 372fdb1..4dc19b1 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -107,18 +107,71 @@ static const PixelFormatDesc formats[] = {WINED3DFMT_Q16W16V16U16,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,GL_COLOR_INDEX ,GL_COLOR_INDEX ,GL_UNSIGNED_SHORT } }; -const PixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt) +/***************************************************************************** + * sRGB Pixel format array + */ +static const PixelFormatDesc srgb_formats[] = { + /*{WINED3DFORMAT ,alphamask ,redmask ,greenmask ,bluemask ,bpp ,isFourcc ,internal ,format ,type }*/ + {WINED3DFMT_UNKNOWN ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,0 ,0 ,0 }, + {WINED3DFMT_DXT1 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,0 }, + {WINED3DFMT_DXT2 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,0 }, + {WINED3DFMT_DXT3 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,0 }, + {WINED3DFMT_DXT4 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,0 }, + {WINED3DFMT_DXT5 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,TRUE ,GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,0 }, + /* Standard ARGB formats */ + {WINED3DFMT_A8R8G8B8 ,0xff000000 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,FALSE ,GL_SRGB8_ALPHA8_EXT ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV }, + {WINED3DFMT_X8R8G8B8 ,0x0 ,0x00ff0000 ,0x0000ff00 ,0x000000ff ,4 ,FALSE ,GL_SRGB8_EXT ,GL_BGRA ,GL_UNSIGNED_INT_8_8_8_8_REV }, + {WINED3DFMT_A8B8G8R8 ,0xff000000 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,FALSE ,GL_SRGB8_ALPHA8_EXT ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV }, + {WINED3DFMT_X8B8G8R8 ,0x0 ,0x000000ff ,0x0000ff00 ,0x00ff0000 ,4 ,FALSE ,GL_SRGB8_EXT ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV }, + /* Luminance */ + {WINED3DFMT_L8 ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,GL_SLUMINANCE8_EXT ,GL_LUMINANCE ,GL_UNSIGNED_BYTE }, + {WINED3DFMT_A8 ,0x000000ff ,0x0 ,0x0 ,0x0 ,1 ,FALSE ,GL_ALPHA8 ,GL_ALPHA ,GL_ALPHA }, + {WINED3DFMT_A8L8 ,0x0000ff00 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_SLUMINANCE8_ALPHA8_EXT ,GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE }, + /* Bump mapping stuff */ + {WINED3DFMT_V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX ,GL_UNSIGNED_BYTE }, + {WINED3DFMT_L6V5U5 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,GL_COLOR_INDEX8_EXT ,GL_COLOR_INDEX ,GL_UNSIGNED_SHORT_5_5_5_1 }, + {WINED3DFMT_X8L8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_SRGB8_ALPHA8_EXT ,GL_BGRA ,GL_UNSIGNED_BYTE }, + {WINED3DFMT_Q8W8V8U8 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_SRGB8_ALPHA8_EXT ,GL_RGBA ,GL_UNSIGNED_INT_8_8_8_8_REV/*?*/ }, + {WINED3DFMT_V16U16 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,GL_COLOR_INDEX ,GL_COLOR_INDEX ,GL_UNSIGNED_SHORT }, + {WINED3DFMT_W11V11U10 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 }, + {WINED3DFMT_A2W10V10U10 ,0xb0000000 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 }, + /* Float */ + {WINED3DFMT_R16F ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,FALSE ,0 ,0 ,0 }, + {WINED3DFMT_G16R16F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 }, + {WINED3DFMT_A16B16G16R16F,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,GL_RGBA16F_ARB ,GL_RGBA ,GL_HALF_FLOAT_ARB }, + /* IEEE formats */ + {WINED3DFMT_R32F ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,FALSE ,0 ,0 ,0 }, + {WINED3DFMT_G32R32F ,0x0 ,0x0 ,0x0 ,0x0 ,8 ,FALSE ,0 ,0 ,0 }, + {WINED3DFMT_A32B32G32R32F,0x0 ,0x0 ,0x0 ,0x0 ,16 ,FALSE ,GL_RGBA32F_ARB ,GL_RGBA ,GL_FLOAT }, +}; + +const PixelFormatDesc *getFormatDescEntry(IWineD3DStateBlockImpl* stateBlock, WINED3DFORMAT fmt) { + /* Select the appropriate table */ + const PixelFormatDesc* table = + (stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE])?srgb_formats:formats; + /* First check if the format is at the position of its value. * This will catch the argb formats before the loop is entered */ - if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) { - return &formats[fmt]; + + unsigned int rowSize = sizeof(PixelFormatDesc); + unsigned int tableSize = 0; + + if (table == formats) + tableSize = sizeof(formats); + else if (table == srgb_formats) + tableSize = sizeof(srgb_formats); + + TRACE("size of table: %d\n", tableSize); + if(fmt < (tableSize / rowSize) && table[fmt].format == fmt) { + return &table[fmt]; } else { unsigned int i; - for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) { - if(formats[i].format == fmt) { - return &formats[i]; + for(i = 0; i < (tableSize / rowSize); i++) { + if(table[i].format == fmt) { + return &table[i]; } } } @@ -128,7 +181,7 @@ const PixelFormatDesc *getFormatDescEntr return NULL; } /* Get the caller a valid pointer */ - return getFormatDescEntry(WINED3DFMT_UNKNOWN); + return getFormatDescEntry(stateBlock, WINED3DFMT_UNKNOWN); } /***************************************************************************** diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c index 5a10b13..a439ee9 100644 --- a/dlls/wined3d/volume.c +++ b/dlls/wined3d/volume.c @@ -283,7 +283,7 @@ static HRESULT WINAPI IWineD3DVolumeImpl static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, GLenum gl_level) { IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface; - const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.format); + const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.wineD3DDevice->stateBlock, This->resource.format); if(GL_SUPPORT(EXT_TEXTURE3D)) { TRACE("Calling glTexImage3D %x level=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%x, Mem=%p\n", diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index bc8a9b5..10a0a20 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1767,5 +1767,5 @@ typedef struct { GLint glInternal, glFormat, glType; } PixelFormatDesc; -const PixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt); +const PixelFormatDesc *getFormatDescEntry(IWineD3DStateBlockImpl* stateBlock, WINED3DFORMAT fmt); #endif diff --git a/include/wine/wined3d_gl.h b/include/wine/wined3d_gl.h index 36e9a20..a1bfc31 100644 --- a/include/wine/wined3d_gl.h +++ b/include/wine/wined3d_gl.h @@ -438,6 +438,26 @@ #define GL_EXT_texture_env_dot3 1 #define GL_DOT3_RGB_EXT 0x8740 #define GL_DOT3_RGBA_EXT 0x8741 #endif +/* GL_EXT_texture_sRGB */ +#ifndef GL_EXT_texture_sRGB +#define GL_EXT_texture_sRGB 1 +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#endif /* GL_EXT_texture_lod_bias */ #ifndef GL_EXT_texture_lod_bias #define GL_EXT_texture_lod_bias 1 @@ -1443,6 +1463,7 @@ typedef enum _GL_SupportedExt { EXT_TEXTURE_ENV_ADD, EXT_TEXTURE_ENV_COMBINE, EXT_TEXTURE_ENV_DOT3, + EXT_TEXTURE_SRGB, EXT_VERTEX_WEIGHTING, /* NVIDIA */ NV_FOG_DISTANCE,