wined3d: Create and destroy surface DCs through the CS.
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d9d5dcee2b
commit
ad46b67674
|
@ -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;
|
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)
|
static BOOL surface_is_full_rect(const struct wined3d_surface *surface, const RECT *r)
|
||||||
{
|
{
|
||||||
unsigned int t;
|
unsigned int t;
|
||||||
|
|
|
@ -1212,6 +1212,114 @@ HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture,
|
||||||
return WINED3D_OK;
|
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,
|
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,
|
enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type,
|
||||||
UINT multisample_quality, void *mem, UINT pitch)
|
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;
|
surface = sub_resource->u.surface;
|
||||||
if (surface->dc)
|
if (surface->dc)
|
||||||
{
|
{
|
||||||
wined3d_surface_destroy_dc(surface);
|
wined3d_cs_destroy_object(device->cs, texture2d_destroy_dc, surface);
|
||||||
create_dib = TRUE;
|
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);
|
wined3d_texture_invalidate_location(texture, 0, ~valid_location);
|
||||||
|
|
||||||
if (create_dib)
|
if (create_dib)
|
||||||
wined3d_surface_create_dc(surface);
|
wined3d_cs_init_object(device->cs, texture2d_create_dc, surface);
|
||||||
|
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
}
|
}
|
||||||
|
@ -1683,7 +1791,7 @@ static void texture2d_cleanup_sub_resources(struct wined3d_texture *texture)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (surface->dc)
|
if (surface->dc)
|
||||||
wined3d_surface_destroy_dc(surface);
|
texture2d_destroy_dc(surface);
|
||||||
|
|
||||||
if (surface->overlay_dest)
|
if (surface->overlay_dest)
|
||||||
list_remove(&surface->overlay_entry);
|
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);
|
TRACE("Created surface level %u, layer %u @ %p.\n", i, j, surface);
|
||||||
|
|
||||||
if (((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D))
|
if ((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D))
|
||||||
&& FAILED(hr = wined3d_surface_create_dc(surface)))
|
|
||||||
{
|
{
|
||||||
wined3d_texture_cleanup_sync(texture);
|
wined3d_cs_init_object(device->cs, texture2d_create_dc, surface);
|
||||||
return hr;
|
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_device *device = texture->resource.device;
|
||||||
struct wined3d_texture_sub_resource *sub_resource;
|
struct wined3d_texture_sub_resource *sub_resource;
|
||||||
struct wined3d_context *context = NULL;
|
|
||||||
struct wined3d_surface *surface;
|
struct wined3d_surface *surface;
|
||||||
HRESULT hr = WINED3D_OK;
|
|
||||||
|
|
||||||
TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc);
|
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))
|
if (texture->resource.map_count && !(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT))
|
||||||
return WINED3DERR_INVALIDCALL;
|
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)
|
if (!surface->dc)
|
||||||
hr = wined3d_surface_create_dc(surface);
|
wined3d_cs_init_object(device->cs, texture2d_create_dc, surface);
|
||||||
if (context)
|
if (!surface->dc)
|
||||||
context_release(context);
|
|
||||||
if (FAILED(hr))
|
|
||||||
return WINED3DERR_INVALIDCALL;
|
return WINED3DERR_INVALIDCALL;
|
||||||
|
|
||||||
if (!(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT))
|
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;
|
*dc = surface->dc;
|
||||||
TRACE("Returning dc %p.\n", *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)
|
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))
|
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;
|
--sub_resource->map_count;
|
||||||
if (!--texture->resource.map_count && texture->update_map_binding)
|
if (!--texture->resource.map_count && texture->update_map_binding)
|
||||||
|
|
|
@ -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;
|
const struct wined3d_blt_fx *blt_fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
|
||||||
HRESULT surface_color_fill(struct wined3d_surface *s,
|
HRESULT surface_color_fill(struct wined3d_surface *s,
|
||||||
const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN;
|
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,
|
void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb,
|
||||||
struct wined3d_context *context) DECLSPEC_HIDDEN;
|
struct wined3d_context *context) DECLSPEC_HIDDEN;
|
||||||
BOOL surface_load_location(struct wined3d_surface *surface,
|
BOOL surface_load_location(struct wined3d_surface *surface,
|
||||||
|
|
Loading…
Reference in New Issue