wined3d: Support ATI's D3DFMT_ATI2N format.

This is an ATI specific format designed for compressed normal maps,
and quite a few games check for its existence. While it is an
ATI-specific "extension" in d3d9, it is a core part of
D3D10(DXGI_FORMAT_BC5), and supported on Geforce 8 cards.
This commit is contained in:
Stefan Dösinger 2008-07-23 10:33:10 -05:00 committed by Alexandre Julliard
parent 370b8299ab
commit dc25a86cc5
8 changed files with 78 additions and 5 deletions

View File

@ -816,6 +816,23 @@ static void shader_arb_color_correction(SHADER_OPCODE_ARG* arg) {
} }
break; break;
case WINED3DFMT_ATI2N:
/* GL_ATI_texture_compression_3dc returns the two channels as luminance-alpha,
* which means the first one is replicated accross .rgb, and the 2nd one is in
* .a. We need the 2nd in .g
*/
if(strlen(writemask) == 5) {
/* Swap y and z (U and L), and do a sign conversion on x and the new y(V and U) */
shader_addline(arg->buffer, "MOV %s.%c, %s.%c;\n",
reg, writemask[2], reg, writemask[4]);
} else if(strlen(writemask) == 2) {
/* Nothing to do */
} else {
/* This is bad: We have VL, but we need VU */
FIXME("2 or 3 components sampled from a converted ATI2N texture\n");
}
break;
/* stupid compiler */ /* stupid compiler */
default: default:
break; break;

View File

@ -641,7 +641,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, U
Size = ((max(Width,4) * tableEntry->bpp) * max(Height,4)) >> 1; Size = ((max(Width,4) * tableEntry->bpp) * max(Height,4)) >> 1;
} else if (Format == WINED3DFMT_DXT2 || Format == WINED3DFMT_DXT3 || } else if (Format == WINED3DFMT_DXT2 || Format == WINED3DFMT_DXT3 ||
Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5) { Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5 ||
Format == WINED3DFMT_ATI2N) {
Size = ((max(Width,4) * tableEntry->bpp) * max(Height,4)); Size = ((max(Width,4) * tableEntry->bpp) * max(Height,4));
} else { } else {
/* The pitch is a multiple of 4 bytes */ /* The pitch is a multiple of 4 bytes */

View File

@ -59,6 +59,7 @@ static const struct {
{"GL_ATI_texture_mirror_once", ATI_TEXTURE_MIRROR_ONCE, 0 }, {"GL_ATI_texture_mirror_once", ATI_TEXTURE_MIRROR_ONCE, 0 },
{"GL_ATI_envmap_bumpmap", ATI_ENVMAP_BUMPMAP, 0 }, {"GL_ATI_envmap_bumpmap", ATI_ENVMAP_BUMPMAP, 0 },
{"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER, 0 }, {"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER, 0 },
{"GL_ATI_texture_compression_3dc", ATI_TEXTURE_COMPRESSION_3DC, 0 },
/* ARB */ /* ARB */
{"GL_ARB_color_buffer_float", ARB_COLOR_BUFFER_FLOAT, 0 }, {"GL_ARB_color_buffer_float", ARB_COLOR_BUFFER_FLOAT, 0 },
@ -2371,6 +2372,15 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
TRACE_(d3d_caps)("[FAILED]\n"); TRACE_(d3d_caps)("[FAILED]\n");
return FALSE; return FALSE;
/* Vendor specific formats */
case WINED3DFMT_ATI2N:
if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC)) {
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
}
TRACE_(d3d_caps)("[FAILED]\n");
return FALSE;
case WINED3DFMT_UNKNOWN: case WINED3DFMT_UNKNOWN:
return FALSE; return FALSE;

View File

@ -1344,6 +1344,26 @@ static void shader_glsl_color_correction(SHADER_OPCODE_ARG* arg) {
} }
break; break;
case WINED3DFMT_ATI2N:
/* GL_ATI_texture_compression_3dc returns the two channels as luminance-alpha,
* which means the first one is replicated accross .rgb, and the 2nd one is in
* .a. We need the 2nd in .g
*/
mask = shader_glsl_add_dst_param(arg, arg->dst, WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &dst_param);
mask_size = shader_glsl_get_write_mask_size(mask);
if(mask_size == 4) {
/* Swap y and z (U and L), and do a sign conversion on x and the new y(V and U) */
shader_addline(arg->buffer, "%s.%c = %s.%c;\n",
dst_param.reg_name, dst_param.mask_str[2],
dst_param.reg_name, dst_param.mask_str[4]);
} else if(mask_size == 1) {
/* Nothing to do */
} else {
FIXME("%u components sampled from a converted ATI2N texture\n", mask_size);
/* This is bad: We have .r[gb], but we need .ra */
}
break;
/* stupid compiler */ /* stupid compiler */
default: default:
break; break;

View File

@ -93,7 +93,8 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) {
if (This->resource.format == WINED3DFMT_DXT1 || if (This->resource.format == WINED3DFMT_DXT1 ||
This->resource.format == WINED3DFMT_DXT2 || This->resource.format == WINED3DFMT_DXT3 || This->resource.format == WINED3DFMT_DXT2 || This->resource.format == WINED3DFMT_DXT3 ||
This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5) { This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5 ||
This->resource.format == WINED3DFMT_ATI2N) {
if (!GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) { /* We can assume this as the texture would not have been created otherwise */ if (!GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) { /* We can assume this as the texture would not have been created otherwise */
FIXME("(%p) : Attempting to lock a compressed texture when texture compression isn't supported by opengl\n", This); FIXME("(%p) : Attempting to lock a compressed texture when texture compression isn't supported by opengl\n", This);
} else { } else {
@ -232,7 +233,8 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) {
static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data) { static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data) {
if (This->resource.format == WINED3DFMT_DXT1 || if (This->resource.format == WINED3DFMT_DXT1 ||
This->resource.format == WINED3DFMT_DXT2 || This->resource.format == WINED3DFMT_DXT3 || This->resource.format == WINED3DFMT_DXT2 || This->resource.format == WINED3DFMT_DXT3 ||
This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5) { This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5 ||
This->resource.format == WINED3DFMT_ATI2N) {
if (!GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) { if (!GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
FIXME("Using DXT1/3/5 without advertized support\n"); FIXME("Using DXT1/3/5 without advertized support\n");
} else { } else {
@ -296,7 +298,8 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal,
if (This->resource.format == WINED3DFMT_DXT1 || if (This->resource.format == WINED3DFMT_DXT1 ||
This->resource.format == WINED3DFMT_DXT2 || This->resource.format == WINED3DFMT_DXT3 || This->resource.format == WINED3DFMT_DXT2 || This->resource.format == WINED3DFMT_DXT3 ||
This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5) { This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5 ||
This->resource.format == WINED3DFMT_ATI2N) {
/* glCompressedTexImage2D does not accept NULL pointers, so we cannot allocate a compressed texture without uploading data */ /* glCompressedTexImage2D does not accept NULL pointers, so we cannot allocate a compressed texture without uploading data */
TRACE("Not allocating compressed surfaces, surface_upload_data will specify them\n"); TRACE("Not allocating compressed surfaces, surface_upload_data will specify them\n");
@ -3771,7 +3774,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) {
WINED3DFORMAT Format = This->resource.format; WINED3DFORMAT Format = This->resource.format;
/** TODO: add support for non power two compressed textures **/ /** TODO: add support for non power two compressed textures **/
if (Format == WINED3DFMT_DXT1 || Format == WINED3DFMT_DXT2 || Format == WINED3DFMT_DXT3 if (Format == WINED3DFMT_DXT1 || Format == WINED3DFMT_DXT2 || Format == WINED3DFMT_DXT3
|| Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5) { || Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5
|| This->resource.format == WINED3DFMT_ATI2N) {
FIXME("(%p) Compressed non-power-two textures are not supported w(%d) h(%d)\n", FIXME("(%p) Compressed non-power-two textures are not supported w(%d) h(%d)\n",
This, This->currentDesc.Width, This->currentDesc.Height); This, This->currentDesc.Width, This->currentDesc.Height);
return WINED3DERR_NOTAVAILABLE; return WINED3DERR_NOTAVAILABLE;

View File

@ -112,6 +112,8 @@ static const StaticPixelFormatDesc formats[] = {
{WINED3DFMT_INDEX16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE }, {WINED3DFMT_INDEX16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
{WINED3DFMT_INDEX32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE }, {WINED3DFMT_INDEX32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE },
{WINED3DFMT_Q16W16V16U16,0x0 ,0x0 ,0x0 ,0x0 ,8 ,0 ,0 ,FALSE }, {WINED3DFMT_Q16W16V16U16,0x0 ,0x0 ,0x0 ,0x0 ,8 ,0 ,0 ,FALSE },
/* Vendor-specific formats */
{WINED3DFMT_ATI2N ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE },
}; };
typedef struct { typedef struct {
@ -260,6 +262,9 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
{WINED3DFMT_INDEX32 ,0 ,0 , 0, 0 ,0 {WINED3DFMT_INDEX32 ,0 ,0 , 0, 0 ,0
,0 }, ,0 },
{WINED3DFMT_Q16W16V16U16 ,GL_COLOR_INDEX ,GL_COLOR_INDEX , 0, GL_COLOR_INDEX ,GL_UNSIGNED_SHORT {WINED3DFMT_Q16W16V16U16 ,GL_COLOR_INDEX ,GL_COLOR_INDEX , 0, GL_COLOR_INDEX ,GL_UNSIGNED_SHORT
,0 },
/* Vendor-specific formats */
{WINED3DFMT_ATI2N ,0 ,0 , 0, GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE
,0 } ,0 }
}; };
@ -390,6 +395,13 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
*/ */
} }
if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC)) {
dst = getFmtIdx(WINED3DFMT_ATI2N);
gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
gl_info->gl_formats[dst].conversion_group= WINED3DFMT_ATI2N;
}
return TRUE; return TRUE;
} }
@ -519,6 +531,7 @@ const char* debug_d3dformat(WINED3DFORMAT fmt) {
FMT_TO_STR(WINED3DFMT_G32R32F); FMT_TO_STR(WINED3DFMT_G32R32F);
FMT_TO_STR(WINED3DFMT_A32B32G32R32F); FMT_TO_STR(WINED3DFMT_A32B32G32R32F);
FMT_TO_STR(WINED3DFMT_CxV8U8); FMT_TO_STR(WINED3DFMT_CxV8U8);
FMT_TO_STR(WINED3DFMT_ATI2N);
#undef FMT_TO_STR #undef FMT_TO_STR
default: default:
{ {

View File

@ -2991,6 +2991,11 @@ typedef void (WINE_GLAPI *PGLFNSETFRAGMENTSHADERCONSTANTATI) (GLuint dst, const
#define GL_NEGATE_BIT_ATI 0x00000004 #define GL_NEGATE_BIT_ATI 0x00000004
#define GL_BIAS_BIT_ATI 0x00000008 #define GL_BIAS_BIT_ATI 0x00000008
#endif #endif
/* GL_ATI_texture_compression_3dc */
#ifndef GL_ATI_texture_compression_3dc
#define GL_ATI_texture_compression_3dc
#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837
#endif
/* GL_VERSION_2_0 */ /* GL_VERSION_2_0 */
#ifndef GL_VERSION_2_0 #ifndef GL_VERSION_2_0
@ -3357,6 +3362,7 @@ typedef enum _GL_SupportedExt {
EXT_VERTEX_SHADER, EXT_VERTEX_SHADER,
ATI_ENVMAP_BUMPMAP, ATI_ENVMAP_BUMPMAP,
ATI_FRAGMENT_SHADER, ATI_FRAGMENT_SHADER,
ATI_TEXTURE_COMPRESSION_3DC,
/* APPLE */ /* APPLE */
APPLE_FENCE, APPLE_FENCE,
APPLE_CLIENT_STORAGE, APPLE_CLIENT_STORAGE,

View File

@ -303,6 +303,8 @@ typedef enum _WINED3DFORMAT {
WINED3DFMT_CxV8U8 = 117, WINED3DFMT_CxV8U8 = 117,
/* Vendor specific formats */
WINED3DFMT_ATI2N = WINEMAKEFOURCC('A', 'T', 'I', '2'),
WINED3DFMT_FORCE_DWORD = 0xFFFFFFFF WINED3DFMT_FORCE_DWORD = 0xFFFFFFFF
} WINED3DFORMAT; } WINED3DFORMAT;