From 7ac9d258c3be17b480bedff8f36ef0e7e3f97ff6 Mon Sep 17 00:00:00 2001 From: Jason Edmeades Date: Fri, 19 Sep 2003 00:20:19 +0000 Subject: [PATCH] GL doesn't like incorrect lengths passed into DXTN processing. --- dlls/d3d8/device.c | 58 +++++++++++++++++++---------------- dlls/d3d8/directx.c | 2 ++ dlls/d3d8/surface.c | 11 ++++++- dlls/d3d8/utils.c | 74 +++++++++++++++++++++++++++------------------ 4 files changed, 88 insertions(+), 57 deletions(-) diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 47d2fa0e956..922db5d0669 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -625,7 +625,8 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 ifac volume->myDesc.Pool = Pool; volume->myDesc.Usage = Usage; volume->bytesPerPixel = D3DFmtGetBpp(This, Format); - volume->myDesc.Size = (Width * volume->bytesPerPixel) * Height * Depth; + /* Note: Volume textures cannot be dxtn, hence no need to check here */ + volume->myDesc.Size = (Width * volume->bytesPerPixel) * Height * Depth; volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size); volume->lockable = TRUE; @@ -779,7 +780,11 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface object->myDesc.Pool = D3DPOOL_DEFAULT; object->myDesc.MultiSampleType = MultiSample; object->bytesPerPixel = D3DFmtGetBpp(This, Format); - object->myDesc.Size = (Width * object->bytesPerPixel) * Height; + if (Format == D3DFMT_DXT1) { + object->myDesc.Size = (Width * object->bytesPerPixel)/2 * Height; /* DXT1 is half byte per pixel */ + } else { + object->myDesc.Size = (Width * object->bytesPerPixel) * Height; + } object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size); object->lockable = Lockable; object->locked = FALSE; @@ -814,7 +819,11 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE object->myDesc.Pool = D3DPOOL_DEFAULT; object->myDesc.MultiSampleType = MultiSample; object->bytesPerPixel = D3DFmtGetBpp(This, Format); - object->myDesc.Size = (Width * object->bytesPerPixel) * Height; + if (Format == D3DFMT_DXT1) { + object->myDesc.Size = (Width * object->bytesPerPixel)/2 * Height; /* DXT1 is half byte per pixel */ + } else { + object->myDesc.Size = (Width * object->bytesPerPixel) * Height; + } object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size); object->lockable = (D3DFMT_D16_LOCKABLE == Format) ? TRUE : FALSE; object->locked = FALSE; @@ -844,7 +853,11 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface object->myDesc.Usage = 0; object->myDesc.Pool = D3DPOOL_SYSTEMMEM; object->bytesPerPixel = D3DFmtGetBpp(This, Format); - object->myDesc.Size = (Width * object->bytesPerPixel) * Height; + if (Format == D3DFMT_DXT1) { + object->myDesc.Size = ((Width * object->bytesPerPixel) * Height) / 2; /* DXT1 is half byte per pixel */ + } else { + object->myDesc.Size = (Width * object->bytesPerPixel) * Height; + } object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size); object->lockable = TRUE; object->locked = FALSE; @@ -921,11 +934,12 @@ HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, int bytesPerPixel = ((IDirect3DSurface8Impl*) pSourceSurface)->bytesPerPixel; int i; + /* Copy rect by rect */ for (i = 0; i < cRects; i++) { CONST RECT* r = &pSourceRectsArray[i]; CONST POINT* p = &pDestPointsArray[i]; - int copyperline = (r->right - r->left) * bytesPerPixel; + int copyperline; int j; D3DLOCKED_RECT lrSrc; D3DLOCKED_RECT lrDst; @@ -933,7 +947,11 @@ HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, TRACE("Copying rect %d (%ld,%ld),(%ld,%ld) -> (%ld,%ld)\n", i, r->left, r->top, r->right, r->bottom, p->x, p->y); - + if (src->myDesc.Format == D3DFMT_DXT1) { + copyperline = ((r->right - r->left) * bytesPerPixel)/2; /* DXT1 is half byte per pixel */ + } else { + copyperline = ((r->right - r->left) * bytesPerPixel); + } IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) src, &lrSrc, r, D3DLOCK_READONLY); dest_rect.left = p->x; dest_rect.top = p->y; @@ -943,15 +961,6 @@ HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, TRACE("Locked src and dst\n"); /* Find where to start */ -#if 0 - from = copyfrom + (r->top * pitchFrom) + (r->left * bytesPerPixel); - to = copyto + (p->y * pitchTo) + (p->x * bytesPerPixel); - /* Copy line by line */ - for (j = 0; j < (r->bottom - r->top); j++) { - memcpy(to + (j * pitchTo), from + (j * pitchFrom), copyperline); - } -#endif - for (j = 0; j < (r->bottom - r->top); j++) { memcpy((char*) lrDst.pBits + (j * lrDst.Pitch), (char*) lrSrc.pBits + (j * lrSrc.Pitch), copyperline); } @@ -1074,17 +1083,6 @@ HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, ID ENTER_GL(); - /* - { - IDirect3DSurface8Impl* tmp = ((IDirect3DSurface8Impl*) pDestSurface); - FIXME("dest:%u,%u,bpp:%u\n", tmp->myDesc.Width, tmp->myDesc.Height, tmp->bytesPerPixel); - FIXME("dest2:pitch%u\n", lockedRect.Pitch); - FIXME("src:%u,%u\n", This->PresentParms.BackBufferWidth, This->PresentParms.BackBufferHeight); - tmp = This->frontBuffer; - FIXME("src2:%u,%u,bpp:%u\n", tmp->myDesc.Width, tmp->myDesc.Height, tmp->bytesPerPixel); - } - */ - glFlush(); vcheckGLcall("glFlush"); glGetIntegerv(GL_READ_BUFFER, &prev_read); @@ -1206,6 +1204,10 @@ HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) { { long j; long pitch = This->renderTarget->myDesc.Width * This->renderTarget->bytesPerPixel; + + if (This->renderTarget->myDesc.Format == D3DFMT_DXT1) /* DXT1 is half byte per pixel */ + pitch = pitch / 2; + for (j = 0; j < This->renderTarget->myDesc.Height; ++j) { glReadPixels(0, This->renderTarget->myDesc.Height - j - 1, @@ -4025,6 +4027,10 @@ HRESULT WINAPI IDirect3DDevice8Impl_ActiveRender(LPDIRECT3DDEVICE8 iface, { long j; long pitch = This->renderTarget->myDesc.Width * This->renderTarget->bytesPerPixel; + + if (This->renderTarget->myDesc.Format == D3DFMT_DXT1) /* DXT1 is half byte per pixel */ + pitch = pitch / 2; + for (j = 0; j < This->renderTarget->myDesc.Height; ++j) { glReadPixels(0, This->renderTarget->myDesc.Height - j - 1, diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c index d6434c269d1..47667f35a25 100644 --- a/dlls/d3d8/directx.c +++ b/dlls/d3d8/directx.c @@ -786,9 +786,11 @@ static void IDirect3D8Impl_FillGLCaps(LPDIRECT3D8 iface, Display* display) { } else if (strcmp(ThisExtn, "GL_EXT_secondary_color") == 0) { FIXME(" FOUND: EXT Secondary coord support\n"); This->gl_info.supported[EXT_SECONDARY_COLOR] = TRUE; +#if defined(GL_EXT_texture_compression_s3tc) } else if (strcmp(ThisExtn, "GL_EXT_texture_compression_s3tc") == 0) { FIXME(" FOUND: EXT Texture S3TC compression support\n"); This->gl_info.supported[EXT_TEXTURE_COMPRESSION_S3TC] = TRUE; +#endif } else if (strcmp(ThisExtn, "GL_EXT_texture_env_dot3") == 0) { if (FALSE == This->gl_info.supported[ARB_TEXTURE_ENV_DOT3]) { FIXME(" FOUND: EXT Dot3 support\n"); diff --git a/dlls/d3d8/surface.c b/dlls/d3d8/surface.c index cb7e38ac37c..527f60940b6 100644 --- a/dlls/d3d8/surface.c +++ b/dlls/d3d8/surface.c @@ -153,6 +153,8 @@ HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKE } pLockedRect->Pitch = This->bytesPerPixel * This->myDesc.Width; /* Bytes / row */ + if (This->myDesc.Format == D3DFMT_DXT1) /* DXT1 is half byte per pixel */ + pLockedRect->Pitch = pLockedRect->Pitch/2; if (NULL == pRect) { pLockedRect->pBits = This->allocatedMemory; @@ -163,7 +165,12 @@ HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKE TRACE("Locked Rect (%p) = l %ld, t %ld, r %ld, b %ld\n", &This->lockedRect, This->lockedRect.left, This->lockedRect.top, This->lockedRect.right, This->lockedRect.bottom); } else { TRACE("Lock Rect (%p) = l %ld, t %ld, r %ld, b %ld\n", pRect, pRect->left, pRect->top, pRect->right, pRect->bottom); - pLockedRect->pBits = This->allocatedMemory + (pLockedRect->Pitch * pRect->top) + (pRect->left * This->bytesPerPixel); + + if (This->myDesc.Format == D3DFMT_DXT1) { /* DXT1 is half byte per pixel */ + pLockedRect->pBits = This->allocatedMemory + (pLockedRect->Pitch * pRect->top) + ((pRect->left * This->bytesPerPixel/2)); + } else { + pLockedRect->pBits = This->allocatedMemory + (pLockedRect->Pitch * pRect->top) + (pRect->left * This->bytesPerPixel); + } This->lockedRect.left = pRect->left; This->lockedRect.top = pRect->top; This->lockedRect.right = pRect->right; @@ -491,6 +498,8 @@ HRESULT WINAPI IDirect3DSurface8Impl_LoadTexture(LPDIRECT3DSURFACE8 iface, GLenu LEAVE_GL(); } +#else + FIXME("Using DXT1/3/5 without advertized support\n"); #endif } else { TRACE("Calling glTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%x, Mem=%p\n", diff --git a/dlls/d3d8/utils.c b/dlls/d3d8/utils.c index 723aac9a4e3..f63d9889cda 100644 --- a/dlls/d3d8/utils.c +++ b/dlls/d3d8/utils.c @@ -394,6 +394,11 @@ SHORT D3DFmtGetBpp(IDirect3DDevice8Impl* This, D3DFORMAT fmt) { case D3DFMT_D24S8: retVal = 4; break; case D3DFMT_D24X8: retVal = 4; break; case D3DFMT_D32: retVal = 4; break; + /* Compressed */ + case D3DFMT_DXT1: retVal = 1; break; /* Actually 8 bytes per 16 pixels - Special cased later */ + case D3DFMT_DXT3: retVal = 1; break; /* Actually 16 bytes per 16 pixels */ + case D3DFMT_DXT5: retVal = 1; break; /* Actually 16 bytes per 16 pixels */ + /* unknown */ case D3DFMT_UNKNOWN: /* Guess at the highest value of the above */ @@ -424,6 +429,7 @@ GLint D3DFmt2GLIntFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt) { } } #endif + if (retVal == 0) { switch (fmt) { case D3DFMT_P8: retVal = GL_COLOR_INDEX8_EXT; break; @@ -445,22 +451,8 @@ GLint D3DFmt2GLIntFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt) { } GLenum D3DFmt2GLFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt) { - GLenum retVal; + GLenum retVal = 0; - switch (fmt) { - case D3DFMT_P8: retVal = GL_COLOR_INDEX; break; - case D3DFMT_A8P8: retVal = GL_COLOR_INDEX; break; - - case D3DFMT_A4R4G4B4: retVal = GL_BGRA; break; - case D3DFMT_A8R8G8B8: retVal = GL_BGRA; break; - case D3DFMT_X8R8G8B8: retVal = GL_BGRA; break; - case D3DFMT_R8G8B8: retVal = GL_BGR; break; - case D3DFMT_R5G6B5: retVal = GL_RGB; break; - case D3DFMT_A1R5G5B5: retVal = GL_BGRA; break; - default: - FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt)); - retVal = GL_BGR; - } #if defined(GL_EXT_texture_compression_s3tc) if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) { switch (fmt) { @@ -473,27 +465,31 @@ GLenum D3DFmt2GLFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt) { } } #endif + + if (retVal == 0) { + switch (fmt) { + case D3DFMT_P8: retVal = GL_COLOR_INDEX; break; + case D3DFMT_A8P8: retVal = GL_COLOR_INDEX; break; + + case D3DFMT_A4R4G4B4: retVal = GL_BGRA; break; + case D3DFMT_A8R8G8B8: retVal = GL_BGRA; break; + case D3DFMT_X8R8G8B8: retVal = GL_BGRA; break; + case D3DFMT_R8G8B8: retVal = GL_BGR; break; + case D3DFMT_R5G6B5: retVal = GL_RGB; break; + case D3DFMT_A1R5G5B5: retVal = GL_BGRA; break; + default: + FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt)); + retVal = GL_BGR; + } + } + TRACE("fmt2glFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal); return retVal; } GLenum D3DFmt2GLType(IDirect3DDevice8Impl* This, D3DFORMAT fmt) { - GLenum retVal; + GLenum retVal = 0; - switch (fmt) { - case D3DFMT_P8: retVal = GL_UNSIGNED_BYTE; break; - case D3DFMT_A8P8: retVal = GL_UNSIGNED_BYTE; break; - - case D3DFMT_A4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break; - case D3DFMT_A8R8G8B8: retVal = GL_UNSIGNED_BYTE; break; - case D3DFMT_X8R8G8B8: retVal = GL_UNSIGNED_BYTE; break; - case D3DFMT_R5G6B5: retVal = GL_UNSIGNED_SHORT_5_6_5; break; - case D3DFMT_R8G8B8: retVal = GL_UNSIGNED_BYTE; break; - case D3DFMT_A1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break; - default: - FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt)); - retVal = GL_UNSIGNED_BYTE; - } #if defined(GL_EXT_texture_compression_s3tc) if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) { switch (fmt) { @@ -506,6 +502,24 @@ GLenum D3DFmt2GLType(IDirect3DDevice8Impl* This, D3DFORMAT fmt) { } } #endif + + if (retVal == 0) { + switch (fmt) { + case D3DFMT_P8: retVal = GL_UNSIGNED_BYTE; break; + case D3DFMT_A8P8: retVal = GL_UNSIGNED_BYTE; break; + + case D3DFMT_A4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break; + case D3DFMT_A8R8G8B8: retVal = GL_UNSIGNED_BYTE; break; + case D3DFMT_X8R8G8B8: retVal = GL_UNSIGNED_BYTE; break; + case D3DFMT_R5G6B5: retVal = GL_UNSIGNED_SHORT_5_6_5; break; + case D3DFMT_R8G8B8: retVal = GL_UNSIGNED_BYTE; break; + case D3DFMT_A1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break; + default: + FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt)); + retVal = GL_UNSIGNED_BYTE; + } + } + TRACE("fmt2glType for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal); return retVal; }