WineD3D patch submission

Mirek Slugen( thunder.m at email.cz
Sat Sep 22 05:01:50 CDT 2007


I tried this patch, everything works like before, can't find any 
regression in apps like ET: QW, Oblivion, all nvidia D3D SDK tests, 
3DMarks and others. Titan Quest looks beter, but there are still some 
issues in menu, game is not working because of gdi32.dll functionality. 
I create patch for actual git.

Mirek

Mitchell Wheeler napsal(a):
> Hi all,
>
> A week or so ago I tried to get a game working in WINE (Titan Quest), 
> however it seems it really needs a proper DIB engine before it'll be 
> playable.
>
> Anyways, in my attempt to get it working I fixed up some issues w/ 
> "IWineD3DDeviceImpl_UpdateSurface.c" in dlls/wined3d, not entirely sure 
> how you guys do things around here so I thought i'd just post my changes 
> to the function in this mailing list and you can do with it what you 
> want.  (Note: it actually has a few different methods of doing one 
> thing, enclosed in macro blocks to toggle between them.  Technically the 
> first one should work (i think :\) once you guys properly implement 
> surface locking/unlocking, and it's 'simplest', but the last one is the 
> only one that actually works properly (using standard OpenGL calls).
>
> You'll probably have to clean up the code to meet your coding standards 
> / etc, maybe remove the custom byte size calculation of compressed 
> images, and some other things - but the functionality is there...  i 
> also fixed the existing code that didn't actually do what it was 
> supposed to, heh.
>
> Regards,
> Mitchell Wheeler
>
> static HRESULT  WINAPI  IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice 
> *iface, IWineD3DSurface *pSourceSurface, CONST RECT* pSourceRect, 
> IWineD3DSurface *pDestinationSurface, CONST POINT* pDestPoint) {
>     IWineD3DDeviceImpl  *This         = (IWineD3DDeviceImpl *) iface;
>     /** TODO: remove casts to IWineD3DSurfaceImpl
>      *       NOTE: move code to surface to accomplish this
>       ****************************************/
>     IWineD3DSurfaceImpl *pSrcSurface  = (IWineD3DSurfaceImpl 
> *)pSourceSurface;
>     IWineD3DSurfaceImpl *pDestSurface  = 
> (IWineD3DSurfaceImpl*)pDestinationSurface;
>     int srcWidth, srcHeight;
>     unsigned int  srcSurfaceWidth, srcSurfaceHeight, destSurfaceWidth, 
> destSurfaceHeight;
>     WINED3DFORMAT destFormat, srcFormat;
>     int srcLeft, srcTop, destLeft, destTop;
>     WINED3DPOOL       srcPool, destPool;
>     int offset    = 0;
>     int rowoffset = 0; /* how many bytes to add onto the end of a row to 
> wraparound to the beginning of the next */
>     glDescriptor *glDescription = NULL, *glSrcDescription = NULL;
>     GLenum dummy;
>     int bpp;
>     UINT destByteSize = 0, srcByteSize = 0;
>     int destPixelByteSize = 0, srcPixelByteSize = 0;
>     CONVERT_TYPES convert = NO_CONVERSION;
>
>     WINED3DSURFACE_DESC  winedesc;
>
>     TRACE("(%p) : Source (%p)  Rect (%p) Destination (%p) Point(%p)\n", 
> This, pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint);
>     memset(&winedesc, 0, sizeof(winedesc));
>     winedesc.Width  = &srcSurfaceWidth;
>     winedesc.Height = &srcSurfaceHeight;
>     winedesc.Pool   = &srcPool;
>     winedesc.Format = &srcFormat;
>     winedesc.Size   = &srcByteSize;
>
>     IWineD3DSurface_GetDesc(pSourceSurface, &winedesc);
>
>     winedesc.Width  = &destSurfaceWidth;
>     winedesc.Height = &destSurfaceHeight;
>     winedesc.Pool   = &destPool;
>     winedesc.Format = &destFormat;
>     winedesc.Size   = &destByteSize;
>
>     IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc);
>
>     if(srcPool != WINED3DPOOL_SYSTEMMEM  || destPool != 
> WINED3DPOOL_DEFAULT){
>         WARN("source %p must be SYSTEMMEM and dest %p must be DEFAULT, 
> returning WINED3DERR_INVALIDCALL\n", pSourceSurface, pDestinationSurface);
>         return WINED3DERR_INVALIDCALL;
>     }
>
>     /* This call loads the opengl surface directly, instead of copying 
> the surface to the
>      * destination's sysmem copy. If surface conversion is needed, use 
> BltFast instead to
>      * copy in sysmem and use regular surface loading.
>      */
>     d3dfmt_get_conv((IWineD3DSurfaceImpl *) pDestinationSurface, FALSE, 
> TRUE,
>                     &dummy, &dummy, &dummy, &convert, &bpp, FALSE);
>     if(convert != NO_CONVERSION) {
>         return IWineD3DSurface_BltFast(pDestinationSurface,
>                                         pDestPoint  ? pDestPoint->x : 0,
>                                         pDestPoint  ? pDestPoint->y : 0,
>                                         pSourceSurface, (RECT *) 
> pSourceRect, 0);
>     }
>
>     if (destFormat == WINED3DFMT_UNKNOWN) {
>         TRACE("(%p) : Converting destination surface from 
> WINED3DFMT_UNKNOWN to the source format\n", This);
>         IWineD3DSurface_SetFormat(pDestinationSurface, srcFormat);
>
>         /* Get the update surface description */
>         IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc);
>     }
>
>     ActivateContext(This, This->lastActiveRenderTarget, 
> CTXUSAGE_RESOURCELOAD);
>
>     ENTER_GL();
>
>     if (GL_SUPPORT(ARB_MULTITEXTURE)) {
>         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
>         checkGLcall("glActiveTextureARB");
>     }
>
>     /* Make sure the surface is loaded and up to date */
>     IWineD3DSurface_PreLoad(pDestinationSurface);
>     IWineD3DSurface_GetGlDesc(pDestinationSurface, &glDescription);
>     IWineD3DSurface_GetGlDesc(pDestinationSurface, &glSrcDescription);
>
>     /* this needs to be done in lines if the sourceRect != the 
> sourceWidth */
>     srcWidth    = pSourceRect    ? pSourceRect->right - 
> pSourceRect->left    : srcSurfaceWidth;
>     srcHeight    = pSourceRect    ? pSourceRect->bottom - 
> pSourceRect->top    : srcSurfaceHeight;
>     srcLeft        = pSourceRect    ? pSourceRect->left                
>             : 0;
>     srcTop        = pSourceRect    ? pSourceRect->top                    
>         : 0;
>     destLeft    = pDestPoint    ? pDestPoint->x                        
>         : 0;
>     destTop        = pDestPoint    ? pDestPoint->y                    
>             : 0;
>
>     // Calculate the rowOffset / offset values, for copying
>     #define ISDXTFORMAT(format) \
>         (format == WINED3DFMT_DXT1 || format == WINED3DFMT_DXT2 || 
> format == WINED3DFMT_DXT3 || format == WINED3DFMT_DXT4 || format == 
> WINED3DFMT_DXT5)
>
>     // Calculating this for our selves because I don't have faith in how 
> surface->bytesPerPixel is calculated...
>     destPixelByteSize = destByteSize / (int)(destSurfaceWidth * 
> destSurfaceHeight);
>     srcPixelByteSize = srcByteSize / (int)(srcSurfaceWidth * 
> srcSurfaceHeight);
>
>     if(pSourceRect != NULL)
>     {
>         // Irregular surface formats
>         if (destFormat != srcFormat) {
>             FIXME("Can not convert between surface pixel formats...");
>
>             // Would require some relatively big code restructuring for 
> rare occurances (that shouldn't even be supported?)
>
>             return WINED3DERR_INVALIDCALL;
>         }
>         // Uniform surface formats
>         else
>         {
>             if(srcWidth != srcSurfaceWidth || srcLeft > 0)
>             {
>                 rowoffset = srcSurfaceWidth * srcPixelByteSize;
>                 offset += (srcLeft * srcPixelByteSize);
>             }
>
>             if(srcTop > 0)
>                offset += srcTop * srcSurfaceWidth * srcPixelByteSize;
>         }
>
>     }
>
>     /* Sanity check */
>     if (IWineD3DSurface_GetData(pSourceSurface) == NULL) {
>
>         /* need to lock the surface to get the data */
>         FIXME("Surfaces has no allocated memory, but should be an in 
> memory only surface\n");
>     }
>
>     /* TODO: Cube and volume support */
>     if(rowoffset != 0) {
>         // Compressed texture
>         if (ISDXTFORMAT(destFormat))
>         {
>             if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC))
>             {
> #if 0
>                 RECT rect;
>                 rect.left = destLeft;
>                 rect.top = destTop;
>                 rect.right = destLeft + srcWidth;
>                 rect.bottom = destTop + srcHeight;
>
>                 // Lock source/destination regions
>                 WINED3DLOCKED_RECT destRect, srcRect;
>
>                 printf("Locking surfaces...\n");
>                 if(    
> FAILED(IWineD3DSurface_LockRect(pDestinationSurface, &destRect, &rect, 
> 0)) ||
>                     FAILED(IWineD3DSurface_LockRect(pSourceSurface, 
> &srcRect, pSourceRect, WINED3DLOCK_READONLY)))
>                 {
>                     // How should we handle this case?  Just returning 
> an invalid call for now...
>                     return WINED3DERR_INVALIDCALL;
>                 }
>
>                 printf("Surfaces locked, copying contents now... ");
>                 if(destFormat == WINED3DFMT_DXT1) {
>                     printf("DXT1\n");
>                     //memcpy(destRect.pBits, srcRect.pBits, 
> srcRect.Pitch * (srcHeight / 2));
>                     //memcpy(destRect.pBits, srcRect.pBits, 
> srcRect.Pitch * (srcHeight / 2));
>                     memcpy(destRect.pBits, srcRect.pBits, 
> ceil(srcWidth/4) * ceil(srcHeight/4) * 8);
>                 } else {
>                     printf("DXT2-5\n");
>                     //memcpy(destRect.pBits, srcRect.pBits, 
> srcRect.Pitch * (srcHeight / 4));
>                     memcpy(destRect.pBits, srcRect.pBits, 
> ceil(srcWidth/4) * ceil(srcHeight/4) * 16);
>                 }
>
>                 // Unlock source/destination regions
>                 IWineD3DSurface_UnlockRect(pSourceSurface);
>                 IWineD3DSurface_UnlockRect(pDestinationSurface);
>                 printf("Unlocking surfaces...\n");
> #elif 0
>                 // Get pointers to the source/destination buffers
>                 unsigned char *dest_data = (unsigned 
> char*)IWineD3DSurface_GetData(pDestinationSurface);
>                 const unsigned char *src_data = (unsigned 
> char*)IWineD3DSurface_GetData(pSourceSurface);
>
>                 // Copy subsection of source buffer, in to destination 
> buffer.
>                 unsigned char *dest_ptr = dest_data + offset;
>                 const unsigned char *src_ptr = src_data + offset;
>
>                 size_t i;
>                 for(i = 0; i < srcHeight; ++i) {
>                     memcpy(dest_ptr, src_ptr, srcWidth * srcPixelByteSize);
>
>                     dest_ptr += rowoffset;
>                     src_ptr += rowoffset;
>                 }
>
>
>                 // Upload destination buffer to server
>                 GL_EXTCALL(glCompressedTexImage2DARB(glDescription->target,
>                                                     glDescription->level,
>                                                     
> glDescription->glFormatInternal,
>                                                     srcWidth,
>                                                     srcHeight,
>                                                     0,
>                                                     destByteSize,
>                                                     dest_data));
>
>                 checkGLcall("glCompressedTexImage2DARB");
> #elif 1
>                 int blocksize = 16;
>                 if(destFormat == WINED3DFMT_DXT1)
>                     blocksize = 8;
>
>                 #define max(a, b) (a > b? a : b)
>                 srcHeight = max(srcHeight, 4);
>                 srcWidth = max(srcWidth, 4);
>                 #undef max
>
>                 int data_size = (srcWidth / 4) * (srcHeight / 4) * 
> blocksize;
>                 int row_size = data_size / srcHeight;
>                 int pixel_size = row_size / srcWidth;
>                 int stride = srcSurfaceWidth * pixel_size;
>
>                 unsigned char *temp_buffer = HeapAlloc(GetProcessHeap(), 
> 0, data_size);
>                 unsigned char *temp_ptr = temp_buffer;
>
>                 // Debug info
>                 //printf(" > BytesTotal: %i | BytesPerPixel: %i | 
> RowSize: %i\n", data_size, pixel_size, row_size);
>                 //printf(" > Source: %i -> %i, %i -> %i | Dest: %i, 
> %i\n", srcLeft, srcWidth, srcTop, srcHeight, destLeft, destTop);
>                 //printf(" > Offset: %i\n", (int)((row_size * srcTop) + 
> srcLeft * pixel_size));
>
>                 // Get pointers to the source buffer
>                 const unsigned char *src_data = (unsigned 
> char*)IWineD3DSurface_GetData(pSourceSurface);
>                 src_data += (stride * srcTop) + srcLeft * pixel_size;
>
>                 size_t i;
>                 for(i = 0; i < srcHeight; ++i) {
>                     memcpy(temp_ptr, src_data, row_size);
>                     temp_ptr += row_size;
>                     src_data += stride;
>                 }
>
>                 GL_EXTCALL(glCompressedTexSubImage2DARB(
>                     glDescription->target,
>                     glDescription->level,
>                     destLeft,
>                     destTop,
>                     srcWidth,
>                     srcHeight,
>                     glDescription->glFormatInternal,
>                     data_size,
>                     temp_buffer
>                 ));
>                 //checkGLcall("glCompressedTexSubImage2DARB");
>
>                 HeapFree(GetProcessHeap(), 0, temp_buffer);
> #endif
>             }
>             else
>             {
>                 FIXME("TODO: Need to update a DXT compressed texture 
> without hardware support\n");
>             }
>         }
>         // Uncompressed texture
>         else
>         {
>             /* not a whole row so we have to do it a line at a time */
>             int j;
>
>             /* hopefully using pointer addtion will be quicker than 
> using a point + j * rowoffset */
>             const unsigned char* data =((const unsigned char 
> *)IWineD3DSurface_GetData(pSourceSurface)) + offset;
>
>             for(j = destTop; j < (srcHeight + destTop); ++j)
>             {
>                     glTexSubImage2D(glDescription->target
>                         ,glDescription->level
>                         ,destLeft
>                         ,j
>                         ,srcWidth
>                         ,1
>                         ,glDescription->glFormat
>                         ,glDescription->glType
>                         ,data /* could be quicker using */
>                     );
>                 data += rowoffset;
>             }
>         }
>     } else {
>         // Compressed texture
>         if (ISDXTFORMAT(destFormat))
>         {
>             if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC))
>             {
>                 int blocksize = 16;
>                 if(destFormat == WINED3DFMT_DXT1)
>                     blocksize = 8;
>
>                 #define max(a, b) (a > b? a : b)
>                 int data_size = (max(srcWidth, 4) / 4) * (max(srcHeight, 
> 4) / 4) * blocksize;
>                 #undef max
>
>                 //printf(" -> S = %i | CompressedTexImage2D(?, %i, %i, 
> %i, %i, 0, %i, ?)\n", destByteSize, glDescription->level, 
> glDescription->glFormatInternal, srcWidth, srcHeight, data_size);
>                 
> GL_EXTCALL(glCompressedTexSubImage2DARB(glDescription->target,
>                                                     glDescription->level,
>                                                     destLeft,
>                                                     destTop,
>                                                     srcWidth,
>                                                     srcHeight,
>                                                     
> glDescription->glFormatInternal,
>                                                     data_size,
>                                                     
> IWineD3DSurface_GetData(pSourceSurface)));
>
>                 checkGLcall("glCompressedTexImage2DARB");
>             }
>             else
>             {
>                 FIXME("TODO: Need to update a DXT compressed texture 
> without hardware support\n");
>             }
>         }
>         // Uncompressed Texture
>         else
>         {
>             glTexSubImage2D(
>                 glDescription->target,
>                 glDescription->level,
>                 destLeft,
>                 destTop,
>                 srcWidth,
>                 srcHeight,
>                 glDescription->glFormat,
>                 glDescription->glType,
>                 IWineD3DSurface_GetData(pSourceSurface)
>             );
>
>             checkGLcall("glTexSubImage2D");
>         }
>      }
>
>     LEAVE_GL();
>
>     ((IWineD3DSurfaceImpl *)pDestinationSurface)->Flags &= ~SFLAG_INSYSMEM;
>     ((IWineD3DSurfaceImpl *)pDestinationSurface)->Flags |= SFLAG_INTEXTURE;
>     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(0));
>
>     return WINED3D_OK;
> }
>
>
>
>   
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch.diff
Type: text/x-patch
Size: 17700 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-devel/attachments/20070922/bbdac283/attachment-0001.bin 


More information about the wine-devel mailing list