Commit eac96b56 authored by Christian Costa's avatar Christian Costa Committed by Alexandre Julliard

Added native and emulated S3TC support.

parent df80b569
......@@ -15272,6 +15272,80 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
fi
echo "$as_me:$LINENO: checking for -ltxc_dxtn soname" >&5
echo $ECHO_N "checking for -ltxc_dxtn soname... $ECHO_C" >&6
if test "${ac_cv_lib_soname_txc_dxtn+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_get_soname_save_LIBS=$LIBS
LIBS="-ltxc_dxtn $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char fetch_2d_texel_rgba_dxt1 ();
int
main ()
{
fetch_2d_texel_rgba_dxt1 ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_soname_txc_dxtn=`$ac_cv_path_LDD conftest$ac_exeext | grep libtxc_dxtn\\.$LIBEXT | sed "s/^.*\(libtxc_dxtn\.$LIBEXT[^ ]*\).*$/\1/"`
if test "x$ac_cv_lib_soname_txc_dxtn" = "x"
then
ac_cv_lib_soname_txc_dxtn="libtxc_dxtn.$LIBEXT"
fi
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_soname_txc_dxtn="libtxc_dxtn.$LIBEXT"
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_get_soname_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_soname_txc_dxtn" >&5
echo "${ECHO_T}$ac_cv_lib_soname_txc_dxtn" >&6
if test "x$ac_cv_lib_soname_txc_dxtn" != xNONE
then
cat >>confdefs.h <<_ACEOF
#define SONAME_LIBTXC_DXTN "$ac_cv_lib_soname_txc_dxtn"
_ACEOF
fi
echo "$as_me:$LINENO: checking for -lcups soname" >&5
echo $ECHO_N "checking for -lcups soname... $ECHO_C" >&6
if test "${ac_cv_lib_soname_cups+set}" = set; then
......
......@@ -1023,6 +1023,7 @@ then
WINE_GET_SONAME(Xrandr,XRRQueryExtension,[$X_LIBS -lXext -lX11 $X_EXTRA_LIBS])
WINE_GET_SONAME(freetype,FT_Init_FreeType,[$X_LIBS])
WINE_GET_SONAME(GL,glXQueryExtension,[$X_LIBS $X_EXTRA_LIBS])
WINE_GET_SONAME(txc_dxtn,fetch_2d_texel_rgba_dxt1)
WINE_GET_SONAME(cups,cupsGetDefault)
WINE_GET_SONAME(jack,jack_client_new)
WINE_GET_SONAME(fontconfig,FcInit)
......
......@@ -276,4 +276,12 @@ extern void multiply_matrix(LPD3DMATRIX,LPD3DMATRIX,LPD3DMATRIX);
extern const float id_mat[16];
typedef void (*FUNC_FETCH_2D_TEXEL_RGBA_DXT1)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel);
typedef void (*FUNC_FETCH_2D_TEXEL_RGBA_DXT3)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel);
typedef void (*FUNC_FETCH_2D_TEXEL_RGBA_DXT5)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel);
extern FUNC_FETCH_2D_TEXEL_RGBA_DXT1 fetch_2d_texel_rgba_dxt1;
extern FUNC_FETCH_2D_TEXEL_RGBA_DXT3 fetch_2d_texel_rgba_dxt3;
extern FUNC_FETCH_2D_TEXEL_RGBA_DXT5 fetch_2d_texel_rgba_dxt5;
#endif /* __GRAPHICS_WINE_D3D_PRIVATE_H */
......@@ -614,6 +614,26 @@ static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
if (GL_extensions.s3tc_compressed_texture) {
TRACE("Enumerating DXT1\n");
pformat->dwFlags = DDPF_FOURCC;
pformat->dwFourCC = MAKE_FOURCC('D','X','T','1');
if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
TRACE("Enumerating DXT3\n");
pformat->dwFlags = DDPF_FOURCC;
pformat->dwFourCC = MAKE_FOURCC('D','X','T','3');
if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
TRACE("Enumerating DXT5\n");
pformat->dwFlags = DDPF_FOURCC;
pformat->dwFourCC = MAKE_FOURCC('D','X','T','5');
if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
}
TRACE("End of enumeration\n");
return DD_OK;
}
......@@ -4236,6 +4256,13 @@ d3ddevice_init_at_startup(void *gl_handle)
GL_extensions.glMultiTexCoord2fv = pglXGetProcAddressARB("glMultiTexCoord2fv");
GL_extensions.glClientActiveTexture = pglXGetProcAddressARB("glClientActiveTextureARB");
}
if (strstr(glExtensions, "GL_EXT_texture_compression_s3tc")) {
TRACE(" - S3TC compression supported\n");
GL_extensions.s3tc_compressed_texture = TRUE;
GL_extensions.glCompressedTexImage2D = pglXGetProcAddressARB("glCompressedTexImage2D");
GL_extensions.glCompressedTexSubImage2D = pglXGetProcAddressARB("glCompressedTexSubImage2D");
}
}
/* Fill the D3D capabilities according to what GL tells us... */
......
......@@ -642,7 +642,11 @@ GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
if (gl_dst_ptr != NULL) {
if (gl_dst_ptr->loaded == FALSE) {
/* Only check memory for not already loaded texture... */
DWORD mem_used = dst_ptr->surface_desc.dwHeight * dst_ptr->surface_desc.u1.lPitch;
DWORD mem_used;
if (dst_ptr->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)
mem_used = dst_ptr->surface_desc.u1.dwLinearSize;
else
mem_used = dst_ptr->surface_desc.dwHeight * dst_ptr->surface_desc.u1.lPitch;
if (This->ddraw_owner->allocate_memory(This->ddraw_owner, mem_used) < 0) {
TRACE(" out of virtual memory... Warning application.\n");
return D3DERR_TEXTURE_LOAD_FAILED;
......@@ -697,7 +701,10 @@ GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
/* Copy the main memory texture into the surface that corresponds to the OpenGL
texture object. */
memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->u1.lPitch * src_d->dwHeight);
if (dst_ptr->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)
memcpy(dst_d->lpSurface, src_d->lpSurface, src_ptr->surface_desc.u1.dwLinearSize);
else
memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->u1.lPitch * src_d->dwHeight);
if (gl_dst_ptr != NULL) {
/* If the GetHandle was not done, it is an error... */
......
......@@ -380,16 +380,38 @@ create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,
ddsd.u4.ddpfPixelFormat = This->pixelformat;
}
/* We do not support for now compressed texture formats... */
if (ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)
/* We support for now only DXT1, DXT3 & DXT5 compressed texture formats... */
if ((ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) &&
(ddsd.u4.ddpfPixelFormat.dwFourCC != MAKE_FOURCC('D','X','T','1')) &&
(ddsd.u4.ddpfPixelFormat.dwFourCC != MAKE_FOURCC('D','X','T','3')) &&
(ddsd.u4.ddpfPixelFormat.dwFourCC != MAKE_FOURCC('D','X','T','5')) )
{
return DDERR_INVALIDPIXELFORMAT;
}
/* Check if we can really support DXT1, DXT3 & DXT5 */
if ((ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) &&
!GL_extensions.s3tc_compressed_texture && !s3tc_initialized) {
ERR("Trying to create DXT1, DXT3 or DXT5 texture which is not supported by the video card!!!\n");
ERR("However there is a library libtxc_dxtn.so that can be used to do the software decompression...\n");
return DDERR_INVALIDPIXELFORMAT;
}
if (!(ddsd.dwFlags & DDSD_PITCH))
{
ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth,
GET_BPP(ddsd)*8);
if (ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
int size = 0;
int width = ddsd.dwWidth;
int height = ddsd.dwHeight;
switch(ddsd.u4.ddpfPixelFormat.dwFourCC) {
case MAKE_FOURCC('D','X','T','1'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 8; break;
case MAKE_FOURCC('D','X','T','3'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break;
case MAKE_FOURCC('D','X','T','5'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break;
default: FIXME("FOURCC not supported\n"); break;
}
ddsd.u1.dwLinearSize = size;
} else
ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth, GET_BPP(ddsd)*8);
}
/* Check also for the MIPMAP / MIPMAPCOUNT flags.
......@@ -433,9 +455,23 @@ create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,
if (mipmap_surface_desc.dwHeight > 1)
mipmap_surface_desc.dwHeight /= 2;
mipmap_surface_desc.u1.lPitch
= DDRAW_width_bpp_to_pitch(mipmap_surface_desc.dwWidth,
GET_BPP(ddsd)*8);
if (mipmap_surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
int size = 0;
int width = mipmap_surface_desc.dwWidth;
int height = mipmap_surface_desc.dwHeight;
switch(mipmap_surface_desc.u4.ddpfPixelFormat.dwFourCC) {
case MAKE_FOURCC('D','X','T','1'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 8; break;
case MAKE_FOURCC('D','X','T','3'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break;
case MAKE_FOURCC('D','X','T','5'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break;
default: FIXME("FOURCC not supported\n"); break;
}
mipmap_surface_desc.u1.dwLinearSize = size;
} else {
ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth, GET_BPP(ddsd)*8);
mipmap_surface_desc.u1.lPitch
= DDRAW_width_bpp_to_pitch(mipmap_surface_desc.dwWidth,
GET_BPP(ddsd)*8);
}
hr = This->create_texture(This, &mipmap_surface_desc, &mipmap,
pUnkOuter, mipmap_level);
......
......@@ -55,6 +55,8 @@
(to)->dwSize = __size;/*restore size*/ \
} while (0)
#define MAKE_FOURCC(a,b,c,d) ((a << 0) | (b << 8) | (c << 16) | (d << 24))
/*****************************************************************************
* IDirectDraw implementation structure
*/
......@@ -377,6 +379,7 @@ typedef struct {
extern Convert ModeEmulations[8];
extern int _common_depth_to_pixelformat(DWORD depth,LPDIRECTDRAW ddraw);
extern BOOL opengl_initialized;
extern BOOL s3tc_initialized;
/******************************************************************************
* Structure conversion (for thunks)
......
......@@ -30,6 +30,7 @@
#include "winerror.h"
#include "wine/debug.h"
#include "ddraw_private.h"
#include "d3d_private.h"
#include "dsurface/main.h"
#include "dsurface/dib.h"
......@@ -254,8 +255,12 @@ HRESULT DIB_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This,
This->surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
This->surface_desc.lpSurface
= VirtualAlloc(NULL, This->surface_desc.u1.lPitch
if (This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)
This->surface_desc.lpSurface
= VirtualAlloc(NULL, This->surface_desc.u1.dwLinearSize, MEM_COMMIT, PAGE_READWRITE);
else
This->surface_desc.lpSurface
= VirtualAlloc(NULL, This->surface_desc.u1.lPitch
* This->surface_desc.dwHeight + 4, /* The + 4 here is for dumb games reading after the end of the surface
when reading the last byte / half using word access */
MEM_COMMIT, PAGE_READWRITE);
......@@ -354,6 +359,26 @@ static HRESULT _Blt_ColorFill(
return DD_OK;
}
void ComputeShifts(DWORD mask, DWORD* lshift, DWORD* rshift)
{
int pos = 0;
int bits = 0;
*lshift = 0;
*rshift = 0;
if (!mask)
return;
while(!(mask & (1 << pos)))
pos++;
while(mask & (1 << (pos+bits)))
bits++;
*lshift = pos;
*rshift = 8 - bits;
}
HRESULT WINAPI
DIB_DirectDrawSurface_Blt(LPDIRECTDRAWSURFACE7 iface, LPRECT rdst,
LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,
......@@ -393,6 +418,122 @@ DIB_DirectDrawSurface_Blt(LPDIRECTDRAWSURFACE7 iface, LPRECT rdst,
ddesc.dwSize = sizeof(ddesc);
IDirectDrawSurface7_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
if ((sdesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) &&
(ddesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)) {
if (sdesc.u4.ddpfPixelFormat.dwFourCC != sdesc.u4.ddpfPixelFormat.dwFourCC) {
FIXME("FOURCC->FOURCC copy only supported for the same type of surface\n");
return DDERR_INVALIDPIXELFORMAT;
}
memcpy(ddesc.lpSurface, sdesc.lpSurface, ddesc.u1.dwLinearSize);
goto release;
}
if ((sdesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) &&
(!(ddesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC))) {
DWORD rs,rb,rm;
DWORD gs,gb,gm;
DWORD bs,bb,bm;
DWORD as,ab,am;
if (!s3tc_initialized) {
/* FIXME: We may fake this by rendering the texture into the framebuffer using OpenGL functions and reading back
* the framebuffer. This will be slow and somewhat ugly. */
FIXME("Manual S3TC decompression is not supported in native mode\n");
goto release;
}
rm = ddesc.u4.ddpfPixelFormat.u2.dwRBitMask;
ComputeShifts(rm, &rs, &rb);
gm = ddesc.u4.ddpfPixelFormat.u3.dwGBitMask;
ComputeShifts(gm, &gs, &gb);
bm = ddesc.u4.ddpfPixelFormat.u4.dwBBitMask;
ComputeShifts(bm, &bs, &bb);
am = ddesc.u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask;
ComputeShifts(am, &as, &ab);
if (sdesc.u4.ddpfPixelFormat.dwFourCC == MAKE_FOURCC('D','X','T','1')) {
int is16 = ddesc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16;
int pitch = ddesc.u1.lPitch;
int width = ddesc.dwWidth;
int height = ddesc.dwHeight;
int x,y;
char* dst = (char*) ddesc.lpSurface;
char* src = (char*) sdesc.lpSurface;
for (x = 0; x < width; x++)
for (y =0; y < height; y++) {
DWORD pixel = 0;
BYTE data[4];
(*fetch_2d_texel_rgba_dxt1)(width, src, x, y, data);
pixel = 0;
pixel |= ((data[0] >> rb) << rs) & rm;
pixel |= ((data[1] >> gb) << gs) & gm;
pixel |= ((data[2] >> bb) << bs) & bm;
pixel |= ((data[3] >> ab) << as) & am;
if (is16)
*((WORD*)(dst+y*pitch+x*(is16?2:4))) = pixel;
else
*((DWORD*)(dst+y*pitch+x*(is16?2:4))) = pixel;
}
} else if (sdesc.u4.ddpfPixelFormat.dwFourCC == MAKE_FOURCC('D','X','T','3')) {
int is16 = ddesc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16;
int pitch = ddesc.u1.lPitch;
int width = ddesc.dwWidth;
int height = ddesc.dwHeight;
int x,y;
char* dst = (char*) ddesc.lpSurface;
char* src = (char*) sdesc.lpSurface;
for (x = 0; x < width; x++)
for (y =0; y < height; y++) {
DWORD pixel = 0;
BYTE data[4];
(*fetch_2d_texel_rgba_dxt3)(width, src, x, y, data);
pixel = 0;
pixel |= ((data[0] >> rb) << rs) & rm;
pixel |= ((data[1] >> gb) << gs) & gm;
pixel |= ((data[2] >> bb) << bs) & bm;
pixel |= ((data[3] >> ab) << as) & am;
if (is16)
*((WORD*)(dst+y*pitch+x*(is16?2:4))) = pixel;
else
*((DWORD*)(dst+y*pitch+x*(is16?2:4))) = pixel;
}
} else if (sdesc.u4.ddpfPixelFormat.dwFourCC == MAKE_FOURCC('D','X','T','5')) {
int is16 = ddesc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16;
int pitch = ddesc.u1.lPitch;
int width = ddesc.dwWidth;
int height = ddesc.dwHeight;
int x,y;
char* dst = (char*) ddesc.lpSurface;
char* src = (char*) sdesc.lpSurface;
for (x = 0; x < width; x++)
for (y =0; y < height; y++) {
DWORD pixel = 0;
BYTE data[4];
(*fetch_2d_texel_rgba_dxt5)(width, src, x, y, data);
pixel = 0;
pixel |= ((data[0] >> rb) << rs) & rm;
pixel |= ((data[1] >> gb) << gs) & gm;
pixel |= ((data[2] >> bb) << bs) & bm;
pixel |= ((data[3] >> ab) << as) & am;
if (is16)
*((WORD*)(dst+y*pitch+x*(is16?2:4))) = pixel;
else
*((DWORD*)(dst+y*pitch+x*(is16?2:4))) = pixel;
}
}
#if 0 /* Usefull for debugging */
{
static int idx;
char texname[255];
FILE* f;
sprintf(texname, "dxt_%d.pnm", idx++);
f = fopen(texname,"w");
DDRAW_dump_surface_to_disk(This, f, 1);
fclose(f);
}
#endif
goto release;
}
if (rdst) {
memcpy(&xdst,rdst,sizeof(xdst));
} else {
......@@ -842,6 +983,14 @@ DIB_DirectDrawSurface_BltFast(LPDIRECTDRAWSURFACE7 iface, DWORD dstx,
/* Get the surface description without locking to first compute the width / height */
ddesc = This->surface_desc;
sdesc = (ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src))->surface_desc;
if ((sdesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) && (ddesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)) {
if (trans)
FIXME("trans arg not supported when a FOURCC surface is involved\n");
if (dstx || dsty)
FIXME("offset for destination surface is not supported\n");
DIB_DirectDrawSurface_Blt(iface, NULL, src, rsrc, 0, NULL);
}
if (!rsrc) {
WARN("rsrc is NULL!\n");
......
......@@ -1119,9 +1119,21 @@ Main_DirectDrawSurface_Lock(LPDIRECTDRAWSURFACE7 iface, LPRECT prect,
This->lock_update(This, prect, flags);
pDDSD->lpSurface = (char *)This->surface_desc.lpSurface
+ prect->top * This->surface_desc.u1.lPitch
+ prect->left * GET_BPP(This->surface_desc);
if (pDDSD->u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
int blksize;
switch(pDDSD->u4.ddpfPixelFormat.dwFourCC) {
case MAKE_FOURCC('D','X','T','1') : blksize = 8; break;
case MAKE_FOURCC('D','X','T','3') : blksize = 16; break;
case MAKE_FOURCC('D','X','T','5') : blksize = 16; break;
default: return DDERR_INVALIDPIXELFORMAT;
}
pDDSD->lpSurface = (char *)This->surface_desc.lpSurface
+ prect->top/4 * (pDDSD->dwWidth+3)/4 * blksize
+ prect->left/4 * blksize;
} else
pDDSD->lpSurface = (char *)This->surface_desc.lpSurface
+ prect->top * This->surface_desc.u1.lPitch
+ prect->left * GET_BPP(This->surface_desc);
} else {
This->lock_update(This, NULL, flags);
}
......
......@@ -86,7 +86,6 @@ static void *gl_handle = NULL;
static BOOL DDRAW_bind_to_opengl( void )
{
const char *glname = SONAME_LIBGL;
BOOL ret_value;
gl_handle = wine_dlopen(glname, RTLD_NOW, NULL, 0);
if (!gl_handle) {
......@@ -104,11 +103,7 @@ static BOOL DDRAW_bind_to_opengl( void )
#undef GL_API_FUNCTION
/* And now calls the function to initialize the various fields for the rendering devices */
ret_value = d3ddevice_init_at_startup(gl_handle);
wine_dlclose(gl_handle, NULL, 0);
gl_handle = NULL;
return ret_value;
return d3ddevice_init_at_startup(gl_handle);
sym_not_found:
WARN("Wine cannot find certain functions that it needs inside the OpenGL\n"
......@@ -121,6 +116,49 @@ sym_not_found:
#endif /* HAVE_OPENGL */
BOOL s3tc_initialized = 0;
static void *s3tc_handle = NULL;
FUNC_FETCH_2D_TEXEL_RGBA_DXT1 fetch_2d_texel_rgba_dxt1;
FUNC_FETCH_2D_TEXEL_RGBA_DXT3 fetch_2d_texel_rgba_dxt3;
FUNC_FETCH_2D_TEXEL_RGBA_DXT5 fetch_2d_texel_rgba_dxt5;
#ifndef SONAME_LIBTXC_DXTN
#define SONAME_LIBTXC_DXTN "libtxc_dxtn.so"
#endif
static BOOL DDRAW_bind_to_s3tc( void )
{
const char * const s3tcname = SONAME_LIBTXC_DXTN;
s3tc_handle = wine_dlopen(s3tcname, RTLD_NOW, NULL, 0);
if (!s3tc_handle) {
TRACE("No S3TC software decompression library seems to be present (%s).\n",s3tcname);
return FALSE;
}
TRACE("Found S3TC software decompression library (%s).\n",s3tcname);
#define API_FUNCTION(f) \
if((f = wine_dlsym(s3tc_handle, #f, NULL, 0)) == NULL) \
{ \
WARN("Can't find symbol %s\n", #f); \
goto sym_not_found; \
}
API_FUNCTION(fetch_2d_texel_rgba_dxt1);
API_FUNCTION(fetch_2d_texel_rgba_dxt3);
API_FUNCTION(fetch_2d_texel_rgba_dxt5);
#undef API_FUNCTION
return TRUE;
sym_not_found:
WARN("Wine cannot find functions that are necessary for S3TC software decompression\n");
wine_dlclose(s3tc_handle, NULL, 0);
s3tc_handle = NULL;
return FALSE;
}
/***********************************************************************
* DirectDrawEnumerateExA (DDRAW.@)
*/
......@@ -607,6 +645,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
#ifdef HAVE_OPENGL
opengl_initialized = DDRAW_bind_to_opengl();
#endif /* HAVE_OPENGL */
s3tc_initialized = DDRAW_bind_to_s3tc();
}
if (DDRAW_num_drivers > 0)
......
......@@ -654,6 +654,31 @@ HRESULT upload_surface_to_tex_memory_init(IDirectDrawSurfaceImpl *surf_ptr, GLui
current_surface = surf_ptr;
current_level = level;
if (src_pf->dwFlags & DDPF_FOURCC) {
GLenum retVal;
int size = surf_ptr->surface_desc.u1.dwLinearSize;
int width = surf_ptr->surface_desc.dwWidth;
int height = surf_ptr->surface_desc.dwHeight;
LPVOID buffer = surf_ptr->surface_desc.lpSurface;
switch (src_pf->dwFourCC) {
case MAKE_FOURCC('D','X','T','1'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
case MAKE_FOURCC('D','X','T','3'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
case MAKE_FOURCC('D','X','T','5'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
default:
FIXME("FourCC Not supported\n");
return DD_OK;
break;
}
if (GL_extensions.s3tc_compressed_texture) {
GL_extensions.glCompressedTexImage2D(GL_TEXTURE_2D, current_level, retVal, width, height, 0, size, buffer);
} else
ERR("Trying to upload S3TC texture whereas the device does not have support for it\n");
return DD_OK;
}
/* First, do some sanity checks ... */
if ((surf_ptr->surface_desc.u1.lPitch % bpp) != 0) {
FIXME("Warning : pitch is not a multiple of BPP - not supported yet !\n");
......@@ -932,6 +957,32 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
width = rect->right - rect->left;
height = rect->bottom - rect->top;
if (current_surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
GLint retVal;
int size = current_surface->surface_desc.u1.dwLinearSize;
int width_ = current_surface->surface_desc.dwWidth;
int height_ = current_surface->surface_desc.dwHeight;
LPVOID buffer = current_surface->surface_desc.lpSurface;
switch (current_surface->surface_desc.u4.ddpfPixelFormat.dwFourCC) {
case MAKE_FOURCC('D','X','T','1'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
case MAKE_FOURCC('D','X','T','3'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
case MAKE_FOURCC('D','X','T','5'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
default:
FIXME("Not supported\n");
return DD_OK;
break;
}
if (GL_extensions.s3tc_compressed_texture) {
/* GL_extensions.glCompressedTexSubImage2D(GL_TEXTURE_2D, current_level, xoffset, yoffset, width, height, retVal, (unsigned char*)temp_buffer); */
GL_extensions.glCompressedTexImage2D(GL_TEXTURE_2D, current_level, retVal, width_, height_, 0, size, buffer);
} else
ERR("Trying to upload S3TC texture whereas the device does not have support for it\n");
return DD_OK;
}
/* Used when converting stuff */
line_increase = src_d->u1.lPitch - (width * bpp);
......
......@@ -175,6 +175,12 @@ typedef struct {
void (*glActiveTexture)(GLenum texture);
void (*glMultiTexCoord2fv)(GLenum target, const GLfloat *v);
void (*glClientActiveTexture)(GLenum texture);
/* S3TC/DXTN compressed texture */
BOOLEAN s3tc_compressed_texture;
void (*glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width,
GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
void (*glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLsizei imageSize, const GLvoid *data);
} GL_EXTENSIONS_LIST;
extern GL_EXTENSIONS_LIST GL_extensions;
......
......@@ -893,6 +893,9 @@
/* Define to the soname of the libssl library. */
#undef SONAME_LIBSSL
/* Define to the soname of the libtxc_dxtn library. */
#undef SONAME_LIBTXC_DXTN
/* Define to the soname of the libX11 library. */
#undef SONAME_LIBX11
......
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