Commit dc25a86c authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

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.
parent 370b8299
......@@ -816,6 +816,23 @@ static void shader_arb_color_correction(SHADER_OPCODE_ARG* arg) {
}
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 */
default:
break;
......
......@@ -641,7 +641,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, U
Size = ((max(Width,4) * tableEntry->bpp) * max(Height,4)) >> 1;
} 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));
} else {
/* The pitch is a multiple of 4 bytes */
......
......@@ -59,6 +59,7 @@ static const struct {
{"GL_ATI_texture_mirror_once", ATI_TEXTURE_MIRROR_ONCE, 0 },
{"GL_ATI_envmap_bumpmap", ATI_ENVMAP_BUMPMAP, 0 },
{"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER, 0 },
{"GL_ATI_texture_compression_3dc", ATI_TEXTURE_COMPRESSION_3DC, 0 },
/* ARB */
{"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");
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:
return FALSE;
......
......@@ -1344,6 +1344,26 @@ static void shader_glsl_color_correction(SHADER_OPCODE_ARG* arg) {
}
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 */
default:
break;
......
......@@ -93,7 +93,8 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) {
if (This->resource.format == WINED3DFMT_DXT1 ||
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 */
FIXME("(%p) : Attempting to lock a compressed texture when texture compression isn't supported by opengl\n", This);
} 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) {
if (This->resource.format == WINED3DFMT_DXT1 ||
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)) {
FIXME("Using DXT1/3/5 without advertized support\n");
} else {
......@@ -296,7 +298,8 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal,
if (This->resource.format == WINED3DFMT_DXT1 ||
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 */
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;
/** TODO: add support for non power two compressed textures **/
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",
This, This->currentDesc.Width, This->currentDesc.Height);
return WINED3DERR_NOTAVAILABLE;
......
......@@ -112,6 +112,8 @@ static const StaticPixelFormatDesc formats[] = {
{WINED3DFMT_INDEX16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE },
{WINED3DFMT_INDEX32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,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 {
......@@ -260,6 +262,9 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
{WINED3DFMT_INDEX32 ,0 ,0 , 0, 0 ,0
,0 },
{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 }
};
......@@ -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;
}
......@@ -519,6 +531,7 @@ const char* debug_d3dformat(WINED3DFORMAT fmt) {
FMT_TO_STR(WINED3DFMT_G32R32F);
FMT_TO_STR(WINED3DFMT_A32B32G32R32F);
FMT_TO_STR(WINED3DFMT_CxV8U8);
FMT_TO_STR(WINED3DFMT_ATI2N);
#undef FMT_TO_STR
default:
{
......
......@@ -2991,6 +2991,11 @@ typedef void (WINE_GLAPI *PGLFNSETFRAGMENTSHADERCONSTANTATI) (GLuint dst, const
#define GL_NEGATE_BIT_ATI 0x00000004
#define GL_BIAS_BIT_ATI 0x00000008
#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 */
#ifndef GL_VERSION_2_0
......@@ -3357,6 +3362,7 @@ typedef enum _GL_SupportedExt {
EXT_VERTEX_SHADER,
ATI_ENVMAP_BUMPMAP,
ATI_FRAGMENT_SHADER,
ATI_TEXTURE_COMPRESSION_3DC,
/* APPLE */
APPLE_FENCE,
APPLE_CLIENT_STORAGE,
......
......@@ -303,6 +303,8 @@ typedef enum _WINED3DFORMAT {
WINED3DFMT_CxV8U8 = 117,
/* Vendor specific formats */
WINED3DFMT_ATI2N = WINEMAKEFOURCC('A', 'T', 'I', '2'),
WINED3DFMT_FORCE_DWORD = 0xFFFFFFFF
} WINED3DFORMAT;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment