wined3d: Introduce surface_init() to handle most of the surface initialization.
Henri Verbeet
hverbeet at codeweavers.com
Mon Jun 15 02:06:49 CDT 2009
---
dlls/wined3d/device.c | 135 +++----------------------------------
dlls/wined3d/surface.c | 145 +++++++++++++++++++++++++++++++++++++++-
dlls/wined3d/surface_gdi.c | 2 +-
dlls/wined3d/wined3d_private.h | 6 ++
4 files changed, 160 insertions(+), 128 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index df55962..93075ae 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -895,156 +895,39 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, UI
WINED3DSURFTYPE Impl, IUnknown *parent)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- IWineD3DSurfaceImpl *object; /*NOTE: impl ref allowed since this is a create function */
- unsigned int Size = 1;
- const struct GlPixelFormatDesc *glDesc = getFormatDescEntry(Format, &GLINFO_LOCATION);
+ IWineD3DSurfaceImpl *object;
HRESULT hr;
TRACE("(%p) Create surface\n",This);
- if(MultisampleQuality > 0) {
- FIXME("MultisampleQuality set to %d, substituting 0\n", MultisampleQuality);
- MultisampleQuality=0;
- }
-
- /** FIXME: Check that the format is supported
- * by the device.
- *******************************/
-
- if (WINED3DFMT_UNKNOWN == Format) {
- Size = 0;
- }
- else if (glDesc->Flags & WINED3DFMT_FLAG_COMPRESSED)
- {
- UINT row_block_count = (Width + glDesc->block_width - 1) / glDesc->block_width;
- UINT row_count = (Height + glDesc->block_height - 1) / glDesc->block_height;
- Size = row_count * row_block_count * glDesc->block_byte_count;
- }
- else
+ if (Impl == SURFACE_OPENGL && !This->adapter)
{
- /* The pitch is a multiple of 4 bytes */
- Size = ((Width * glDesc->byte_count) + This->surface_alignment - 1) & ~(This->surface_alignment - 1);
- Size *= Height;
+ ERR("OpenGL surfaces are not available without OpenGL.\n");
+ return WINED3DERR_NOTAVAILABLE;
}
- if(glDesc->heightscale != 0.0) Size *= glDesc->heightscale;
-
- /** Create and initialise the surface resource **/
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
{
- ERR("Out of memory\n");
+ ERR("Failed to allocate surface memory.\n");
*ppSurface = NULL;
return WINED3DERR_OUTOFVIDEOMEMORY;
}
- /* Look at the implementation and set the correct Vtable */
- switch(Impl)
- {
- case SURFACE_OPENGL:
- /* Check if a 3D adapter is available when creating gl surfaces */
- if (!This->adapter)
- {
- ERR("OpenGL surfaces are not available without opengl\n");
- HeapFree(GetProcessHeap(), 0, object);
- return WINED3DERR_NOTAVAILABLE;
- }
- object->lpVtbl = &IWineD3DSurface_Vtbl;
- break;
-
- case SURFACE_GDI:
- object->lpVtbl = &IWineGDISurface_Vtbl;
- break;
-
- default:
- /* To be sure to catch this */
- ERR("Unknown requested surface implementation %d!\n", Impl);
- HeapFree(GetProcessHeap(), 0, object);
- return WINED3DERR_INVALIDCALL;
- }
-
- hr = resource_init((IWineD3DResource *)object, WINED3DRTYPE_SURFACE, This, Size, Usage, glDesc, Pool, parent);
+ hr = surface_init(object, Impl, This->surface_alignment, Width, Height, Level, Lockable,
+ Discard, MultiSample, MultisampleQuality, This, Usage, Format, Pool, parent);
if (FAILED(hr))
{
- WARN("Failed to initialize resource, returning %#x\n", hr);
+ WARN("Failed to initialize surface, returning %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
*ppSurface = NULL;
return hr;
}
- TRACE("(%p) : Created resource %p\n", This, object);
+ TRACE("(%p) : Created surface %p\n", This, object);
*ppSurface = (IWineD3DSurface *)object;
- /* "Standalone" surface */
- IWineD3DSurface_SetContainer((IWineD3DSurface *)object, NULL);
-
- object->currentDesc.Width = Width;
- object->currentDesc.Height = Height;
- object->currentDesc.MultiSampleType = MultiSample;
- object->currentDesc.MultiSampleQuality = MultisampleQuality;
- object->glDescription.level = Level;
- list_init(&object->overlays);
-
- /* Flags */
- object->Flags = SFLAG_NORMCOORD; /* Default to normalized coords */
- object->Flags |= Discard ? SFLAG_DISCARD : 0;
- object->Flags |= (WINED3DFMT_D16_LOCKABLE == Format) ? SFLAG_LOCKABLE : 0;
- object->Flags |= Lockable ? SFLAG_LOCKABLE : 0;
-
- TRACE("Pool %d %d %d %d\n",Pool, WINED3DPOOL_DEFAULT, WINED3DPOOL_MANAGED, WINED3DPOOL_SYSTEMMEM);
-
- /** Quick lockable sanity check TODO: remove this after surfaces, usage and lockability have been debugged properly
- * this function is too deep to need to care about things like this.
- * Levels need to be checked too, and possibly Type since they all affect what can be done.
- * ****************************************/
- switch(Pool) {
- case WINED3DPOOL_SCRATCH:
- if(!Lockable)
- FIXME("Create surface called with a pool of SCRATCH and a Lockable of FALSE "
- "which are mutually exclusive, setting lockable to TRUE\n");
- Lockable = TRUE;
- break;
- case WINED3DPOOL_SYSTEMMEM:
- if(!Lockable) FIXME("Create surface called with a pool of SYSTEMMEM and a Lockable of FALSE, "
- "this is acceptable but unexpected (I can't know how the surface can be usable!)\n");
- case WINED3DPOOL_MANAGED:
- if(Usage == WINED3DUSAGE_DYNAMIC) FIXME("Create surface called with a pool of MANAGED and a "
- "Usage of DYNAMIC which are mutually exclusive, not doing "
- "anything just telling you.\n");
- break;
- case WINED3DPOOL_DEFAULT: /*TODO: Create offscreen plain can cause this check to fail..., find out if it should */
- if(!(Usage & WINED3DUSAGE_DYNAMIC) && !(Usage & WINED3DUSAGE_RENDERTARGET)
- && !(Usage & WINED3DUSAGE_DEPTHSTENCIL ) && Lockable)
- WARN("Creating a surface with a POOL of DEFAULT with Lockable true, that doesn't specify DYNAMIC usage.\n");
- break;
- default:
- FIXME("(%p) Unknown pool %d\n", This, Pool);
- break;
- };
-
- if (Usage & WINED3DUSAGE_RENDERTARGET && Pool != WINED3DPOOL_DEFAULT) {
- FIXME("Trying to create a render target that isn't in the default pool\n");
- }
-
- /* mark the texture as dirty so that it gets loaded first time around*/
- surface_add_dirty_rect(*ppSurface, NULL);
- TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) lockable(%d) surf@%p, surfmem@%p, %d bytes\n",
- This, Width, Height, Format, debug_d3dformat(Format),
- (WINED3DFMT_D16_LOCKABLE == Format), *ppSurface, object->resource.allocatedMemory, object->resource.size);
-
- list_init(&object->renderbuffers);
-
- /* Call the private setup routine */
- hr = IWineD3DSurface_PrivateSetup((IWineD3DSurface *)object);
- if (FAILED(hr))
- {
- ERR("Private setup failed, returning %#x\n", hr);
- IWineD3DSurface_Release(*ppSurface);
- *ppSurface = NULL;
- return hr;
- }
-
return hr;
}
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index a3ecf29..33fc51a 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -32,11 +32,13 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
WINE_DECLARE_DEBUG_CHANNEL(d3d);
-#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
+
+#define GLINFO_LOCATION (*gl_info)
static void surface_cleanup(IWineD3DSurfaceImpl *This)
{
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+ const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
renderbuffer_entry_t *entry, *entry2;
TRACE("(%p) : Cleaning up.\n", This);
@@ -92,6 +94,143 @@ static void surface_cleanup(IWineD3DSurfaceImpl *This)
resource_cleanup((IWineD3DResource *)This);
}
+HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, UINT alignment,
+ UINT width, UINT height, UINT level, BOOL lockable, BOOL discard, WINED3DMULTISAMPLE_TYPE multisample_type,
+ UINT multisample_quality, IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format,
+ WINED3DPOOL pool, IUnknown *parent)
+{
+ const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
+ const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, &GLINFO_LOCATION);
+ void (*cleanup)(IWineD3DSurfaceImpl *This);
+ unsigned int resource_size;
+ HRESULT hr;
+
+ if (multisample_quality > 0)
+ {
+ FIXME("multisample_quality set to %u, substituting 0\n", multisample_quality);
+ multisample_quality = 0;
+ }
+
+ /* FIXME: Check that the format is supported by the device. */
+
+ if (format == WINED3DFMT_UNKNOWN)
+ {
+ resource_size = 0;
+ }
+ else if (format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
+ {
+ UINT row_block_count = (width + format_desc->block_width - 1) / format_desc->block_width;
+ UINT row_count = (height + format_desc->block_height - 1) / format_desc->block_height;
+ resource_size = row_count * row_block_count * format_desc->block_byte_count;
+ }
+ else
+ {
+ /* The pitch is a multiple of 4 bytes. */
+ resource_size = ((width * format_desc->byte_count) + alignment - 1) & ~(alignment - 1);
+ resource_size *= height;
+ }
+
+ if (format_desc->heightscale != 0.0) resource_size *= format_desc->heightscale;
+
+ /* Look at the implementation and set the correct Vtable. */
+ switch (surface_type)
+ {
+ case SURFACE_OPENGL:
+ surface->lpVtbl = &IWineD3DSurface_Vtbl;
+ cleanup = surface_cleanup;
+ break;
+
+ case SURFACE_GDI:
+ surface->lpVtbl = &IWineGDISurface_Vtbl;
+ cleanup = surface_gdi_cleanup;
+ break;
+
+ default:
+ ERR("Requested unknown surface implementation %#x.\n", surface_type);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ hr = resource_init((IWineD3DResource *)surface, WINED3DRTYPE_SURFACE,
+ device, resource_size, usage, format_desc, pool, parent);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize resource, returning %#x.\n", hr);
+ return hr;
+ }
+
+ /* "Standalone" surface. */
+ IWineD3DSurface_SetContainer((IWineD3DSurface *)surface, NULL);
+
+ surface->currentDesc.Width = width;
+ surface->currentDesc.Height = height;
+ surface->currentDesc.MultiSampleType = multisample_type;
+ surface->currentDesc.MultiSampleQuality = multisample_quality;
+ surface->glDescription.level = level;
+ list_init(&surface->overlays);
+
+ /* Flags */
+ surface->Flags = SFLAG_NORMCOORD; /* Default to normalized coords. */
+ if (discard) surface->Flags |= SFLAG_DISCARD;
+ if (lockable || format == WINED3DFMT_D16_LOCKABLE) surface->Flags |= SFLAG_LOCKABLE;
+
+ /* Quick lockable sanity check.
+ * TODO: remove this after surfaces, usage and lockability have been debugged properly
+ * this function is too deep to need to care about things like this.
+ * Levels need to be checked too, since they all affect what can be done. */
+ switch (pool)
+ {
+ case WINED3DPOOL_SCRATCH:
+ if(!lockable)
+ {
+ FIXME("Called with a pool of SCRATCH and a lockable of FALSE "
+ "which are mutually exclusive, setting lockable to TRUE.\n");
+ lockable = TRUE;
+ }
+ break;
+
+ case WINED3DPOOL_SYSTEMMEM:
+ if (!lockable)
+ FIXME("Called with a pool of SYSTEMMEM and a lockable of FALSE, this is acceptable but unexpected.\n");
+ break;
+
+ case WINED3DPOOL_MANAGED:
+ if (usage & WINED3DUSAGE_DYNAMIC)
+ FIXME("Called with a pool of MANAGED and a usage of DYNAMIC which are mutually exclusive.\n");
+ break;
+
+ case WINED3DPOOL_DEFAULT:
+ if (lockable && !(usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL)))
+ WARN("Creating a lockable surface with a POOL of DEFAULT, that doesn't specify DYNAMIC usage.\n");
+ break;
+
+ default:
+ FIXME("Unknown pool %#x.\n", pool);
+ break;
+ };
+
+ if (usage & WINED3DUSAGE_RENDERTARGET && pool != WINED3DPOOL_DEFAULT)
+ {
+ FIXME("Trying to create a render target that isn't in the default pool.\n");
+ }
+
+ /* Mark the texture as dirty so that it gets loaded first time around. */
+ surface_add_dirty_rect((IWineD3DSurface *)surface, NULL);
+ list_init(&surface->renderbuffers);
+
+ TRACE("surface %p, memory %p, size %u\n", surface, surface->resource.allocatedMemory, surface->resource.size);
+
+ /* Call the private setup routine */
+ hr = IWineD3DSurface_PrivateSetup((IWineD3DSurface *)surface);
+ if (FAILED(hr))
+ {
+ ERR("Private setup failed, returning %#x\n", hr);
+ cleanup(surface);
+ return hr;
+ }
+
+ return hr;
+}
+
static void surface_force_reload(IWineD3DSurface *iface)
{
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
@@ -190,6 +329,10 @@ static BOOL primary_render_target_is_p8(IWineD3DDeviceImpl *device)
return FALSE;
}
+#undef GLINFO_LOCATION
+
+#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
+
/* This call just downloads data, the caller is responsible for activating the
* right context and binding the correct texture. */
static void surface_download_data(IWineD3DSurfaceImpl *This) {
diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c
index ca5c738..a194569 100644
--- a/dlls/wined3d/surface_gdi.c
+++ b/dlls/wined3d/surface_gdi.c
@@ -35,7 +35,7 @@
/* Use the d3d_surface debug channel to have one channel for all surfaces */
WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
-static void surface_gdi_cleanup(IWineD3DSurfaceImpl *This)
+void surface_gdi_cleanup(IWineD3DSurfaceImpl *This)
{
TRACE("(%p) : Cleaning up.\n", This);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1997792..a1ac336 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1920,6 +1920,12 @@ struct IWineD3DSurfaceImpl
extern const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl;
extern const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl;
+void surface_gdi_cleanup(IWineD3DSurfaceImpl *This);
+HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, UINT alignment,
+ UINT width, UINT height, UINT level, BOOL lockable, BOOL discard, WINED3DMULTISAMPLE_TYPE multisample_type,
+ UINT multisample_quality, IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format,
+ WINED3DPOOL pool, IUnknown *parent);
+
/* Predeclare the shared Surface functions */
HRESULT WINAPI IWineD3DBaseSurfaceImpl_QueryInterface(IWineD3DSurface *iface, REFIID riid, LPVOID *ppobj);
ULONG WINAPI IWineD3DBaseSurfaceImpl_AddRef(IWineD3DSurface *iface);
--
1.6.0.6
--------------020206080606080801050201--
More information about the wine-patches
mailing list