Commit 21856fbd authored by Lionel Ulmer's avatar Lionel Ulmer Committed by Alexandre Julliard

- implement FB => Texture blits

- fix compilation on non-recent glext.h systems
parent e4882b15
......@@ -1824,7 +1824,7 @@ GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
case D3DTOP_BLENDCURRENTALPHA: src = GL_PREVIOUS_EXT;
}
glTexEnvi(GL_TEXTURE_ENV, parm, GL_INTERPOLATE_ARB);
glTexEnvi(GL_TEXTURE_ENV, parm, GL_INTERPOLATE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, src);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, src);
......
......@@ -82,26 +82,14 @@ get_sub_mimaplevel(IDirectDrawSurfaceImpl *tex_ptr)
/*******************************************************************************
* IDirectSurface callback methods
*/
HRESULT
gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
gltex_flush_texture_memory_to_GL(IDirectDrawSurfaceImpl *surf_ptr) {
#if 0
static BOOL color_table_queried = FALSE;
#endif
static void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
IDirectDrawSurfaceImpl *surf_ptr;
GLuint tex_name = glThis->tex_name;
TRACE(" activating OpenGL texture id %d.\n", tex_name);
glBindTexture(GL_TEXTURE_2D, tex_name);
if (This->mipmap_level != 0) {
WARN(" application activating a sub-level of the mipmapping chain (level %d) !\n", This->mipmap_level);
}
surf_ptr = This;
while (surf_ptr != NULL) {
GLenum internal_format = GL_RGBA, format = GL_RGBA, pixel_format = GL_UNSIGNED_BYTE; /* This is only to prevent warnings.. */
VOID *surface = NULL;
DDSURFACEDESC *src_d = (DDSURFACEDESC *)&(surf_ptr->surface_desc);
......@@ -109,7 +97,7 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
BOOL upload_done = FALSE;
BOOL error = FALSE;
if (gl_surf_ptr->dirty_flag == FALSE) {
if (gl_surf_ptr->dirty_flag != SURFACE_MEMORY_DIRTY) {
TRACE(" - level %d already uploaded.\n", surf_ptr->mipmap_level);
} else {
TRACE(" - uploading texture level %d (initial done = %d).\n",
......@@ -178,8 +166,8 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
DWORD i;
BYTE *src = (BYTE *) src_d->lpSurface, *dst;
if (glThis->surface_ptr != NULL)
surface = glThis->surface_ptr;
if (gl_surf_ptr->surface_ptr != NULL)
surface = gl_surf_ptr->surface_ptr;
else
surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
dst = (BYTE *) surface;
......@@ -238,8 +226,8 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
DWORD i;
WORD *src = (WORD *) src_d->lpSurface, *dst;
if (glThis->surface_ptr != NULL)
surface = glThis->surface_ptr;
if (gl_surf_ptr->surface_ptr != NULL)
surface = gl_surf_ptr->surface_ptr;
else
surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
......@@ -273,8 +261,8 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
DWORD i;
WORD *src = (WORD *) src_d->lpSurface, *dst;
if (glThis->surface_ptr != NULL)
surface = glThis->surface_ptr;
if (gl_surf_ptr->surface_ptr != NULL)
surface = gl_surf_ptr->surface_ptr;
else
surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
......@@ -300,8 +288,8 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
DWORD i;
WORD *src = (WORD *) src_d->lpSurface, *dst;
if (glThis->surface_ptr != NULL)
surface = glThis->surface_ptr;
if (gl_surf_ptr->surface_ptr != NULL)
surface = gl_surf_ptr->surface_ptr;
else
surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
......@@ -324,8 +312,8 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
DWORD i;
WORD *src = (WORD *) src_d->lpSurface, *dst;
if (glThis->surface_ptr != NULL)
surface = glThis->surface_ptr;
if (gl_surf_ptr->surface_ptr != NULL)
surface = gl_surf_ptr->surface_ptr;
else
surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
......@@ -355,8 +343,8 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
DWORD i;
WORD *src = (WORD *) src_d->lpSurface, *dst;
if (glThis->surface_ptr != NULL)
surface = glThis->surface_ptr;
if (gl_surf_ptr->surface_ptr != NULL)
surface = gl_surf_ptr->surface_ptr;
else
surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
......@@ -386,8 +374,8 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
DWORD i;
WORD *src = (WORD *) src_d->lpSurface, *dst;
if (glThis->surface_ptr != NULL)
surface = glThis->surface_ptr;
if (gl_surf_ptr->surface_ptr != NULL)
surface = gl_surf_ptr->surface_ptr;
else
surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
......@@ -426,8 +414,8 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
BYTE *src = (BYTE *) src_d->lpSurface;
DWORD *dst;
if (glThis->surface_ptr != NULL)
surface = glThis->surface_ptr;
if (gl_surf_ptr->surface_ptr != NULL)
surface = gl_surf_ptr->surface_ptr;
else
surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
......@@ -462,8 +450,8 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
DWORD i;
DWORD *src = (DWORD *) src_d->lpSurface, *dst;
if (glThis->surface_ptr != NULL)
surface = glThis->surface_ptr;
if (gl_surf_ptr->surface_ptr != NULL)
surface = gl_surf_ptr->surface_ptr;
else
surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
......@@ -489,8 +477,8 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
DWORD i;
DWORD *src = (DWORD *) src_d->lpSurface, *dst;
if (glThis->surface_ptr != NULL)
surface = glThis->surface_ptr;
if (gl_surf_ptr->surface_ptr != NULL)
surface = gl_surf_ptr->surface_ptr;
else
surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
......@@ -519,8 +507,8 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
DWORD i;
DWORD *src = (DWORD *) src_d->lpSurface, *dst;
if (glThis->surface_ptr != NULL)
surface = glThis->surface_ptr;
if (gl_surf_ptr->surface_ptr != NULL)
surface = gl_surf_ptr->surface_ptr;
else
surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
dst = (DWORD *) surface;
......@@ -572,11 +560,11 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
pixel_format,
surface == NULL ? src_d->lpSurface : surface);
}
gl_surf_ptr->dirty_flag = FALSE;
gl_surf_ptr->dirty_flag = SURFACE_MEMORY;
/* And store the surface pointer for future reuse.. */
if (surface)
glThis->surface_ptr = surface;
gl_surf_ptr->surface_ptr = surface;
} else if (error == TRUE) {
if (ERR_ON(ddraw)) {
ERR(" unsupported pixel format for textures : \n");
......@@ -585,6 +573,38 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
}
}
return DD_OK;
}
HRESULT
gltex_flush_texture_GL_to_memory(IDirectDrawSurfaceImpl *surf_ptr) {
IDirect3DTextureGLImpl *gl_surf_ptr = (IDirect3DTextureGLImpl *) surf_ptr->tex_private;
FIXME("This is not supported yet... Expect some graphical glitches !!!\n");
/* GL and memory are in sync again ... */
gl_surf_ptr->dirty_flag = SURFACE_MEMORY;
return DD_OK;
}
HRESULT
gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
IDirectDrawSurfaceImpl *surf_ptr;
GLuint tex_name = glThis->tex_name;
TRACE(" activating OpenGL texture id %d.\n", tex_name);
glBindTexture(GL_TEXTURE_2D, tex_name);
if (This->mipmap_level != 0) {
WARN(" application activating a sub-level of the mipmapping chain (level %d) !\n", This->mipmap_level);
}
surf_ptr = This;
while (surf_ptr != NULL) {
gltex_flush_texture_memory_to_GL(surf_ptr);
if (surf_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) {
surf_ptr = get_sub_mimaplevel(surf_ptr);
} else {
......@@ -610,12 +630,124 @@ gltex_setcolorkey_cb(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDDCOLORKEY c
{
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
glThis->dirty_flag = TRUE;
if (glThis->dirty_flag == SURFACE_GL) {
GLuint cur_tex;
ENTER_GL();
glGetIntegerv(GL_TEXTURE_BINDING_2D, &cur_tex);
glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
gltex_flush_texture_GL_to_memory(This);
glBindTexture(GL_TEXTURE_2D, cur_tex);
LEAVE_GL();
}
glThis->dirty_flag = SURFACE_MEMORY_DIRTY;
/* TODO: check color-keying on mipmapped surfaces... */
return DD_OK;
}
HRESULT
gltex_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst,
LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,
DWORD dwFlags, LPDDBLTFX lpbltfx)
{
if (src != NULL) {
IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src);
if (src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) {
FIXME("Blt from framebuffer to texture - unsupported now, please report !\n");
}
}
return DDERR_INVALIDPARAMS;
}
HRESULT
gltex_bltfast(IDirectDrawSurfaceImpl *surf_ptr, DWORD dstx,
DWORD dsty, LPDIRECTDRAWSURFACE7 src,
LPRECT rsrc, DWORD trans)
{
if (src != NULL) {
IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src);
if ((src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) &&
((trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) == 0)) {
/* This is a blt without color keying... We can use the direct copy. */
RECT rsrc2;
DWORD width, height;
GLuint cur_tex;
IDirect3DTextureGLImpl *gl_surf_ptr = surf_ptr->tex_private;
int y;
if (rsrc == NULL) {
WARN("rsrc is NULL\n");
rsrc = &rsrc2;
rsrc->left = 0;
rsrc->top = 0;
rsrc->right = src_ptr->surface_desc.dwWidth;
rsrc->bottom = src_ptr->surface_desc.dwHeight;
}
width = rsrc->right - rsrc->left;
height = rsrc->bottom - rsrc->top;
if (((dstx + width) > surf_ptr->surface_desc.dwWidth) ||
((dsty + height) > surf_ptr->surface_desc.dwHeight)) {
FIXME("Does not handle clipping yet in FB => Texture blits !\n");
return DDERR_INVALIDPARAMS;
}
TRACE(" direct frame buffer => texture BltFast override.\n");
ENTER_GL();
glGetIntegerv(GL_TEXTURE_BINDING_2D, &cur_tex);
glBindTexture(GL_TEXTURE_2D, gl_surf_ptr->tex_name);
if ((gl_surf_ptr->dirty_flag == SURFACE_MEMORY_DIRTY) &&
!((dstx == 0) && (dsty == 0) &&
(width == surf_ptr->surface_desc.dwWidth) && (height == surf_ptr->surface_desc.dwHeight))) {
/* If not 'full size' and the surface is dirty, first flush it to GL before doing the copy. */
gltex_flush_texture_memory_to_GL(surf_ptr);
}
/* This is a hack and would need some clean-up :-) */
if (gl_surf_ptr->initial_upload_done == FALSE) {
gl_surf_ptr->dirty_flag = SURFACE_MEMORY_DIRTY;
gltex_flush_texture_memory_to_GL(surf_ptr);
}
if ((src_ptr->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0)
glReadBuffer(GL_FRONT);
else if ((src_ptr->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER))
glReadBuffer(GL_BACK);
else {
ERR("Wrong surface type for locking !\n");
LEAVE_GL();
return DDERR_INVALIDPARAMS;
}
for (y = src_ptr->surface_desc.dwHeight - rsrc->top;
y >= (src_ptr->surface_desc.dwHeight - (rsrc->top + height));
y--) {
glCopyTexSubImage2D(GL_TEXTURE_2D, surf_ptr->mipmap_level,
dstx, dsty,
rsrc->left, y,
width, 1);
dsty++;
}
glBindTexture(GL_TEXTURE_2D, cur_tex);
LEAVE_GL();
gl_surf_ptr->dirty_flag = SURFACE_GL;
return DD_OK;
}
}
return DDERR_INVALIDPARAMS;
}
HRESULT WINAPI
Main_IDirect3DTextureImpl_2_1T_PaletteChanged(LPDIRECT3DTEXTURE2 iface,
DWORD dwStart,
......@@ -668,13 +800,25 @@ static void gltex_set_palette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteIm
{
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
if (glThis->dirty_flag == SURFACE_GL) {
GLuint cur_tex;
ENTER_GL();
glGetIntegerv(GL_TEXTURE_BINDING_2D, &cur_tex);
glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
gltex_flush_texture_GL_to_memory(This);
glBindTexture(GL_TEXTURE_2D, cur_tex);
LEAVE_GL();
}
/* First call the previous set_palette function */
glThis->set_palette(This, pal);
/* And set the dirty flag */
glThis->dirty_flag = TRUE;
glThis->dirty_flag = SURFACE_MEMORY_DIRTY;
/* TODO: check palette on mipmapped surfaces... */
/* TODO: check palette on mipmapped surfaces...
TODO: do we need to re-upload in case of usage of the paletted texture extension ? */
}
static void
......@@ -728,7 +872,7 @@ gltex_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
/* Set the dirty flag according to the lock type */
if ((This->lastlocktype & DDLOCK_READONLY) == 0)
glThis->dirty_flag = TRUE;
glThis->dirty_flag = SURFACE_MEMORY_DIRTY;
}
HRESULT WINAPI
......@@ -817,7 +961,7 @@ GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
if (gl_dst_ptr->tex_name == 0) ERR("Unbound GL texture !!!\n");
/* Set this texture as dirty */
gl_dst_ptr->dirty_flag = TRUE;
gl_dst_ptr->dirty_flag = SURFACE_MEMORY_DIRTY;
}
}
......@@ -997,6 +1141,11 @@ HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOL
surf->aux_setcolorkey_cb = gltex_setcolorkey_cb;
surf->set_palette = gltex_set_palette;
/* We are the only one to use the aux_blt and aux_bltfast overides, so no need
to save those... */
surf->aux_blt = gltex_blt;
surf->aux_bltfast = gltex_bltfast;
ENTER_GL();
if (surf->mipmap_level == 0) {
glGenTextures(1, &(private->tex_name));
......@@ -1010,7 +1159,7 @@ HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOL
LEAVE_GL();
/* And set the dirty flag accordingly */
private->dirty_flag = (at_creation == FALSE);
private->dirty_flag = (at_creation == FALSE ? SURFACE_MEMORY_DIRTY : SURFACE_MEMORY);
private->initial_upload_done = FALSE;
}
......
......@@ -39,6 +39,7 @@ GL_API_FUNCTION(glColor3f)
GL_API_FUNCTION(glColor3ub)
GL_API_FUNCTION(glColor4ub)
GL_API_FUNCTION(glColorMaterial)
GL_API_FUNCTION(glCopyTexSubImage2D)
GL_API_FUNCTION(glCullFace)
GL_API_FUNCTION(glDeleteTextures)
GL_API_FUNCTION(glDepthFunc)
......
......@@ -63,6 +63,7 @@
#define glColor3f pglColor3f
#define glColor3ub pglColor3ub
#define glColor4ub pglColor4ub
#define glCopyTexSubImage2D pglCopyTexSubImage2D
#define glColorMaterial pglColorMaterial
#define glCullFace pglCullFace
#define glDeleteTextures pglDeleteTextures
......
......@@ -39,6 +39,12 @@ extern void (*wine_tsx11_unlock_ptr)(void);
extern const GUID IID_D3DDEVICE_OpenGL;
typedef enum {
SURFACE_GL,
SURFACE_MEMORY,
SURFACE_MEMORY_DIRTY
} SURFACE_STATE;
typedef struct IDirect3DGLImpl
{
struct IDirect3DImpl parent;
......@@ -60,7 +66,7 @@ typedef struct IDirect3DTextureGLImpl
/* Texture upload management */
BOOLEAN initial_upload_done;
BOOLEAN dirty_flag;
SURFACE_STATE dirty_flag;
/* Surface optimization */
void *surface_ptr;
......@@ -79,12 +85,6 @@ typedef enum {
GL_TRANSFORM_VERTEXBUFFER
} GL_TRANSFORM_STATE;
typedef enum {
SURFACE_GL,
SURFACE_MEMORY,
SURFACE_MEMORY_DIRTY
} SURFACE_STATE;
typedef struct IDirect3DDeviceGLImpl
{
struct IDirect3DDeviceImpl parent;
......
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