GL doesn't like incorrect lengths passed into DXTN processing.

This commit is contained in:
Jason Edmeades 2003-09-19 00:20:19 +00:00 committed by Alexandre Julliard
parent 6bfd84a331
commit 7ac9d258c3
4 changed files with 88 additions and 57 deletions

View File

@ -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,

View File

@ -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");

View File

@ -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",

View File

@ -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;
}