[dx77] Correct the dxtn processing

Jason Edmeades us at the-edmeades.demon.co.uk
Thu Sep 18 16:25:31 CDT 2003


Changelog

GL doesnt like incorrect lengths passed into DXTN processing. This patch 
should get dxt1 working again, and fixes the regression in Operation 
Flashpoint

Jason
-------------- next part --------------
diff -u3 dlls/d3d8/dx76/device.c dlls/d3d8/device.c
--- dlls/d3d8/dx76/device.c	2003-09-18 22:59:22.000000000 +0100
+++ dlls/d3d8/device.c	2003-09-18 22:52:51.000000000 +0100
@@ -625,7 +625,8 @@
         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 @@
     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 @@
     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 @@
     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 @@
 
         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 @@
  
 
             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 @@
             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 @@
 
     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 @@
 	{
 	  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 @@
       {
 	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 -u3 dlls/d3d8/dx76/directx.c dlls/d3d8/directx.c
--- dlls/d3d8/dx76/directx.c	2003-09-18 21:14:23.000000000 +0100
+++ dlls/d3d8/directx.c	2003-09-18 21:42:21.000000000 +0100
@@ -786,9 +786,11 @@
 	} 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 -u3 dlls/d3d8/dx76/surface.c dlls/d3d8/surface.c
--- dlls/d3d8/dx76/surface.c	2003-09-18 22:59:26.000000000 +0100
+++ dlls/d3d8/surface.c	2003-09-18 22:55:07.000000000 +0100
@@ -153,6 +153,8 @@
     }
 
     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 @@
       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 @@
 
       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 -u3 dlls/d3d8/dx76/utils.c dlls/d3d8/utils.c
--- dlls/d3d8/dx76/utils.c	2003-09-18 22:59:27.000000000 +0100
+++ dlls/d3d8/utils.c	2003-09-18 22:29:48.000000000 +0100
@@ -394,6 +394,11 @@
     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 @@
       }
     }
 #endif
+
     if (retVal == 0) {
         switch (fmt) {
         case D3DFMT_P8:               retVal = GL_COLOR_INDEX8_EXT; break;
@@ -445,22 +451,8 @@
 }
 
 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 @@
       }
     }
 #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 @@
       }
     }
 #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;
 }


More information about the wine-patches mailing list