mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 20:59:54 +00:00
- fix the texture upload code when RECT is actually used
- optimize FB Locks / Unlocks when RECTs are used
This commit is contained in:
parent
e14233ae03
commit
068fa5d471
@ -107,11 +107,11 @@ static BOOL opengl_flip( LPVOID dev, LPVOID drawable)
|
||||
|
||||
TRACE("(%p, %ld)\n", gl_d3d_dev->display,(Drawable)drawable);
|
||||
ENTER_GL();
|
||||
if (gl_d3d_dev->state == SURFACE_MEMORY_DIRTY) {
|
||||
d3d_dev->flush_to_framebuffer(d3d_dev, NULL, gl_d3d_dev->lock_surf);
|
||||
if (gl_d3d_dev->state[WINE_GL_BUFFER_BACK] == SURFACE_MEMORY_DIRTY) {
|
||||
d3d_dev->flush_to_framebuffer(d3d_dev, &(gl_d3d_dev->lock_rect[WINE_GL_BUFFER_BACK]), gl_d3d_dev->lock_surf[WINE_GL_BUFFER_BACK]);
|
||||
}
|
||||
gl_d3d_dev->state = SURFACE_GL;
|
||||
gl_d3d_dev->front_state = SURFACE_GL;
|
||||
gl_d3d_dev->state[WINE_GL_BUFFER_BACK] = SURFACE_GL;
|
||||
gl_d3d_dev->state[WINE_GL_BUFFER_FRONT] = SURFACE_GL;
|
||||
glXSwapBuffers(gl_d3d_dev->display, (Drawable)drawable);
|
||||
LEAVE_GL();
|
||||
|
||||
@ -1103,11 +1103,11 @@ static void draw_primitive_strided(IDirect3DDeviceImpl *This,
|
||||
EnterCriticalSection(&(This->crit));
|
||||
|
||||
ENTER_GL();
|
||||
if (glThis->state == SURFACE_MEMORY_DIRTY) {
|
||||
This->flush_to_framebuffer(This, NULL, glThis->lock_surf);
|
||||
if (glThis->state[WINE_GL_BUFFER_BACK] == SURFACE_MEMORY_DIRTY) {
|
||||
This->flush_to_framebuffer(This, &(glThis->lock_rect[WINE_GL_BUFFER_BACK]), glThis->lock_surf[WINE_GL_BUFFER_BACK]);
|
||||
}
|
||||
|
||||
glThis->state = SURFACE_GL;
|
||||
glThis->state[WINE_GL_BUFFER_BACK] = SURFACE_GL;
|
||||
|
||||
/* Just a hack for now.. Will have to find better algorithm :-/ */
|
||||
if ((d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ) {
|
||||
@ -2413,11 +2413,11 @@ static HRESULT d3ddevice_clear(IDirect3DDeviceImpl *This,
|
||||
/* Clears the screen */
|
||||
ENTER_GL();
|
||||
|
||||
if (glThis->state == SURFACE_MEMORY_DIRTY) {
|
||||
if (glThis->state[WINE_GL_BUFFER_BACK] == SURFACE_MEMORY_DIRTY) {
|
||||
/* TODO: optimize here the case where Clear changes all the screen... */
|
||||
This->flush_to_framebuffer(This, NULL, glThis->lock_surf);
|
||||
This->flush_to_framebuffer(This, &(glThis->lock_rect[WINE_GL_BUFFER_BACK]), glThis->lock_surf[WINE_GL_BUFFER_BACK]);
|
||||
}
|
||||
glThis->state = SURFACE_GL;
|
||||
glThis->state[WINE_GL_BUFFER_BACK] = SURFACE_GL;
|
||||
|
||||
if (dwFlags & D3DCLEAR_ZBUFFER) {
|
||||
bitfield |= GL_DEPTH_BUFFER_BIT;
|
||||
@ -2700,40 +2700,78 @@ static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, D
|
||||
{
|
||||
IDirect3DDeviceImpl *d3d_dev = This->d3ddevice;
|
||||
IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev;
|
||||
BOOLEAN is_front;
|
||||
WINE_GL_BUFFER_TYPE buffer_type;
|
||||
RECT loc_rect;
|
||||
|
||||
if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
|
||||
is_front = TRUE;
|
||||
if ((gl_d3d_dev->front_state != SURFACE_GL) &&
|
||||
(gl_d3d_dev->front_lock_surf != This)) {
|
||||
buffer_type = WINE_GL_BUFFER_FRONT;
|
||||
if ((gl_d3d_dev->state[WINE_GL_BUFFER_FRONT] != SURFACE_GL) &&
|
||||
(gl_d3d_dev->lock_surf[WINE_GL_BUFFER_FRONT] != This)) {
|
||||
ERR("Change of front buffer.. Expect graphic corruptions !\n");
|
||||
}
|
||||
gl_d3d_dev->front_lock_surf = This;
|
||||
gl_d3d_dev->lock_surf[WINE_GL_BUFFER_FRONT] = This;
|
||||
} else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
|
||||
is_front = FALSE;
|
||||
if ((gl_d3d_dev->state != SURFACE_GL) &&
|
||||
(gl_d3d_dev->lock_surf != This)) {
|
||||
buffer_type = WINE_GL_BUFFER_BACK;
|
||||
if ((gl_d3d_dev->state[WINE_GL_BUFFER_BACK] != SURFACE_GL) &&
|
||||
(gl_d3d_dev->lock_surf[WINE_GL_BUFFER_BACK] != This)) {
|
||||
ERR("Change of back buffer.. Expect graphic corruptions !\n");
|
||||
}
|
||||
gl_d3d_dev->lock_surf = This;
|
||||
gl_d3d_dev->lock_surf[WINE_GL_BUFFER_BACK] = This;
|
||||
} else {
|
||||
ERR("Wrong surface type for locking !\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (pRect == NULL) {
|
||||
loc_rect.top = 0;
|
||||
loc_rect.left = 0;
|
||||
loc_rect.bottom = This->surface_desc.dwHeight;
|
||||
loc_rect.right = This->surface_desc.dwWidth;
|
||||
pRect = &loc_rect;
|
||||
}
|
||||
|
||||
/* Try to acquire the device critical section */
|
||||
EnterCriticalSection(&(d3d_dev->crit));
|
||||
|
||||
if (((is_front == TRUE) && (gl_d3d_dev->front_state == SURFACE_GL)) ||
|
||||
((is_front == FALSE) && (gl_d3d_dev->state == SURFACE_GL))) {
|
||||
if (gl_d3d_dev->lock_rect_valid[buffer_type] == TRUE) {
|
||||
ERR("Two consecutive locks on %s buffer... Expect problems !\n",
|
||||
(buffer_type == WINE_GL_BUFFER_BACK ? "back" : "front"));
|
||||
}
|
||||
gl_d3d_dev->lock_rect_valid[buffer_type] = TRUE;
|
||||
|
||||
if (gl_d3d_dev->state[buffer_type] != SURFACE_GL) {
|
||||
/* Check if the new rectangle is in the previous one or not.
|
||||
If it is not, flush first the previous locks on screen.
|
||||
*/
|
||||
if ((pRect->top < gl_d3d_dev->lock_rect[buffer_type].top) ||
|
||||
(pRect->left < gl_d3d_dev->lock_rect[buffer_type].left) ||
|
||||
(pRect->right > gl_d3d_dev->lock_rect[buffer_type].right) ||
|
||||
(pRect->bottom > gl_d3d_dev->lock_rect[buffer_type].bottom)) {
|
||||
if (gl_d3d_dev->state[buffer_type] == SURFACE_MEMORY_DIRTY) {
|
||||
TRACE(" flushing back to %s buffer as new rect : (%ldx%ld) - (%ldx%ld) not included in old rect : (%ldx%ld) - (%ldx%ld)\n",
|
||||
(buffer_type == WINE_GL_BUFFER_BACK ? "back" : "front"),
|
||||
pRect->left, pRect->top, pRect->right, pRect->bottom,
|
||||
gl_d3d_dev->lock_rect[buffer_type].left, gl_d3d_dev->lock_rect[buffer_type].top,
|
||||
gl_d3d_dev->lock_rect[buffer_type].right, gl_d3d_dev->lock_rect[buffer_type].bottom);
|
||||
d3d_dev->flush_to_framebuffer(d3d_dev, &(gl_d3d_dev->lock_rect[buffer_type]), gl_d3d_dev->lock_surf[buffer_type]);
|
||||
}
|
||||
gl_d3d_dev->state[buffer_type] = SURFACE_GL;
|
||||
gl_d3d_dev->lock_rect[buffer_type] = *pRect;
|
||||
}
|
||||
/* In the other case, do not upgrade the locking rectangle as it's no need... */
|
||||
} else {
|
||||
gl_d3d_dev->lock_rect[buffer_type] = *pRect;
|
||||
}
|
||||
|
||||
if (gl_d3d_dev->state[buffer_type] == SURFACE_GL) {
|
||||
/* If the surface is already in memory, no need to do anything here... */
|
||||
GLenum buffer_type;
|
||||
GLenum buffer_format;
|
||||
GLenum buffer_color;
|
||||
RECT loc_rect;
|
||||
int y;
|
||||
char *dst;
|
||||
|
||||
TRACE(" copying frame buffer to main memory.\n");
|
||||
TRACE(" copying %s buffer to main memory with rectangle (%ldx%ld) - (%ldx%ld).\n", (buffer_type == WINE_GL_BUFFER_BACK ? "back" : "front"),
|
||||
pRect->left, pRect->top, pRect->right, pRect->bottom);
|
||||
|
||||
/* Note that here we cannot do 'optmizations' about the WriteOnly flag... Indeed, a game
|
||||
may only write to the device... But when we will blit it back to the screen, we need
|
||||
@ -2746,19 +2784,19 @@ static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, D
|
||||
(This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0xF800) &&
|
||||
(This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x07E0) &&
|
||||
(This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x001F)) {
|
||||
buffer_type = GL_UNSIGNED_SHORT_5_6_5;
|
||||
buffer_format = GL_UNSIGNED_SHORT_5_6_5;
|
||||
buffer_color = GL_RGB;
|
||||
} else if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 24) &&
|
||||
(This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0xFF0000) &&
|
||||
(This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x00FF00) &&
|
||||
(This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x0000FF)) {
|
||||
buffer_type = GL_UNSIGNED_BYTE;
|
||||
buffer_format = GL_UNSIGNED_BYTE;
|
||||
buffer_color = GL_RGB;
|
||||
} else if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) &&
|
||||
(This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) &&
|
||||
(This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) &&
|
||||
(This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x000000FF)) {
|
||||
buffer_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
buffer_format = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
buffer_color = GL_BGRA;
|
||||
} else {
|
||||
ERR(" unsupported pixel format at device locking.\n");
|
||||
@ -2771,39 +2809,25 @@ static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, D
|
||||
|
||||
ENTER_GL();
|
||||
|
||||
if (is_front == TRUE)
|
||||
if (buffer_type == WINE_GL_BUFFER_FRONT)
|
||||
/* Application wants to lock the front buffer */
|
||||
glReadBuffer(GL_FRONT);
|
||||
else
|
||||
/* Application wants to lock the back buffer */
|
||||
glReadBuffer(GL_BACK);
|
||||
|
||||
/* Just a hack while waiting for proper rectangle support */
|
||||
pRect = NULL;
|
||||
if (pRect == NULL) {
|
||||
loc_rect.top = 0;
|
||||
loc_rect.left = 0;
|
||||
loc_rect.bottom = This->surface_desc.dwHeight;
|
||||
loc_rect.right = This->surface_desc.dwWidth;
|
||||
} else {
|
||||
loc_rect = *pRect;
|
||||
}
|
||||
|
||||
dst = ((char *)This->surface_desc.lpSurface) +
|
||||
(loc_rect.top * This->surface_desc.u1.lPitch) + (loc_rect.left * GET_BPP(This->surface_desc));
|
||||
for (y = (This->surface_desc.dwHeight - loc_rect.top - 1);
|
||||
y >= ((int) This->surface_desc.dwHeight - (int) loc_rect.bottom);
|
||||
(pRect->top * This->surface_desc.u1.lPitch) + (pRect->left * GET_BPP(This->surface_desc));
|
||||
for (y = (This->surface_desc.dwHeight - pRect->top - 1);
|
||||
y >= ((int) This->surface_desc.dwHeight - (int) pRect->bottom);
|
||||
y--) {
|
||||
glReadPixels(loc_rect.left, y,
|
||||
loc_rect.right - loc_rect.left, 1,
|
||||
buffer_color, buffer_type, dst);
|
||||
glReadPixels(pRect->left, y,
|
||||
pRect->right - pRect->left, 1,
|
||||
buffer_color, buffer_format, dst);
|
||||
dst += This->surface_desc.u1.lPitch;
|
||||
}
|
||||
|
||||
if (is_front)
|
||||
gl_d3d_dev->front_state = SURFACE_MEMORY;
|
||||
else
|
||||
gl_d3d_dev->state = SURFACE_MEMORY;
|
||||
gl_d3d_dev->state[buffer_type] = SURFACE_MEMORY;
|
||||
|
||||
#if 0
|
||||
/* I keep this code here as it's very useful to debug :-) */
|
||||
@ -2835,13 +2859,16 @@ static void d3ddevice_flush_to_frame_buffer(IDirect3DDeviceImpl *d3d_dev, LPCREC
|
||||
|
||||
/* Note : no need here to lock the 'device critical section' as we are already protected by
|
||||
the GL critical section. */
|
||||
|
||||
loc_rect.top = 0;
|
||||
loc_rect.left = 0;
|
||||
loc_rect.bottom = surf->surface_desc.dwHeight;
|
||||
loc_rect.right = surf->surface_desc.dwWidth;
|
||||
|
||||
TRACE(" flushing memory back to the frame-buffer (%ld,%ld) x (%ld,%ld).\n", loc_rect.top, loc_rect.left, loc_rect.right, loc_rect.bottom);
|
||||
if (pRect == NULL) {
|
||||
loc_rect.top = 0;
|
||||
loc_rect.left = 0;
|
||||
loc_rect.bottom = surf->surface_desc.dwHeight;
|
||||
loc_rect.right = surf->surface_desc.dwWidth;
|
||||
pRect = &loc_rect;
|
||||
}
|
||||
|
||||
TRACE(" flushing memory back to screen memory (%ld,%ld) x (%ld,%ld).\n", pRect->top, pRect->left, pRect->right, pRect->bottom);
|
||||
|
||||
/* This is a hack to prevent querying the current texture from GL */
|
||||
gl_d3d_dev->current_bound_texture[0] = (IDirectDrawSurfaceImpl *) 0x00000001;
|
||||
@ -2883,8 +2910,8 @@ static void d3ddevice_flush_to_frame_buffer(IDirect3DDeviceImpl *d3d_dev, LPCREC
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glDepthRange(0.0, 1.0);
|
||||
glViewport(0, 0, d3d_dev->surface->surface_desc.dwWidth, d3d_dev->surface->surface_desc.dwHeight);
|
||||
glScissor(loc_rect.left, surf->surface_desc.dwHeight - loc_rect.bottom,
|
||||
loc_rect.right - loc_rect.left, loc_rect.bottom - loc_rect.top);
|
||||
glScissor(pRect->left, surf->surface_desc.dwHeight - pRect->bottom,
|
||||
pRect->right - pRect->left, pRect->bottom - pRect->top);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
@ -2893,15 +2920,15 @@ static void d3ddevice_flush_to_frame_buffer(IDirect3DDeviceImpl *d3d_dev, LPCREC
|
||||
glDisable(GL_FOG);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
|
||||
for (x = loc_rect.left; x < loc_rect.right; x += UNLOCK_TEX_SIZE) {
|
||||
for (y = loc_rect.top; y < loc_rect.bottom; y += UNLOCK_TEX_SIZE) {
|
||||
for (x = pRect->left; x < pRect->right; x += UNLOCK_TEX_SIZE) {
|
||||
for (y = pRect->top; y < pRect->bottom; y += UNLOCK_TEX_SIZE) {
|
||||
/* First, upload the texture... */
|
||||
RECT flush_rect;
|
||||
|
||||
flush_rect.left = x;
|
||||
flush_rect.top = y;
|
||||
flush_rect.right = (x + UNLOCK_TEX_SIZE > surf->surface_desc.dwWidth) ? surf->surface_desc.dwWidth : (x + UNLOCK_TEX_SIZE);
|
||||
flush_rect.bottom = (y + UNLOCK_TEX_SIZE > surf->surface_desc.dwHeight) ? surf->surface_desc.dwHeight : (y + UNLOCK_TEX_SIZE);
|
||||
flush_rect.right = (x + UNLOCK_TEX_SIZE > pRect->right) ? pRect->right : (x + UNLOCK_TEX_SIZE);
|
||||
flush_rect.bottom = (y + UNLOCK_TEX_SIZE > pRect->bottom) ? pRect->bottom : (y + UNLOCK_TEX_SIZE);
|
||||
|
||||
upload_surface_to_tex_memory(&flush_rect, 0, 0, &(gl_d3d_dev->surface_ptr));
|
||||
|
||||
@ -2956,21 +2983,28 @@ static void d3ddevice_flush_to_frame_buffer(IDirect3DDeviceImpl *d3d_dev, LPCREC
|
||||
|
||||
static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
|
||||
{
|
||||
BOOLEAN is_front;
|
||||
WINE_GL_BUFFER_TYPE buffer_type;
|
||||
IDirect3DDeviceImpl *d3d_dev = This->d3ddevice;
|
||||
IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev;
|
||||
|
||||
if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
|
||||
is_front = TRUE;
|
||||
buffer_type = WINE_GL_BUFFER_FRONT;
|
||||
} else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
|
||||
is_front = FALSE;
|
||||
buffer_type = WINE_GL_BUFFER_BACK;
|
||||
} else {
|
||||
ERR("Wrong surface type for locking !\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (gl_d3d_dev->lock_rect_valid[buffer_type] == FALSE) {
|
||||
ERR("Unlock without prior lock on %s buffer... Expect problems !\n",
|
||||
(buffer_type == WINE_GL_BUFFER_BACK ? "back" : "front"));
|
||||
}
|
||||
gl_d3d_dev->lock_rect_valid[buffer_type] = FALSE;
|
||||
|
||||
/* First, check if we need to do anything. For the backbuffer, flushing is done at the next 3D activity. */
|
||||
if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
|
||||
if (is_front == TRUE) {
|
||||
if (buffer_type == WINE_GL_BUFFER_FRONT) {
|
||||
GLenum prev_draw;
|
||||
|
||||
TRACE(" flushing front buffer immediatly on screen.\n");
|
||||
@ -2978,11 +3012,15 @@ static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
|
||||
ENTER_GL();
|
||||
glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
|
||||
glDrawBuffer(GL_FRONT);
|
||||
d3d_dev->flush_to_framebuffer(d3d_dev, pRect, gl_d3d_dev->front_lock_surf);
|
||||
/* Note: we do not use the application provided lock rectangle but our own stored at
|
||||
lock time. This is because in old D3D versions, the 'lock' parameter did not
|
||||
exist.
|
||||
*/
|
||||
d3d_dev->flush_to_framebuffer(d3d_dev, &(gl_d3d_dev->lock_rect[WINE_GL_BUFFER_FRONT]), gl_d3d_dev->lock_surf[WINE_GL_BUFFER_FRONT]);
|
||||
glDrawBuffer(prev_draw);
|
||||
LEAVE_GL();
|
||||
} else {
|
||||
gl_d3d_dev->state = SURFACE_MEMORY_DIRTY;
|
||||
gl_d3d_dev->state[WINE_GL_BUFFER_BACK] = SURFACE_MEMORY_DIRTY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3156,7 +3194,8 @@ d3ddevice_create(IDirect3DDeviceImpl **obj, IDirectDrawImpl *d3d, IDirectDrawSur
|
||||
/* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
|
||||
LEAVE_GL();
|
||||
|
||||
gl_object->state = SURFACE_GL;
|
||||
gl_object->state[WINE_GL_BUFFER_BACK] = SURFACE_GL;
|
||||
gl_object->state[WINE_GL_BUFFER_FRONT] = SURFACE_GL;
|
||||
|
||||
/* fill_device_capabilities(d3d->ddraw); */
|
||||
|
||||
|
@ -596,7 +596,8 @@ HRESULT upload_surface_to_tex_memory_init(IDirectDrawSurfaceImpl *surf_ptr, GLui
|
||||
BOOL colorkey_active = need_alpha_ck && (surf_ptr->surface_desc.dwFlags & DDSD_CKSRCBLT);
|
||||
GLenum internal_format = GL_LUMINANCE; /* A bogus value to be sure to have a nice Mesa warning :-) */
|
||||
BYTE bpp = GET_BPP(surf_ptr->surface_desc);
|
||||
|
||||
BOOL sub_texture = TRUE;
|
||||
|
||||
current_surface = surf_ptr;
|
||||
current_level = level;
|
||||
|
||||
@ -606,14 +607,9 @@ HRESULT upload_surface_to_tex_memory_init(IDirectDrawSurfaceImpl *surf_ptr, GLui
|
||||
}
|
||||
|
||||
/* Note: we only check width here as you cannot have width non-zero while height is set to zero */
|
||||
if (tex_width != 0) {
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, surf_ptr->surface_desc.u1.lPitch / bpp);
|
||||
} else {
|
||||
if (surf_ptr->surface_desc.u1.lPitch == (surf_ptr->surface_desc.dwWidth * bpp)) {
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
} else {
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, surf_ptr->surface_desc.u1.lPitch / bpp);
|
||||
}
|
||||
if (tex_width == 0) {
|
||||
sub_texture = FALSE;
|
||||
|
||||
tex_width = surf_ptr->surface_desc.dwWidth;
|
||||
tex_height = surf_ptr->surface_desc.dwHeight;
|
||||
}
|
||||
@ -841,6 +837,17 @@ HRESULT upload_surface_to_tex_memory_init(IDirectDrawSurfaceImpl *surf_ptr, GLui
|
||||
}
|
||||
}
|
||||
|
||||
if ((sub_texture == TRUE) && (convert_type == NO_CONVERSION)) {
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, surf_ptr->surface_desc.u1.lPitch / bpp);
|
||||
} else {
|
||||
if (surf_ptr->surface_desc.u1.lPitch == (surf_ptr->surface_desc.dwWidth * bpp)) {
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
} else {
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, surf_ptr->surface_desc.u1.lPitch / bpp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
@ -851,7 +858,8 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
|
||||
RECT lrect;
|
||||
DWORD width, height;
|
||||
BYTE bpp = GET_BPP(current_surface->surface_desc);
|
||||
|
||||
int line_increase;
|
||||
|
||||
if (rect == NULL) {
|
||||
lrect.top = 0;
|
||||
lrect.left = 0;
|
||||
@ -863,11 +871,15 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
|
||||
width = rect->right - rect->left;
|
||||
height = rect->bottom - rect->top;
|
||||
|
||||
/* Used when converting stuff */
|
||||
line_increase = src_d->dwWidth - width;
|
||||
|
||||
switch (convert_type) {
|
||||
case CONVERT_PALETTED: {
|
||||
IDirectDrawPaletteImpl* pal = current_surface->palette;
|
||||
BYTE table[256][4];
|
||||
int i;
|
||||
int x, y;
|
||||
BYTE *src = (BYTE *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
|
||||
|
||||
if (pal == NULL) {
|
||||
@ -896,13 +908,16 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
|
||||
*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
current_tex_width * current_tex_height * sizeof(DWORD));
|
||||
dst = (BYTE *) *temp_buffer;
|
||||
|
||||
for (i = 0; i < height * width; i++) {
|
||||
BYTE color = *src++;
|
||||
*dst++ = table[color][0];
|
||||
*dst++ = table[color][1];
|
||||
*dst++ = table[color][2];
|
||||
*dst++ = table[color][3];
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
BYTE color = *src++;
|
||||
*dst++ = table[color][0];
|
||||
*dst++ = table[color][1];
|
||||
*dst++ = table[color][2];
|
||||
*dst++ = table[color][3];
|
||||
}
|
||||
src += line_increase;
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -917,7 +932,7 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
|
||||
Note2: when using color-keying + alpha, are the alpha bits part of the
|
||||
color-space or not ?
|
||||
*/
|
||||
DWORD i;
|
||||
int x, y;
|
||||
WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
|
||||
|
||||
if (*temp_buffer == NULL)
|
||||
@ -925,19 +940,22 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
|
||||
current_tex_width * current_tex_height * sizeof(WORD));
|
||||
dst = (WORD *) *temp_buffer;
|
||||
|
||||
for (i = 0; i < height * width; i++) {
|
||||
WORD color = *src++;
|
||||
*dst = ((color & 0xFFC0) | ((color & 0x1F) << 1));
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= 0x0001;
|
||||
dst++;
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
WORD color = *src++;
|
||||
*dst = ((color & 0xFFC0) | ((color & 0x1F) << 1));
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= 0x0001;
|
||||
dst++;
|
||||
}
|
||||
src += line_increase;
|
||||
}
|
||||
} break;
|
||||
|
||||
case CONVERT_CK_5551: {
|
||||
/* Change the alpha value of the color-keyed pixels to emulate color-keying. */
|
||||
DWORD i;
|
||||
int x, y;
|
||||
WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
|
||||
|
||||
if (*temp_buffer == NULL)
|
||||
@ -945,19 +963,22 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
|
||||
current_tex_width * current_tex_height * sizeof(WORD));
|
||||
dst = (WORD *) *temp_buffer;
|
||||
|
||||
for (i = 0; i < height * width; i++) {
|
||||
WORD color = *src++;
|
||||
*dst = color & 0xFFFE;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= color & 0x0001;
|
||||
dst++;
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
WORD color = *src++;
|
||||
*dst = color & 0xFFFE;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= color & 0x0001;
|
||||
dst++;
|
||||
}
|
||||
src += line_increase;
|
||||
}
|
||||
} break;
|
||||
|
||||
case CONVERT_CK_4444: {
|
||||
/* Change the alpha value of the color-keyed pixels to emulate color-keying. */
|
||||
DWORD i;
|
||||
int x, y;
|
||||
WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
|
||||
|
||||
if (*temp_buffer == NULL)
|
||||
@ -965,19 +986,22 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
|
||||
current_tex_width * current_tex_height * sizeof(WORD));
|
||||
dst = (WORD *) *temp_buffer;
|
||||
|
||||
for (i = 0; i < height * width; i++) {
|
||||
WORD color = *src++;
|
||||
*dst = color & 0xFFF0;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= color & 0x000F;
|
||||
dst++;
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
WORD color = *src++;
|
||||
*dst = color & 0xFFF0;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= color & 0x000F;
|
||||
dst++;
|
||||
}
|
||||
src += line_increase;
|
||||
}
|
||||
} break;
|
||||
|
||||
case CONVERT_CK_4444_ARGB: {
|
||||
/* Move the four Alpha bits... */
|
||||
DWORD i;
|
||||
int x, y;
|
||||
WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
|
||||
|
||||
if (*temp_buffer == NULL)
|
||||
@ -985,18 +1009,21 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
|
||||
current_tex_width * current_tex_height * sizeof(WORD));
|
||||
dst = (WORD *) *temp_buffer;
|
||||
|
||||
for (i = 0; i < height * width; i++) {
|
||||
WORD color = *src++;
|
||||
*dst = (color & 0x0FFF) << 4;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= (color & 0xF000) >> 12;
|
||||
dst++;
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
WORD color = *src++;
|
||||
*dst = (color & 0x0FFF) << 4;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= (color & 0xF000) >> 12;
|
||||
dst++;
|
||||
}
|
||||
src += line_increase;
|
||||
}
|
||||
} break;
|
||||
|
||||
case CONVERT_CK_1555: {
|
||||
DWORD i;
|
||||
int x, y;
|
||||
WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
|
||||
|
||||
if (*temp_buffer == NULL)
|
||||
@ -1004,19 +1031,22 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
|
||||
current_tex_width * current_tex_height * sizeof(WORD));
|
||||
dst = (WORD *) *temp_buffer;
|
||||
|
||||
for (i = 0; i < height * width; i++) {
|
||||
WORD color = *src++;
|
||||
*dst = (color & 0x7FFF) << 1;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= (color & 0x8000) >> 15;
|
||||
dst++;
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
WORD color = *src++;
|
||||
*dst = (color & 0x7FFF) << 1;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= (color & 0x8000) >> 15;
|
||||
dst++;
|
||||
}
|
||||
src += line_increase;
|
||||
}
|
||||
} break;
|
||||
|
||||
case CONVERT_555: {
|
||||
/* Converting the 0555 format in 5551 packed */
|
||||
DWORD i;
|
||||
int x, y;
|
||||
WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
|
||||
|
||||
if (*temp_buffer == NULL)
|
||||
@ -1025,18 +1055,24 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
|
||||
dst = (WORD *) *temp_buffer;
|
||||
|
||||
if (src_d->dwFlags & DDSD_CKSRCBLT) {
|
||||
for (i = 0; i < height * width; i++) {
|
||||
WORD color = *src++;
|
||||
*dst = (color & 0x7FFF) << 1;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= 0x0001;
|
||||
dst++;
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
WORD color = *src++;
|
||||
*dst = (color & 0x7FFF) << 1;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= 0x0001;
|
||||
dst++;
|
||||
}
|
||||
src += line_increase;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < height * width; i++) {
|
||||
WORD color = *src++;
|
||||
*dst++ = ((color & 0x7FFF) << 1) | 0x0001;
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
WORD color = *src++;
|
||||
*dst++ = ((color & 0x7FFF) << 1) | 0x0001;
|
||||
}
|
||||
src += line_increase;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1044,7 +1080,7 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
|
||||
|
||||
case CONVERT_CK_RGB24: {
|
||||
/* This is a pain :-) */
|
||||
DWORD i;
|
||||
int x, y;
|
||||
BYTE *src = (BYTE *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top));
|
||||
DWORD *dst;
|
||||
|
||||
@ -1053,20 +1089,23 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
|
||||
current_tex_width * current_tex_height * sizeof(DWORD));
|
||||
dst = (DWORD *) *temp_buffer;
|
||||
|
||||
for (i = 0; i < height * width; i++) {
|
||||
DWORD color = *((DWORD *) src) & 0x00FFFFFF;
|
||||
src += 3;
|
||||
*dst = *src++ << 8;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= 0xFF;
|
||||
dst++;
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
DWORD color = *((DWORD *) src) & 0x00FFFFFF;
|
||||
src += 3;
|
||||
*dst = *src++ << 8;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= 0xFF;
|
||||
dst++;
|
||||
}
|
||||
src += 3 * line_increase;
|
||||
}
|
||||
} break;
|
||||
|
||||
case CONVERT_CK_8888: {
|
||||
/* Just use the alpha component to handle color-keying... */
|
||||
DWORD i;
|
||||
int x, y;
|
||||
DWORD *src = (DWORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
|
||||
|
||||
if (*temp_buffer == NULL)
|
||||
@ -1074,18 +1113,21 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
|
||||
current_tex_width * current_tex_height * sizeof(DWORD));
|
||||
dst = (DWORD *) *temp_buffer;
|
||||
|
||||
for (i = 0; i < height * width; i++) {
|
||||
DWORD color = *src++;
|
||||
*dst = color & 0xFFFFFF00;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= color & 0x000000FF;
|
||||
dst++;
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
DWORD color = *src++;
|
||||
*dst = color & 0xFFFFFF00;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= color & 0x000000FF;
|
||||
dst++;
|
||||
}
|
||||
src += line_increase;
|
||||
}
|
||||
} break;
|
||||
|
||||
case CONVERT_CK_8888_ARGB: {
|
||||
DWORD i;
|
||||
int x, y;
|
||||
DWORD *src = (DWORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
|
||||
|
||||
if (*temp_buffer == NULL)
|
||||
@ -1093,19 +1135,22 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
|
||||
current_tex_width * current_tex_height * sizeof(DWORD));
|
||||
dst = (DWORD *) *temp_buffer;
|
||||
|
||||
for (i = 0; i < height * width; i++) {
|
||||
DWORD color = *src++;
|
||||
*dst = (color & 0x00FFFFFF) << 8;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= (color & 0xFF000000) >> 24;
|
||||
dst++;
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
DWORD color = *src++;
|
||||
*dst = (color & 0x00FFFFFF) << 8;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= (color & 0xFF000000) >> 24;
|
||||
dst++;
|
||||
}
|
||||
src += line_increase;
|
||||
}
|
||||
} break;
|
||||
|
||||
case CONVERT_RGB32_888: {
|
||||
/* Just add an alpha component and handle color-keying... */
|
||||
DWORD i;
|
||||
int x, y;
|
||||
DWORD *src = (DWORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
|
||||
|
||||
if (*temp_buffer == NULL)
|
||||
@ -1114,29 +1159,39 @@ HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, v
|
||||
dst = (DWORD *) *temp_buffer;
|
||||
|
||||
if (src_d->dwFlags & DDSD_CKSRCBLT) {
|
||||
for (i = 0; i < height * width; i++) {
|
||||
DWORD color = *src++;
|
||||
*dst = color << 8;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= 0xFF;
|
||||
dst++;
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
DWORD color = *src++;
|
||||
*dst = color << 8;
|
||||
if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
|
||||
(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
|
||||
*dst |= 0xFF;
|
||||
dst++;
|
||||
}
|
||||
src += line_increase;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < height * width; i++) {
|
||||
*dst++ = (*src++ << 8) | 0xFF;
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
*dst++ = (*src++ << 8) | 0xFF;
|
||||
}
|
||||
src += line_increase;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case NO_CONVERSION:
|
||||
/* Nothing to do here as the name suggests... This just prevents a compiler warning */
|
||||
/* Nothing to do here as the name suggests... Just set-up the buffer correctly */
|
||||
surf_buffer = (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top));
|
||||
break;
|
||||
}
|
||||
|
||||
if (convert_type != NO_CONVERSION) {
|
||||
surf_buffer = *temp_buffer;
|
||||
if (width != current_tex_width) {
|
||||
/* Overide the default PixelStore parameter if only using part of the actual texture */
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
|
||||
}
|
||||
}
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D,
|
||||
|
@ -100,6 +100,11 @@ typedef enum {
|
||||
GL_TRANSFORM_VERTEXBUFFER
|
||||
} GL_TRANSFORM_STATE;
|
||||
|
||||
typedef enum {
|
||||
WINE_GL_BUFFER_BACK = 0,
|
||||
WINE_GL_BUFFER_FRONT
|
||||
} WINE_GL_BUFFER_TYPE;
|
||||
|
||||
typedef struct IDirect3DDeviceGLImpl
|
||||
{
|
||||
struct IDirect3DDeviceImpl parent;
|
||||
@ -124,9 +129,13 @@ typedef struct IDirect3DDeviceGLImpl
|
||||
GLuint unlock_tex;
|
||||
void *surface_ptr;
|
||||
GLenum current_internal_format;
|
||||
|
||||
SURFACE_STATE state, front_state;
|
||||
IDirectDrawSurfaceImpl *lock_surf, *front_lock_surf;
|
||||
|
||||
/* 0 is back-buffer, 1 is front-buffer */
|
||||
SURFACE_STATE state[2];
|
||||
IDirectDrawSurfaceImpl *lock_surf[2];
|
||||
RECT lock_rect[2];
|
||||
/* This is just here to print-out a nice warning if we have two successive locks */
|
||||
BOOLEAN lock_rect_valid[2];
|
||||
} IDirect3DDeviceGLImpl;
|
||||
|
||||
/* This is for the OpenGL additions... */
|
||||
|
Loading…
Reference in New Issue
Block a user