surface.c revision 4e664340a06cc85b77cd1e6bddcd5b2da558ddd5
2d0611ffc9f91c5fc2ddccb93f9a3d17791ae650takashi * IWineD3DSurface Implementation
d3e250aab242db84d14060985b5db675a731d548nd * Copyright 1998 Lionel Ulmer
c79e39ad568d9af854765f64049534044ef6c034nd * Copyright 2000-2001 TransGaming Technologies Inc.
c79e39ad568d9af854765f64049534044ef6c034nd * Copyright 2002-2005 Jason Edmeades
c79e39ad568d9af854765f64049534044ef6c034nd * Copyright 2002-2003 Raphael Junqueira
c79e39ad568d9af854765f64049534044ef6c034nd * Copyright 2004 Christian Costa
c79e39ad568d9af854765f64049534044ef6c034nd * Copyright 2005 Oliver Stieber
c79e39ad568d9af854765f64049534044ef6c034nd * Copyright 2006-2008 Stefan Dösinger for CodeWeavers
0bd1ddab48139fbbe68f4e257fe669dc19f58fe9rbowen * Copyright 2007-2008 Henri Verbeet
4b575a6b6704b516f22d65a3ad35696d7b9ba372rpluem * Copyright 2006-2008 Roderick Colenbrander
4b575a6b6704b516f22d65a3ad35696d7b9ba372rpluem * Copyright 2009 Henri Verbeet for CodeWeavers
c79e39ad568d9af854765f64049534044ef6c034nd * This library is free software; you can redistribute it and/or
#include "config.h"
#include "wined3d_private.h"
ENTER_GL();
LEAVE_GL();
UINT surface_calculate_size(const struct wined3d_format_desc *format_desc, UINT alignment, UINT width, UINT height)
size = 0;
return size;
struct blt_info
struct float_rect
static void surface_get_blt_info(GLenum target, const RECT *rect_in, GLsizei w, GLsizei h, struct blt_info *info)
struct float_rect f;
if (rect_in)
switch (target)
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE_ARB:
if (rect_in)
void draw_textured_quad(IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, const RECT *dst_rect, WINED3DTEXTUREFILTERTYPE Filter)
surface_get_blt_info(src_surface->texture_target, src_rect, src_surface->pow2Width, src_surface->pow2Height, &info);
glEnd();
if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)src_surface, &IID_IWineD3DBaseTexture, (void **)&texture)))
UINT width, UINT height, UINT level, BOOL lockable, BOOL discard, WINED3DMULTISAMPLE_TYPE multisample_type,
#ifdef VBOX_WITH_WDDM
, void *pvClientMem
unsigned int resource_size;
if (multisample_quality > 0)
multisample_quality = 0;
switch (surface_type)
case SURFACE_OPENGL:
case SURFACE_GDI:
return WINED3DERR_INVALIDCALL;
#ifdef VBOX_WITH_WDDM
return hr;
#ifdef VBOX_WITH_WDDM
switch (pool)
case WINED3DPOOL_SCRATCH:
if(!lockable)
case WINED3DPOOL_SYSTEMMEM:
if (!lockable)
FIXME("Called with a pool of SYSTEMMEM and a lockable of FALSE, this is acceptable but unexpected.\n");
case WINED3DPOOL_MANAGED:
case WINED3DPOOL_DEFAULT:
if (lockable && !(usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL)))
TRACE("surface %p, memory %p, size %u\n", surface, surface->resource.allocatedMemory, surface->resource.size);
return hr;
#ifdef VBOX_WITH_WDDM
return hr;
Assert(0);
if(srgb)
#ifdef VBOX_WITH_WDDM
* from sampler() in state.c. This means we can't touch anything other than
ENTER_GL();
LEAVE_GL();
return TRUE;
return FALSE;
FIXME("Read back converted textures unsupported, format=%s\n", debug_d3dformat(format_desc->format));
ENTER_GL();
LEAVE_GL();
void *mem;
int src_pitch = 0;
int dst_pitch = 0;
if (format_desc->format == WINED3DFMT_P8_UINT && primary_render_target_is_p8(This->resource.device))
LEAVE_GL();
UINT y;
* rendering. If an app does, the SFLAG_DYNLOCK flag will kick in and the memory copy won't be released,
if (srgb)
if (format_desc->heightscale != 1.0f && format_desc->heightscale != 0.0f) height *= format_desc->heightscale;
ENTER_GL();
LEAVE_GL();
#ifdef VBOX_WITH_WDDM
static void surface_upload_data_rect(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info,
if (srgb)
if (format_desc->heightscale != 1.0f && format_desc->heightscale != 0.0f) height *= format_desc->heightscale;
ENTER_GL();
LEAVE_GL();
static void surface_allocate_surface(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info,
if (srgb)
if (format_desc->heightscale != 1.0f && format_desc->heightscale != 0.0f) height *= format_desc->heightscale;
TRACE("(%p) : Creating surface (target %#x) level %d, d3d format %s, internal format %#x, width %d, height %d, gl format %#x, gl type=%#x\n",
ENTER_GL();
if(This->Flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION | SFLAG_CONVERTED) || This->resource.allocatedMemory == NULL) {
* allocatedMemory == NULL: Not defined in the extension. Seems to disable client storage effectively
mem = (BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
#ifdef VBOX_WITH_WDDM
if(enable_client_storage) {
LEAVE_GL();
void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height) {
if (!renderbuffer) {
return GL_NONE;
return GL_COLOR_ATTACHMENT0;
return GL_BACK;
return GL_FRONT;
return GL_BACK;
#ifdef VBOX_WITH_WDDM
static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, DWORD flag, const RECT *rect);
IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL /* no partial locking for textures yet */);
if (dirty_rect)
if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture)))
static BOOL surface_convert_color_to_argb(IWineD3DSurfaceImpl *This, DWORD color, DWORD *argb_color)
case WINED3DFMT_P8_UINT:
case WINED3DFMT_B5G6R5_UNORM:
case WINED3DFMT_B8G8R8_UNORM:
ERR("Unhandled conversion from %s to ARGB!\n", debug_d3dformat(This->resource.format_desc->format));
return FALSE;
return TRUE;
if (!ref)
return ref;
if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
/* Make sure the texture is reloaded because of the palette change, this kills performance though :( */
ENTER_GL();
LEAVE_GL();
This->resource.heapMemory = HeapAlloc(GetProcessHeap() ,0 , This->resource.size + RESOURCE_ALIGNMENT);
(BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
ENTER_GL();
GL_EXTCALL(glGetBufferSubDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0, This->resource.size, This->resource.allocatedMemory));
LEAVE_GL();
This->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size + RESOURCE_ALIGNMENT);
return FALSE;
(BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
return TRUE;
ENTER_GL();
LEAVE_GL();
if(!texture) {
ENTER_GL();
LEAVE_GL();
static void read_from_framebuffer(IWineD3DSurfaceImpl *This, const RECT *rect, void *dest, UINT pitch)
if(!warned) {
* Certain graphics drivers seem to dislike some enabled states when reading from opengl, the blitting usage
* should help here. Furthermore unlockrect will need the context set up for blitting. The context manager will find
ENTER_GL();
if(!rect) {
case WINED3DFMT_P8_UINT:
if(!mem) {
LEAVE_GL();
glReadPixels(local_rect.left, (!srcIsUpsideDown) ? (This->currentDesc.Height - local_rect.bottom) : local_rect.top ,
if(!srcIsUpsideDown) {
if(!srcIsUpsideDown) {
if(!row) {
LEAVE_GL();
LEAVE_GL();
/* For P8 textures we need to perform an inverse palette lookup. This is done by searching for a palette
* index which matches the RGB value. Note this isn't guaranteed to work when there are multiple entries for
* In case of P8 render targets, the index is stored in the alpha component so no conversion is needed.
if (This->resource.format_desc->format == WINED3DFMT_P8_UINT && !primary_render_target_is_p8(myDevice))
/* Activate the surface to read from. In some situations it isn't the currently active target(e.g. backbuffer
* locking during offscreen rendering). RESOURCELOAD is ok because glCopyTexSubImage2D isn't affected by any
ENTER_GL();
LEAVE_GL();
ENTER_GL();
LEAVE_GL();
ENTER_GL();
LEAVE_GL();
ENTER_GL();
LEAVE_GL();
void surface_prepare_texture(IWineD3DSurfaceImpl *surface, const struct wined3d_gl_info *gl_info, BOOL srgb)
/* Performance optimization: Count how often a surface is locked, if it is locked regularly do not throw away the system memory copy.
* This avoids the need to download the surface from opengl all the time. The surface is still downloaded if the opengl texture is
/* MAXLOCKCOUNT is defined in wined3d_private.h */
ENTER_GL();
GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->resource.size + 4, This->resource.allocatedMemory, GL_STREAM_DRAW_ARB));
LEAVE_GL();
This->resource.heapMemory = HeapAlloc(GetProcessHeap() ,0 , This->resource.size + RESOURCE_ALIGNMENT);
(BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
return WINED3DERR_INVALIDCALL;
goto lock_end;
goto lock_end;
ENTER_GL();
This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_WRITE_ARB));
LEAVE_GL();
if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&pBaseTexture))) {
static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fmt, GLenum type, UINT bpp, const BYTE *mem) {
ENTER_GL();
/* When the surface is locked we only have to refresh the locked part else we need to update the whole image */
LEAVE_GL();
return WINEDDERR_NOTLOCKED;
ENTER_GL();
LEAVE_GL();
goto unlock_end;
if ((This->Flags & SFLAG_SWAPCHAIN) || (myDevice->render_targets && iface == myDevice->render_targets[0]))
if(!warned) {
ERR("The application tries to write to the render target, but render target locking is disabled\n");
goto unlock_end;
case RTL_READTEX:
IWineD3DSurface_LoadLocation(iface, SFLAG_INTEXTURE, NULL /* partial texture loading not supported yet */);
case RTL_READDRAW:
if(!fullsurface) {
/* Partial rectangle tracking is not commonly implemented, it is only done for render targets. Overwrite
* the flags to bring them back into a sane state. INSYSMEM was set before to tell LoadLocation where
* to read the rectangle from. Indrawable is set because all modifications from the partial sysmem copy
* are written back to the drawable, thus the surface is merged again in the drawable. The sysmem copy is
return WINED3D_OK;
ENTER_GL();
#ifdef VBOX_WITH_WDDM
LEAVE_GL();
return WINEDDERR_NODC;
return WINEDDERR_DCALREADYCREATED;
return WINED3DERR_INVALIDCALL;
&lock,
NULL,
/* Sync the DIB with the PBO. This can't be done earlier because LockRect activates the allocatedMemory */
return hr;
#ifdef VBOX_WITH_WDDM
swapchain = (IWineD3DSwapChainImpl *)This->resource.device->swapchains[This->resource.device->NumberOfSwapChains-1];
if (pal) {
return WINED3D_OK;
return WINEDDERR_NODC;
return WINEDDERR_NODC;
return WINED3D_OK;
HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, struct wined3d_format_desc *desc, CONVERT_TYPES *convert)
case WINED3DFMT_P8_UINT:
if (!((blit_supported && device->render_targets && This == (IWineD3DSurfaceImpl*)device->render_targets[0]))
if(colorkey_active) {
case WINED3DFMT_B2G3R3_UNORM:
if (colorkey_active) {
case WINED3DFMT_B5G6R5_UNORM:
if (colorkey_active) {
if (colorkey_active) {
case WINED3DFMT_B8G8R8_UNORM:
if (colorkey_active) {
if (colorkey_active) {
return WINED3D_OK;
if (!pal)
/* In DirectDraw the palette is a property of the surface, there are no such things as device palettes. */
if (index_in_alpha)
/* Direct3D >= 8 palette usage style: P8 textures use device palettes, palette entry format is A8R8G8B8,
if (index_in_alpha)
switch (convert) {
case NO_CONVERSION:
case CONVERT_PALETTED:
case CONVERT_PALETTED_CK:
for (y = 0; y < height; y++)
for (x = 0; x < width; x++) {
case CONVERT_CK_565:
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++ ) {
Dest++;
case CONVERT_CK_5551:
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++ ) {
Dest++;
case CONVERT_CK_RGB24:
for (y = 0; y < height; y++)
for (x = 0; x < width; x++) {
case CONVERT_RGB32_888:
for (y = 0; y < height; y++)
for (x = 0; x < width; x++) {
return WINED3D_OK;
return FALSE;
return FALSE;
return TRUE;
/* Make sure the texture is reloaded because of the color key change, this kills performance though :( */
return WINED3D_OK;
return WINED3DERR_INVALIDCALL;
static unsigned int gen = 0;
++gen;
return WINED3D_OK;
if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
ENTER_GL();
if (!*name) {
#ifdef VBOX_WITH_WDDM
#ifdef VBOX_WITH_WDDM
} else if (*name) {
LEAVE_GL();
#include <errno.h>
#include <stdio.h>
static HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, const char* filename)
char *allocatedMemory;
const char *textureRow;
/* check to see if we're a 'virtual' texture, e.g. we're not a pbuffer of texture, we're a back buffer*/
ENTER_GL();
NULL);
LEAVE_GL();
ENTER_GL();
glGetTexImage(GL_TEXTURE_2D, This->texture_level, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, allocatedMemory);
if (tmpTexture) {
LEAVE_GL();
if (NULL == f) {
return WINED3DERR_INVALIDCALL;
/* Save the data out to a TGA file because 1: it's an easy raw format, 2: it supports an alpha channel */
TRACE("(%p) opened %s with format %s\n", This, filename, debug_d3dformat(This->resource.format_desc->format));
fputc(0,f);
fputc(0,f);
fputc(0,f);
fputc(0,f);
fputc(0,f);
fputc(0,f);
fputc(0,f);
fputc(0,f);
fputc(0,f);
fputc(0,f);
fputc(0,f);
/* if the data is upside down if we've fetched it from a back buffer, so it needs flipping again to make it the correct way up */
if(swapChain)
for (y = 0 ; y < height; y++) {
for (i = 0; i < width; i++) {
if(swapChain)
fclose(f);
if(swapChain) {
return WINED3D_OK;
TRACE("(%p) : glFormat %d, glFormatInternal %d, glType %d\n", This, This->resource.format_desc->glFormat,
return hr;
return WINED3DERR_INVALIDCALL;
return WINED3D_OK;
void* tmp;
static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DSurface *override, DWORD Flags) {
return WINEDDERR_NOTFLIPPABLE;
return WINED3D_OK;
if(override) {
if(!swapchain) {
return WINEDDERR_NOTFLIPPABLE;
/* Just overwrite the swapchain presentation interval. This is ok because only ddraw apps can call Flip,
if((Flags & (WINEDDFLIP_NOVSYNC | WINEDDFLIP_INTERVAL2 | WINEDDFLIP_INTERVAL3 | WINEDDFLIP_INTERVAL4)) == 0) {
return hr;
static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface,
/* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
ENTER_GL();
FIXME("Doing a pixel by pixel copy from the framebuffer to a texture, expect major performance issues\n");
if (upsidedown
if (doit)
LEAVE_GL();
static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface,
ENTER_GL();
if(noBackBufferBackup) {
/* Backup the back buffer and copy the source buffer into a texture to draw an upside down stretched quad. If
/* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */
/* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
if (src_offscreen)
fbheight);
IWineD3DSurface_GetContainer((IWineD3DSurface *)SrcSurface, &IID_IWineD3DSwapChain, (void **)&src_swapchain);
/* TODO: Only copy the part that will be read. Use src_rect->left, src_rect->bottom as origin, but with the width watch
fbheight);
if(upsidedown) {
glEnd();
if(backup) {
glVertex2i(0, 0);
glEnd();
if(backup) {
LEAVE_GL();
if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
return WINED3DERR_INVALIDCALL;
IWineD3DSurface_GetContainer( (IWineD3DSurface *) This, &IID_IWineD3DSwapChain, (void **)&dstSwapchain);
if(Src) {
return WINED3DERR_INVALIDCALL;
IWineD3DSurface_GetContainer( (IWineD3DSurface *) Src, &IID_IWineD3DSwapChain, (void **)&srcSwapchain);
SrcSurface != myDevice->render_targets[0] && This != (IWineD3DSurfaceImpl *) myDevice->render_targets[0]) {
return WINED3DERR_INVALIDCALL;
return WINED3DERR_INVALIDCALL;
/* The only case where both surfaces on a swapchain are supported is a back buffer -> front buffer blit on the same swapchain */
((IWineD3DSurface *) This == dstSwapchain->frontBuffer) && SrcSurface == dstSwapchain->backBuffer[0]) {
* This path will only be entered for d3d7 and ddraw apps, because d3d8/9 offer no way to blit TO the front buffer
return WINED3D_OK;
return WINED3DERR_INVALIDCALL;
return WINED3DERR_INVALIDCALL;
return WINED3DERR_INVALIDCALL;
} else if(dstSwapchain) {
return WINED3DERR_INVALIDCALL;
return WINED3DERR_INVALIDCALL;
return WINED3DERR_INVALIDCALL;
* -> If the app wants a image that is scaled on the x axis, and the destination rectangle is smaller
* -> If the app wants a scaled image with a dest rect that is bigger than the fb, it has to be copied
* If EXT_framebuffer_blit is supported that can be used instead. Note that EXT_framebuffer_blit implies
* FBO support, so it doesn't really make sense to try and make it work with different offscreen rendering
return WINED3D_OK;
} else if(Src) {
return WINED3D_OK;
UINT h;
return WINED3DERR_INVALIDCALL;
ENTER_GL();
LEAVE_GL();
#ifdef VBOX_WITH_WDDM
return WINED3D_OK;
return WINED3DERR_INVALIDCALL;
return WINED3DERR_INVALIDCALL;
return WINED3DERR_INVALIDCALL;
float depth;
case WINED3DFMT_D16_UNORM:
case WINED3DFMT_X8D24_UNORM:
case WINED3DFMT_D32_UNORM:
return WINED3DERR_INVALIDCALL;
#ifdef VBOX_WITH_WDDM
return WINED3DERR_INVALIDCALL;
return WINED3DERR_INVALIDCALL;
return WINED3DERR_INVALIDCALL;
return WINED3DERR_INVALIDCALL;
return WINED3DERR_INVALIDCALL;
return WINED3DERR_INVALIDCALL;
return WINED3DERR_INVALIDCALL;
if(!mem) {
return WINED3DERR_OUTOFVIDEOMEMORY;
int outpitch;
if(!mem) {
return WINED3DERR_OUTOFVIDEOMEMORY;
d3dfmt_convert_surface(Src->resource.allocatedMemory, mem, srcPitch, srcWidth, srcHeight, outpitch, convert, Src);
ENTER_GL();
LEAVE_GL();
ENTER_GL();
LEAVE_GL();
IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This, srgb ? SFLAG_INSRGBTEX : SFLAG_INTEXTURE, TRUE);
return WINED3D_OK;
static HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT *DestRect, IWineD3DSurface *SrcSurface,
return WINEDDERR_SURFACEBUSY;
if(iface == myDevice->stencilBufferTarget || (SrcSurface && SrcSurface == myDevice->stencilBufferTarget)) {
TRACE("Attempt to access the depth stencil surface in a BeginScene / EndScene pair, returning WINED3DERR_INVALIDCALL\n");
return WINED3DERR_INVALIDCALL;
} else if(IWineD3DSurfaceImpl_BltZ(This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx) == WINED3D_OK) {
return WINED3D_OK;
if(IWineD3DSurfaceImpl_BltOverride(This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx, Filter) == WINED3D_OK) return WINED3D_OK;
#ifdef VBOX_WITH_WDDM
if (IWineD3DSurfaceImpl_BltSys2Vram(This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx, Filter) == WINED3D_OK) return WINED3D_OK;
return WINEDDERR_SURFACEBUSY;
TRACE("Attempt to access the depth stencil surface in a BeginScene / EndScene pair, returning WINED3DERR_INVALIDCALL\n");
return WINED3DERR_INVALIDCALL;
if(IWineD3DSurfaceImpl_BltOverride(This, &DstRect, Source, &SrcRect, Flags, NULL, WINED3DTEXF_POINT) == WINED3D_OK) return WINED3D_OK;
/* Make sure the texture is up to date. This call doesn't do anything if the texture is already up to date. */
return WINED3D_OK;
#ifdef VBOX_WITH_WDDM
static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, DWORD flag, const RECT *rect);
if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] || gl_info->supported[WINE_NORMALIZED_TEXRECT])
return WINED3DERR_NOTAVAILABLE;
if ((This->pow2Width > gl_info->limits.texture_size || This->pow2Height > gl_info->limits.texture_size)
1: Do the same as we do with nonpow 2 and scale the texture, (any texture ops would require the texture to be scaled which is potentially slow)
4: Create the surface, but allow it to be used only for DirectDraw Blts. Some apps(e.g. Swat 3) create textures with a Height of 16 and a Width > 3000 and blt 16x16 letter areas from them to the render target.
return WINED3DERR_NOTAVAILABLE;
is used in combination with texture uploads (RTL_READTEX/RTL_TEXTEX). The reason is that EXT_PALETTED_TEXTURE
return WINED3D_OK;
glViewport(0, 0, w, h);
glEnd();
glPopAttrib();
void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *context, DWORD location)
ENTER_GL();
LEAVE_GL();
if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
ENTER_GL();
LEAVE_GL();
if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DWORD flag, BOOL persistent) {
if(persistent) {
if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&texture) == WINED3D_OK) {
if((This->Flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) && (flag & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX))) {
if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&texture) == WINED3D_OK) {
#ifdef VBOX_WITH_WDDM
ENTER_GL();
LEAVE_GL();
#ifdef VBOX_WITH_WDDM
static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, DWORD flag, const RECT *rect) {
if(rect) {
return WINED3D_OK;
return WINED3DERR_DEVICELOST;
int byte_count;
d3dfmt_get_conv(This, FALSE /* We need color keying */, FALSE /* We won't use textures */, &desc, &convert);
if(!mem) {
return WINED3DERR_OUTOFVIDEOMEMORY;
d3dfmt_convert_surface(This->resource.allocatedMemory, mem, pitch, width, height, outpitch, convert, This);
if(srgb) {
if(!mem) {
return WINED3DERR_OUTOFVIDEOMEMORY;
if(!mem) {
return WINED3DERR_OUTOFVIDEOMEMORY;
d3dfmt_convert_surface(This->resource.allocatedMemory, mem, pitch, width, height, outpitch, convert, This);
ENTER_GL();
LEAVE_GL();
ENTER_GL();
LEAVE_GL();
#ifdef VBOX_WITH_WDDM
return WINED3D_OK;
static HRESULT WINAPI IWineD3DSurfaceImpl_SetContainer(IWineD3DSurface *iface, IWineD3DBase *container)
if(container) {
if(swapchain) {
return SURFACE_OPENGL;
return WINED3D_OK;
return hr;
static void ffp_blit_p8_upload_palette(IWineD3DSurfaceImpl *surface, const struct wined3d_gl_info *gl_info)
ENTER_GL();
GL_EXTCALL(glColorTableEXT(surface->texture_target, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, table));
LEAVE_GL();
ENTER_GL();
LEAVE_GL();
return WINED3D_OK;
ENTER_GL();
LEAVE_GL();
return FALSE;
return TRUE;
return FALSE;
return FALSE;
return TRUE;
return TRUE;
return FALSE;
static HRESULT ffp_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color)
return WINED3D_OK;
return WINED3D_OK;
return TRUE;
return FALSE;
static HRESULT cpu_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color)
BltFx.u5.dwFillColor = color_convert_argb_to_fmt(fill_color, dst_surface->resource.format_desc->format);
return IWineD3DBaseSurfaceImpl_Blt((IWineD3DSurface*)dst_surface, dst_rect, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT);
return FALSE;
return FALSE;
return FALSE;
if(!((src_format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) || (src_usage & WINED3DUSAGE_RENDERTARGET))
&& ((dst_format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) || (dst_usage & WINED3DUSAGE_RENDERTARGET)))
return FALSE;
return FALSE;
return FALSE;
return TRUE;