Added native and emulated S3TC support.
This commit is contained in:
parent
df80b56953
commit
eac96b5606
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue