[PATCH 2/5] wined3d: Create and destroy surface DCs through the CS.
Henri Verbeet
hverbeet at codeweavers.com
Fri Mar 17 07:33:16 CDT 2017
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
dlls/wined3d/surface.c | 98 ----------------------------
dlls/wined3d/texture.c | 143 +++++++++++++++++++++++++++++++++++------
dlls/wined3d/wined3d_private.h | 2 -
3 files changed, 122 insertions(+), 121 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 7c84ffd..aa85698 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -252,104 +252,6 @@ static void get_color_masks(const struct wined3d_format *format, DWORD *masks)
masks[2] = ((1u << format->blue_size) - 1) << format->blue_offset;
}
-void wined3d_surface_destroy_dc(struct wined3d_surface *surface)
-{
- unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
- struct wined3d_texture *texture = surface->container;
- struct wined3d_device *device = texture->resource.device;
- const struct wined3d_gl_info *gl_info = NULL;
- D3DKMT_DESTROYDCFROMMEMORY destroy_desc;
- struct wined3d_context *context = NULL;
- struct wined3d_bo_address data;
- NTSTATUS status;
-
- if (!surface->dc)
- {
- ERR("Surface %p has no DC.\n", surface);
- return;
- }
-
- TRACE("dc %p, bitmap %p.\n", surface->dc, surface->bitmap);
-
- destroy_desc.hDc = surface->dc;
- destroy_desc.hBitmap = surface->bitmap;
- if ((status = D3DKMTDestroyDCFromMemory(&destroy_desc)))
- ERR("Failed to destroy dc, status %#x.\n", status);
- surface->dc = NULL;
- surface->bitmap = NULL;
-
- if (device->d3d_initialized)
- {
- context = context_acquire(device, NULL, 0);
- gl_info = context->gl_info;
- }
-
- wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
- wined3d_texture_unmap_bo_address(&data, gl_info, GL_PIXEL_UNPACK_BUFFER);
-
- if (context)
- context_release(context);
-}
-
-HRESULT wined3d_surface_create_dc(struct wined3d_surface *surface)
-{
- unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
- struct wined3d_texture *texture = surface->container;
- const struct wined3d_format *format = texture->resource.format;
- struct wined3d_device *device = texture->resource.device;
- const struct wined3d_gl_info *gl_info = NULL;
- struct wined3d_context *context = NULL;
- unsigned int row_pitch, slice_pitch;
- struct wined3d_bo_address data;
- D3DKMT_CREATEDCFROMMEMORY desc;
- NTSTATUS status;
-
- TRACE("surface %p.\n", surface);
-
- if (!format->ddi_format)
- {
- WARN("Cannot create a DC for format %s.\n", debug_d3dformat(format->id));
- return WINED3DERR_INVALIDCALL;
- }
-
- wined3d_texture_get_pitch(texture, surface->texture_level, &row_pitch, &slice_pitch);
-
- if (device->d3d_initialized)
- {
- context = context_acquire(device, NULL, 0);
- gl_info = context->gl_info;
- }
-
- wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
- desc.pMemory = wined3d_texture_map_bo_address(&data, texture->sub_resources[sub_resource_idx].size,
- gl_info, GL_PIXEL_UNPACK_BUFFER, 0);
-
- if (context)
- context_release(context);
-
- desc.Format = format->ddi_format;
- desc.Width = wined3d_texture_get_level_width(texture, surface->texture_level);
- desc.Height = wined3d_texture_get_level_height(texture, surface->texture_level);
- desc.Pitch = row_pitch;
- desc.hDeviceDc = CreateCompatibleDC(NULL);
- desc.pColorTable = NULL;
-
- status = D3DKMTCreateDCFromMemory(&desc);
- DeleteDC(desc.hDeviceDc);
- if (status)
- {
- WARN("Failed to create DC, status %#x.\n", status);
- return WINED3DERR_INVALIDCALL;
- }
-
- surface->dc = desc.hDc;
- surface->bitmap = desc.hBitmap;
-
- TRACE("Created DC %p, bitmap %p for surface %p.\n", surface->dc, surface->bitmap, surface);
-
- return WINED3D_OK;
-}
-
static BOOL surface_is_full_rect(const struct wined3d_surface *surface, const RECT *r)
{
unsigned int t;
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index ddc128c..4351089 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -1212,6 +1212,114 @@ HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture,
return WINED3D_OK;
}
+static void texture2d_create_dc(void *object)
+{
+ const struct wined3d_gl_info *gl_info = NULL;
+ struct wined3d_surface *surface = object;
+ struct wined3d_context *context = NULL;
+ const struct wined3d_format *format;
+ unsigned int row_pitch, slice_pitch;
+ struct wined3d_texture *texture;
+ struct wined3d_bo_address data;
+ D3DKMT_CREATEDCFROMMEMORY desc;
+ unsigned int sub_resource_idx;
+ struct wined3d_device *device;
+ NTSTATUS status;
+
+ TRACE("surface %p.\n", surface);
+
+ texture = surface->container;
+ sub_resource_idx = surface_get_sub_resource_idx(surface);
+ device = texture->resource.device;
+
+ format = texture->resource.format;
+ if (!format->ddi_format)
+ {
+ WARN("Cannot create a DC for format %s.\n", debug_d3dformat(format->id));
+ return;
+ }
+
+ if (device->d3d_initialized)
+ {
+ context = context_acquire(device, NULL, 0);
+ gl_info = context->gl_info;
+ }
+
+ wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding);
+ wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding);
+ wined3d_texture_get_pitch(texture, surface->texture_level, &row_pitch, &slice_pitch);
+ wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
+ desc.pMemory = wined3d_texture_map_bo_address(&data, texture->sub_resources[sub_resource_idx].size,
+ gl_info, GL_PIXEL_UNPACK_BUFFER, 0);
+
+ if (context)
+ context_release(context);
+
+ desc.Format = format->ddi_format;
+ desc.Width = wined3d_texture_get_level_width(texture, surface->texture_level);
+ desc.Height = wined3d_texture_get_level_height(texture, surface->texture_level);
+ desc.Pitch = row_pitch;
+ desc.hDeviceDc = CreateCompatibleDC(NULL);
+ desc.pColorTable = NULL;
+
+ status = D3DKMTCreateDCFromMemory(&desc);
+ DeleteDC(desc.hDeviceDc);
+ if (status)
+ {
+ WARN("Failed to create DC, status %#x.\n", status);
+ return;
+ }
+
+ surface->dc = desc.hDc;
+ surface->bitmap = desc.hBitmap;
+
+ TRACE("Created DC %p, bitmap %p for surface %p.\n", surface->dc, surface->bitmap, surface);
+}
+
+static void texture2d_destroy_dc(void *object)
+{
+ const struct wined3d_gl_info *gl_info = NULL;
+ struct wined3d_surface *surface = object;
+ D3DKMT_DESTROYDCFROMMEMORY destroy_desc;
+ struct wined3d_context *context = NULL;
+ struct wined3d_texture *texture;
+ struct wined3d_bo_address data;
+ unsigned int sub_resource_idx;
+ struct wined3d_device *device;
+ NTSTATUS status;
+
+ texture = surface->container;
+ sub_resource_idx = surface_get_sub_resource_idx(surface);
+ device = texture->resource.device;
+
+ if (!surface->dc)
+ {
+ ERR("Surface %p has no DC.\n", surface);
+ return;
+ }
+
+ TRACE("dc %p, bitmap %p.\n", surface->dc, surface->bitmap);
+
+ destroy_desc.hDc = surface->dc;
+ destroy_desc.hBitmap = surface->bitmap;
+ if ((status = D3DKMTDestroyDCFromMemory(&destroy_desc)))
+ ERR("Failed to destroy dc, status %#x.\n", status);
+ surface->dc = NULL;
+ surface->bitmap = NULL;
+
+ if (device->d3d_initialized)
+ {
+ context = context_acquire(device, NULL, 0);
+ gl_info = context->gl_info;
+ }
+
+ wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
+ wined3d_texture_unmap_bo_address(&data, gl_info, GL_PIXEL_UNPACK_BUFFER);
+
+ if (context)
+ context_release(context);
+}
+
HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT width, UINT height,
enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type,
UINT multisample_quality, void *mem, UINT pitch)
@@ -1271,7 +1379,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
surface = sub_resource->u.surface;
if (surface->dc)
{
- wined3d_surface_destroy_dc(surface);
+ wined3d_cs_destroy_object(device->cs, texture2d_destroy_dc, surface);
create_dib = TRUE;
}
@@ -1332,7 +1440,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
wined3d_texture_invalidate_location(texture, 0, ~valid_location);
if (create_dib)
- wined3d_surface_create_dc(surface);
+ wined3d_cs_init_object(device->cs, texture2d_create_dc, surface);
return WINED3D_OK;
}
@@ -1683,7 +1791,7 @@ static void texture2d_cleanup_sub_resources(struct wined3d_texture *texture)
}
if (surface->dc)
- wined3d_surface_destroy_dc(surface);
+ texture2d_destroy_dc(surface);
if (surface->overlay_dest)
list_remove(&surface->overlay_entry);
@@ -2206,11 +2314,14 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
TRACE("Created surface level %u, layer %u @ %p.\n", i, j, surface);
- if (((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D))
- && FAILED(hr = wined3d_surface_create_dc(surface)))
+ if ((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D))
{
- wined3d_texture_cleanup_sync(texture);
- return hr;
+ wined3d_cs_init_object(device->cs, texture2d_create_dc, surface);
+ if (!surface->dc)
+ {
+ wined3d_texture_cleanup_sync(texture);
+ return WINED3DERR_INVALIDCALL;
+ }
}
}
}
@@ -2984,9 +3095,7 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i
{
struct wined3d_device *device = texture->resource.device;
struct wined3d_texture_sub_resource *sub_resource;
- struct wined3d_context *context = NULL;
struct wined3d_surface *surface;
- HRESULT hr = WINED3D_OK;
TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc);
@@ -3011,17 +3120,9 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i
if (texture->resource.map_count && !(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT))
return WINED3DERR_INVALIDCALL;
- if (device->d3d_initialized)
- context = context_acquire(device, NULL, 0);
-
- wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding);
- wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding);
-
if (!surface->dc)
- hr = wined3d_surface_create_dc(surface);
- if (context)
- context_release(context);
- if (FAILED(hr))
+ wined3d_cs_init_object(device->cs, texture2d_create_dc, surface);
+ if (!surface->dc)
return WINED3DERR_INVALIDCALL;
if (!(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT))
@@ -3032,7 +3133,7 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i
*dc = surface->dc;
TRACE("Returning dc %p.\n", *dc);
- return hr;
+ return WINED3D_OK;
}
HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc)
@@ -3064,7 +3165,7 @@ HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsign
}
if (!(texture->resource.usage & WINED3DUSAGE_OWNDC) && !(device->wined3d->flags & WINED3D_NO3D))
- wined3d_surface_destroy_dc(surface);
+ wined3d_cs_destroy_object(device->cs, texture2d_destroy_dc, surface);
--sub_resource->map_count;
if (!--texture->resource.map_count && texture->update_map_binding)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1a01106..5b5134a 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3061,8 +3061,6 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
const struct wined3d_blt_fx *blt_fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
HRESULT surface_color_fill(struct wined3d_surface *s,
const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN;
-HRESULT wined3d_surface_create_dc(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
-void wined3d_surface_destroy_dc(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb,
struct wined3d_context *context) DECLSPEC_HIDDEN;
BOOL surface_load_location(struct wined3d_surface *surface,
--
2.1.4
More information about the wine-patches
mailing list