[PATCH 2/6] wined3d: Implement texture DC creation on top of D3DKMTCreateDCFromMemory().
Henri Verbeet
hverbeet at codeweavers.com
Thu Apr 14 12:32:46 CDT 2016
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
dlls/d3d9/tests/d3d9ex.c | 2 +-
dlls/d3d9/tests/device.c | 2 +-
dlls/ddraw/surface.c | 2 +-
dlls/ddraw/tests/ddraw1.c | 2 +-
dlls/ddraw/tests/ddraw2.c | 4 +-
dlls/ddraw/tests/ddraw4.c | 4 +-
dlls/ddraw/tests/ddraw7.c | 4 +-
dlls/wined3d/palette.c | 5 --
dlls/wined3d/surface.c | 200 ++++++++++++++++-------------------------
dlls/wined3d/swapchain.c | 45 +++-------
dlls/wined3d/texture.c | 101 +++++++--------------
dlls/wined3d/utils.c | 42 ++++++---
dlls/wined3d/wined3d_private.h | 37 ++++----
13 files changed, 180 insertions(+), 270 deletions(-)
diff --git a/dlls/d3d9/tests/d3d9ex.c b/dlls/d3d9/tests/d3d9ex.c
index e9548de..8506f2d 100644
--- a/dlls/d3d9/tests/d3d9ex.c
+++ b/dlls/d3d9/tests/d3d9ex.c
@@ -1471,7 +1471,7 @@ static void test_user_memory_getdc(void)
ok(!!bitmap, "Failed to get bitmap.\n");
size = GetObjectA(bitmap, sizeof(dib), &dib);
ok(size == sizeof(dib), "Got unexpected size %d.\n", size);
- todo_wine ok(dib.dsBm.bmBits == data, "Got unexpected bits %p, expected %p.\n", dib.dsBm.bmBits, data);
+ ok(dib.dsBm.bmBits == data, "Got unexpected bits %p, expected %p.\n", dib.dsBm.bmBits, data);
BitBlt(dc, 0, 0, 16, 8, NULL, 0, 0, WHITENESS);
BitBlt(dc, 0, 8, 16, 8, NULL, 0, 0, BLACKNESS);
hr = IDirect3DSurface9_ReleaseDC(surface, dc);
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index a14e3d4..237fcc3 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -7689,7 +7689,7 @@ static void test_getdc(void)
ok(dib.dsBmih.biCompression == (testdata[i].bit_count == 16 ? BI_BITFIELDS : BI_RGB),
"Got unexpected compression %#x for format %s.\n",
dib.dsBmih.biCompression, testdata[i].name);
- todo_wine ok(!dib.dsBmih.biSizeImage, "Got unexpected image size %u for format %s.\n",
+ ok(!dib.dsBmih.biSizeImage, "Got unexpected image size %u for format %s.\n",
dib.dsBmih.biSizeImage, testdata[i].name);
ok(!dib.dsBmih.biXPelsPerMeter, "Got unexpected horizontal resolution %d for format %s.\n",
dib.dsBmih.biXPelsPerMeter, testdata[i].name);
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index c47c546..8f627d8 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -2172,7 +2172,7 @@ static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7 *iface, HDC *dc)
* does not touch *dc. */
case WINED3DERR_INVALIDCALL:
*dc = NULL;
- return DDERR_INVALIDPARAMS;
+ return DDERR_CANTCREATEDC;
default:
return hr;
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index 9b9db30..0bb601b 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -8720,7 +8720,7 @@ static void test_getdc(void)
|| broken(U2(test_data[i].format).dwRGBBitCount == 32 && dib.dsBmih.biCompression == BI_BITFIELDS),
"Got unexpected compression %#x for format %s.\n",
dib.dsBmih.biCompression, test_data[i].name);
- todo_wine ok(!dib.dsBmih.biSizeImage, "Got unexpected image size %u for format %s.\n",
+ ok(!dib.dsBmih.biSizeImage, "Got unexpected image size %u for format %s.\n",
dib.dsBmih.biSizeImage, test_data[i].name);
ok(!dib.dsBmih.biXPelsPerMeter, "Got unexpected horizontal resolution %d for format %s.\n",
dib.dsBmih.biXPelsPerMeter, test_data[i].name);
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index 43e2c48..f1a5ff3 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -5346,7 +5346,7 @@ static void test_user_memory_getdc(void)
ok(!!bitmap, "Failed to get bitmap.\n");
size = GetObjectA(bitmap, sizeof(dib), &dib);
ok(size == sizeof(dib), "Got unexpected size %d.\n", size);
- todo_wine ok(dib.dsBm.bmBits == data, "Got unexpected bits %p, expected %p.\n", dib.dsBm.bmBits, data);
+ ok(dib.dsBm.bmBits == data, "Got unexpected bits %p, expected %p.\n", dib.dsBm.bmBits, data);
BitBlt(dc, 0, 0, 16, 8, NULL, 0, 0, WHITENESS);
BitBlt(dc, 0, 8, 16, 8, NULL, 0, 0, BLACKNESS);
hr = IDirectDrawSurface3_ReleaseDC(surface3, dc);
@@ -9835,7 +9835,7 @@ static void test_getdc(void)
|| broken(U2(test_data[i].format).dwRGBBitCount == 32 && dib.dsBmih.biCompression == BI_BITFIELDS),
"Got unexpected compression %#x for format %s.\n",
dib.dsBmih.biCompression, test_data[i].name);
- todo_wine ok(!dib.dsBmih.biSizeImage, "Got unexpected image size %u for format %s.\n",
+ ok(!dib.dsBmih.biSizeImage, "Got unexpected image size %u for format %s.\n",
dib.dsBmih.biSizeImage, test_data[i].name);
ok(!dib.dsBmih.biXPelsPerMeter, "Got unexpected horizontal resolution %d for format %s.\n",
dib.dsBmih.biXPelsPerMeter, test_data[i].name);
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index fdf9e58..775b9d6 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -6659,7 +6659,7 @@ static void test_user_memory_getdc(void)
ok(!!bitmap, "Failed to get bitmap.\n");
size = GetObjectA(bitmap, sizeof(dib), &dib);
ok(size == sizeof(dib), "Got unexpected size %d.\n", size);
- todo_wine ok(dib.dsBm.bmBits == data, "Got unexpected bits %p, expected %p.\n", dib.dsBm.bmBits, data);
+ ok(dib.dsBm.bmBits == data, "Got unexpected bits %p, expected %p.\n", dib.dsBm.bmBits, data);
BitBlt(dc, 0, 0, 16, 8, NULL, 0, 0, WHITENESS);
BitBlt(dc, 0, 8, 16, 8, NULL, 0, 0, BLACKNESS);
hr = IDirectDrawSurface4_ReleaseDC(surface, dc);
@@ -11112,7 +11112,7 @@ static void test_getdc(void)
|| broken(U2(test_data[i].format).dwRGBBitCount == 32 && dib.dsBmih.biCompression == BI_BITFIELDS),
"Got unexpected compression %#x for format %s.\n",
dib.dsBmih.biCompression, test_data[i].name);
- todo_wine ok(!dib.dsBmih.biSizeImage, "Got unexpected image size %u for format %s.\n",
+ ok(!dib.dsBmih.biSizeImage, "Got unexpected image size %u for format %s.\n",
dib.dsBmih.biSizeImage, test_data[i].name);
ok(!dib.dsBmih.biXPelsPerMeter, "Got unexpected horizontal resolution %d for format %s.\n",
dib.dsBmih.biXPelsPerMeter, test_data[i].name);
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 2fc2796..f4388ca 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -6525,7 +6525,7 @@ static void test_user_memory_getdc(void)
ok(!!bitmap, "Failed to get bitmap.\n");
size = GetObjectA(bitmap, sizeof(dib), &dib);
ok(size == sizeof(dib), "Got unexpected size %d.\n", size);
- todo_wine ok(dib.dsBm.bmBits == data, "Got unexpected bits %p, expected %p.\n", dib.dsBm.bmBits, data);
+ ok(dib.dsBm.bmBits == data, "Got unexpected bits %p, expected %p.\n", dib.dsBm.bmBits, data);
BitBlt(dc, 0, 0, 16, 8, NULL, 0, 0, WHITENESS);
BitBlt(dc, 0, 8, 16, 8, NULL, 0, 0, BLACKNESS);
hr = IDirectDrawSurface7_ReleaseDC(surface, dc);
@@ -11378,7 +11378,7 @@ static void test_getdc(void)
|| broken(U2(test_data[i].format).dwRGBBitCount == 32 && dib.dsBmih.biCompression == BI_BITFIELDS),
"Got unexpected compression %#x for format %s.\n",
dib.dsBmih.biCompression, test_data[i].name);
- todo_wine ok(!dib.dsBmih.biSizeImage, "Got unexpected image size %u for format %s.\n",
+ ok(!dib.dsBmih.biSizeImage, "Got unexpected image size %u for format %s.\n",
dib.dsBmih.biSizeImage, test_data[i].name);
ok(!dib.dsBmih.biXPelsPerMeter, "Got unexpected horizontal resolution %d for format %s.\n",
dib.dsBmih.biXPelsPerMeter, test_data[i].name);
diff --git a/dlls/wined3d/palette.c b/dlls/wined3d/palette.c
index 0d7bfa4..fadcc43 100644
--- a/dlls/wined3d/palette.c
+++ b/dlls/wined3d/palette.c
@@ -20,11 +20,6 @@
*/
#include "config.h"
#include "wine/port.h"
-#include "winerror.h"
-#include "wine/debug.h"
-
-#include <string.h>
-
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index de82dda..9dfefe0 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -35,9 +35,8 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
#define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy. */
-static const DWORD surface_simple_locations =
- WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY
- | WINED3D_LOCATION_DIB | WINED3D_LOCATION_BUFFER;
+static const DWORD surface_simple_locations = WINED3D_LOCATION_SYSMEM
+ | WINED3D_LOCATION_USER_MEMORY | WINED3D_LOCATION_BUFFER;
void wined3d_surface_cleanup(struct wined3d_surface *surface)
{
@@ -80,12 +79,8 @@ void wined3d_surface_cleanup(struct wined3d_surface *surface)
context_release(context);
}
- if (surface->flags & SFLAG_DIBSECTION)
- {
- DeleteDC(surface->hDC);
- DeleteObject(surface->dib.DIBsection);
- surface->dib.bitmap_data = NULL;
- }
+ if (surface->dc)
+ wined3d_surface_destroy_dc(surface);
if (surface->overlay_dest)
list_remove(&surface->overlay_entry);
@@ -348,110 +343,100 @@ static void get_color_masks(const struct wined3d_format *format, DWORD *masks)
masks[2] = ((1u << format->blue_size) - 1) << format->blue_offset;
}
-HRESULT surface_create_dib_section(struct wined3d_surface *surface)
+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;
- const struct wined3d_format *format = texture->resource.format;
- unsigned int format_flags = texture->resource.format_flags;
- unsigned int row_pitch, slice_pitch;
- BITMAPINFO *b_info;
- DWORD *masks;
-
- TRACE("surface %p.\n", surface);
+ 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 (!(format_flags & WINED3DFMT_FLAG_GETDC))
+ if (!surface->dc)
{
- WARN("Cannot use GetDC on a %s surface.\n", debug_d3dformat(format->id));
- return WINED3DERR_INVALIDCALL;
+ ERR("Surface %p has no DC.\n", surface);
+ return;
}
- switch (format->byte_count)
- {
- case 2:
- case 4:
- /* Allocate extra space to store the RGB bit masks. */
- b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(BITMAPINFO, bmiColors[3]));
- break;
+ TRACE("dc %p, bitmap %p.\n", surface->dc, surface->bitmap);
- case 3:
- b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(BITMAPINFO, bmiColors[0]));
- break;
+ 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;
- default:
- /* Allocate extra space for a palette. */
- b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- FIELD_OFFSET(BITMAPINFO, bmiColors[1u << (format->byte_count * 8)]));
- break;
+ if (device->d3d_initialized)
+ {
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
}
- if (!b_info)
- return E_OUTOFMEMORY;
+ wined3d_texture_get_memory(texture, sub_resource_idx, &data, surface->resource.map_binding);
+ wined3d_texture_unmap_bo_address(&data, gl_info, GL_PIXEL_UNPACK_BUFFER);
- b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- wined3d_texture_get_pitch(texture, surface->texture_level, &row_pitch, &slice_pitch);
- b_info->bmiHeader.biWidth = row_pitch / format->byte_count;
- b_info->bmiHeader.biHeight = 0 - wined3d_texture_get_level_height(texture, surface->texture_level);
- b_info->bmiHeader.biSizeImage = slice_pitch;
- b_info->bmiHeader.biPlanes = 1;
- b_info->bmiHeader.biBitCount = format->byte_count * 8;
-
- b_info->bmiHeader.biXPelsPerMeter = 0;
- b_info->bmiHeader.biYPelsPerMeter = 0;
- b_info->bmiHeader.biClrUsed = 0;
- b_info->bmiHeader.biClrImportant = 0;
-
- /* Get the bit masks */
- masks = (DWORD *)b_info->bmiColors;
- switch (format->id)
- {
- case WINED3DFMT_B8G8R8_UNORM:
- b_info->bmiHeader.biCompression = BI_RGB;
- break;
+ if (context)
+ context_release(context);
+}
- case WINED3DFMT_B5G5R5X1_UNORM:
- case WINED3DFMT_B5G5R5A1_UNORM:
- case WINED3DFMT_B4G4R4A4_UNORM:
- case WINED3DFMT_B4G4R4X4_UNORM:
- case WINED3DFMT_B2G3R3_UNORM:
- case WINED3DFMT_B2G3R3A8_UNORM:
- case WINED3DFMT_R10G10B10A2_UNORM:
- case WINED3DFMT_R8G8B8A8_UNORM:
- case WINED3DFMT_R8G8B8X8_UNORM:
- case WINED3DFMT_B10G10R10A2_UNORM:
- case WINED3DFMT_B5G6R5_UNORM:
- case WINED3DFMT_R16G16B16A16_UNORM:
- b_info->bmiHeader.biCompression = BI_BITFIELDS;
- get_color_masks(format, masks);
- break;
+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;
- default:
- /* Don't know palette */
- b_info->bmiHeader.biCompression = BI_RGB;
- break;
+ 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;
}
- TRACE("Creating a DIB section with size %dx%dx%d, size=%d.\n",
- b_info->bmiHeader.biWidth, b_info->bmiHeader.biHeight,
- b_info->bmiHeader.biBitCount, b_info->bmiHeader.biSizeImage);
- surface->dib.DIBsection = CreateDIBSection(0, b_info, DIB_RGB_COLORS, &surface->dib.bitmap_data, 0, 0);
+ wined3d_texture_get_pitch(texture, surface->texture_level, &row_pitch, &slice_pitch);
- if (!surface->dib.DIBsection)
+ if (device->d3d_initialized)
{
- ERR("Failed to create DIB section.\n");
- HeapFree(GetProcessHeap(), 0, b_info);
- return HRESULT_FROM_WIN32(GetLastError());
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
}
- TRACE("DIBSection at %p.\n", surface->dib.bitmap_data);
- surface->dib.bitmap_size = b_info->bmiHeader.biSizeImage;
+ wined3d_texture_get_memory(texture, sub_resource_idx, &data, surface->resource.map_binding);
+ desc.pMemory = wined3d_texture_map_bo_address(&data, surface->resource.size,
+ gl_info, GL_PIXEL_UNPACK_BUFFER, 0);
- HeapFree(GetProcessHeap(), 0, b_info);
+ if (context)
+ context_release(context);
- /* Now allocate a DC. */
- surface->hDC = CreateCompatibleDC(0);
- SelectObject(surface->hDC, surface->dib.DIBsection);
+ 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;
- surface->flags |= SFLAG_DIBSECTION;
+ 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;
}
@@ -2905,7 +2890,6 @@ static DWORD resource_access_from_location(DWORD location)
{
case WINED3D_LOCATION_SYSMEM:
case WINED3D_LOCATION_USER_MEMORY:
- case WINED3D_LOCATION_DIB:
case WINED3D_LOCATION_BUFFER:
return WINED3D_RESOURCE_ACCESS_CPU;
@@ -3132,11 +3116,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
{
TRACE("Removing the pbo attached to surface %p.\n", surface);
- if (surface->flags & SFLAG_DIBSECTION)
- surface->resource.map_binding = WINED3D_LOCATION_DIB;
- else
- surface->resource.map_binding = WINED3D_LOCATION_SYSMEM;
-
+ surface->resource.map_binding = WINED3D_LOCATION_SYSMEM;
surface_load_location(surface, context, surface->resource.map_binding);
wined3d_texture_remove_buffer_object(texture, sub_resource_idx, gl_info);
}
@@ -3275,7 +3255,6 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co
switch (location)
{
- case WINED3D_LOCATION_DIB:
case WINED3D_LOCATION_USER_MEMORY:
case WINED3D_LOCATION_SYSMEM:
case WINED3D_LOCATION_BUFFER:
@@ -4567,26 +4546,6 @@ HRESULT wined3d_surface_init(struct wined3d_surface *surface, struct wined3d_tex
if (wined3d_texture_use_pbo(container, gl_info))
surface->resource.map_binding = WINED3D_LOCATION_BUFFER;
- /* Similar to lockable rendertargets above, creating the DIB section
- * during surface initialization prevents the sysmem pointer from changing
- * after a wined3d_texture_get_dc() call. */
- if ((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D))
- {
- if (FAILED(hr = surface_create_dib_section(surface)))
- {
- wined3d_surface_cleanup(surface);
- return hr;
- }
- surface->resource.map_binding = WINED3D_LOCATION_DIB;
- }
-
- if (surface->resource.map_binding == WINED3D_LOCATION_DIB)
- {
- wined3d_resource_free_sysmem(&surface->resource);
- wined3d_texture_validate_location(container, sub_resource_idx, WINED3D_LOCATION_DIB);
- wined3d_texture_invalidate_location(container, sub_resource_idx, WINED3D_LOCATION_SYSMEM);
- }
-
return hr;
}
@@ -4607,11 +4566,6 @@ void wined3d_surface_prepare(struct wined3d_surface *surface, struct wined3d_con
ERR("Map binding is set to WINED3D_LOCATION_USER_MEMORY but surface->user_memory is NULL.\n");
break;
- case WINED3D_LOCATION_DIB:
- if (!surface->dib.bitmap_data)
- ERR("Map binding is set to WINED3D_LOCATION_DIB but surface->dib.bitmap_data is NULL.\n");
- break;
-
case WINED3D_LOCATION_BUFFER:
wined3d_texture_prepare_buffer_object(texture,
surface_get_sub_resource_idx(surface), context->gl_info);
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index e5c7da6..e9e6bfa 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -661,16 +661,14 @@ static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchai
front = swapchain->front_buffer->sub_resources[0].u.surface;
if (swapchain->palette)
- wined3d_palette_apply_to_dc(swapchain->palette, front->hDC);
+ wined3d_palette_apply_to_dc(swapchain->palette, front->dc);
if (front->container->resource.map_count)
ERR("Trying to blit a mapped surface.\n");
TRACE("Copying surface %p to screen.\n", front);
- surface_load_location(front, NULL, WINED3D_LOCATION_DIB);
-
- src_dc = front->hDC;
+ src_dc = front->dc;
window = swapchain->win_handle;
dst_dc = GetDCEx(window, 0, DCX_CLIPSIBLINGS | DCX_CACHE);
@@ -699,40 +697,25 @@ static void swapchain_gdi_present(struct wined3d_swapchain *swapchain,
const RECT *src_rect, const RECT *dst_rect, DWORD flags)
{
struct wined3d_surface *front, *back;
+ HBITMAP bitmap;
+ void *data;
+ HDC dc;
front = swapchain->front_buffer->sub_resources[0].u.surface;
back = swapchain->back_buffers[0]->sub_resources[0].u.surface;
- /* Flip the DC. */
- {
- HDC tmp;
- tmp = front->hDC;
- front->hDC = back->hDC;
- back->hDC = tmp;
- }
-
- /* Flip the DIBsection. */
- {
- HBITMAP tmp;
- tmp = front->dib.DIBsection;
- front->dib.DIBsection = back->dib.DIBsection;
- back->dib.DIBsection = tmp;
- }
-
/* Flip the surface data. */
- {
- void *tmp;
+ dc = front->dc;
+ bitmap = front->bitmap;
+ data = front->resource.heap_memory;
- tmp = front->dib.bitmap_data;
- front->dib.bitmap_data = back->dib.bitmap_data;
- back->dib.bitmap_data = tmp;
+ front->dc = back->dc;
+ front->bitmap = back->bitmap;
+ front->resource.heap_memory = back->resource.heap_memory;
- if (front->resource.heap_memory)
- ERR("GDI Surface %p has heap memory allocated.\n", front);
-
- if (back->resource.heap_memory)
- ERR("GDI Surface %p has heap memory allocated.\n", back);
- }
+ back->dc = dc;
+ back->bitmap = bitmap;
+ back->resource.heap_memory = data;
/* FPS support */
if (TRACE_ON(fps))
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 50c5b2c..55d2a8e 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -105,7 +105,7 @@ void wined3d_texture_invalidate_location(struct wined3d_texture *texture,
}
/* Context activation is done by the caller. */
-static void *wined3d_texture_map_bo_address(const struct wined3d_bo_address *data, size_t size,
+void *wined3d_texture_map_bo_address(const struct wined3d_bo_address *data, size_t size,
const struct wined3d_gl_info *gl_info, GLenum binding, DWORD flags)
{
BYTE *memory;
@@ -133,7 +133,7 @@ static void *wined3d_texture_map_bo_address(const struct wined3d_bo_address *dat
}
/* Context activation is done by the caller. */
-static void wined3d_texture_unmap_bo_address(const struct wined3d_bo_address *data,
+void wined3d_texture_unmap_bo_address(const struct wined3d_bo_address *data,
const struct wined3d_gl_info *gl_info, GLenum binding)
{
if (!data->buffer_object)
@@ -166,17 +166,6 @@ void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int su
data->buffer_object = 0;
return;
}
- if (locations & WINED3D_LOCATION_DIB)
- {
- if (texture->resource.type == WINED3D_RTYPE_TEXTURE_2D)
- {
- data->addr = sub_resource->u.surface->dib.bitmap_data;
- data->buffer_object = 0;
- return;
- }
- ERR("Invalid location WINED3D_LOCATION_DIB for resource type %s.\n",
- debug_d3dresourcetype(texture->resource.type));
- }
if (locations & WINED3D_LOCATION_SYSMEM)
{
data->addr = sub_resource->resource->heap_memory;
@@ -903,14 +892,9 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
sub_resource = &texture->sub_resources[0];
surface = sub_resource->u.surface;
- if (surface->flags & SFLAG_DIBSECTION)
- {
- DeleteDC(surface->hDC);
- surface->hDC = NULL;
- DeleteObject(surface->dib.DIBsection);
- surface->dib.DIBsection = NULL;
- surface->dib.bitmap_data = NULL;
- surface->flags &= ~SFLAG_DIBSECTION;
+ if (surface->dc)
+ {
+ wined3d_surface_destroy_dc(surface);
create_dib = TRUE;
}
@@ -962,10 +946,6 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
sub_resource->resource->map_binding = WINED3D_LOCATION_USER_MEMORY;
valid_location = WINED3D_LOCATION_USER_MEMORY;
}
- else if (create_dib && SUCCEEDED(surface_create_dib_section(surface)))
- {
- valid_location = WINED3D_LOCATION_DIB;
- }
else
{
wined3d_surface_prepare(surface, NULL, WINED3D_LOCATION_SYSMEM);
@@ -977,10 +957,13 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
* change it - whatever made us not use PBOs might come back, e.g.
* color keys. */
if (sub_resource->resource->map_binding == WINED3D_LOCATION_BUFFER && !wined3d_texture_use_pbo(texture, gl_info))
- sub_resource->resource->map_binding = surface->dib.DIBsection ? WINED3D_LOCATION_DIB : WINED3D_LOCATION_SYSMEM;
+ sub_resource->resource->map_binding = WINED3D_LOCATION_SYSMEM;
wined3d_texture_validate_location(texture, 0, valid_location);
+ if (create_dib)
+ wined3d_surface_create_dc(surface);
+
return WINED3D_OK;
}
@@ -1693,6 +1676,13 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
texture->sub_resources[idx].resource = &surface->resource;
texture->sub_resources[idx].u.surface = surface;
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)))
+ {
+ wined3d_texture_cleanup(texture);
+ return hr;
+ }
}
/* Calculate the next mipmap level. */
surface_desc.width = max(1, surface_desc.width >> 1);
@@ -2239,7 +2229,7 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i
struct wined3d_texture_sub_resource *sub_resource;
struct wined3d_context *context = NULL;
struct wined3d_surface *surface;
- HRESULT hr;
+ HRESULT hr = WINED3D_OK;
TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc);
@@ -2260,43 +2250,31 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i
if (device->d3d_initialized)
context = context_acquire(device, NULL);
- /* Create a DIB section if there isn't a dc yet. */
- if (!surface->hDC)
- {
- if (FAILED(hr = surface_create_dib_section(surface)))
- {
- if (context)
- context_release(context);
- return WINED3DERR_INVALIDCALL;
- }
- if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY
- || texture->flags & WINED3D_TEXTURE_PIN_SYSMEM
- || texture->sub_resources[sub_resource_idx].buffer_object))
- surface->resource.map_binding = WINED3D_LOCATION_DIB;
- }
-
- surface_load_location(surface, context, WINED3D_LOCATION_DIB);
- wined3d_texture_invalidate_location(texture, sub_resource_idx, ~WINED3D_LOCATION_DIB);
+ surface_load_location(surface, context, surface->resource.map_binding);
+ wined3d_texture_invalidate_location(texture, sub_resource_idx, ~surface->resource.map_binding);
+ if (!surface->dc)
+ hr = wined3d_surface_create_dc(surface);
if (context)
context_release(context);
+ if (FAILED(hr))
+ return WINED3DERR_INVALIDCALL;
if (!(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT))
texture->flags |= WINED3D_TEXTURE_DC_IN_USE;
++texture->resource.map_count;
++sub_resource->map_count;
- *dc = surface->hDC;
+ *dc = surface->dc;
TRACE("Returning dc %p.\n", *dc);
- return WINED3D_OK;
+ return hr;
}
HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc)
{
struct wined3d_device *device = texture->resource.device;
struct wined3d_texture_sub_resource *sub_resource;
- struct wined3d_context *context = NULL;
struct wined3d_surface *surface;
TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc);
@@ -2315,38 +2293,19 @@ HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsign
if (!(texture->flags & (WINED3D_TEXTURE_GET_DC_LENIENT | WINED3D_TEXTURE_DC_IN_USE)))
return WINED3DERR_INVALIDCALL;
- if (surface->hDC != dc)
+ if (surface->dc != dc)
{
- WARN("Application tries to release invalid DC %p, surface DC is %p.\n",
- dc, surface->hDC);
+ WARN("Application tries to release invalid DC %p, surface DC is %p.\n", dc, surface->dc);
return WINED3DERR_INVALIDCALL;
}
+ if (!(texture->resource.usage & WINED3DUSAGE_OWNDC) && !(device->wined3d->flags & WINED3D_NO3D))
+ wined3d_surface_destroy_dc(surface);
+
--sub_resource->map_count;
--texture->resource.map_count;
if (!(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT))
texture->flags &= ~WINED3D_TEXTURE_DC_IN_USE;
- if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY
- || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM
- && surface->resource.map_binding != WINED3D_LOCATION_DIB))
- {
- /* The game Salammbo modifies the surface contents without mapping the surface between
- * a GetDC/ReleaseDC operation and flipping the surface. If the DIB remains the active
- * copy and is copied to the screen, this update, which draws the mouse pointer, is lost.
- * Do not only copy the DIB to the map location, but also make sure the map location is
- * copied back to the DIB in the next getdc call.
- *
- * The same consideration applies to user memory surfaces. */
-
- if (device->d3d_initialized)
- context = context_acquire(device, NULL);
-
- surface_load_location(surface, context, surface->resource.map_binding);
- wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_DIB);
- if (context)
- context_release(context);
- }
-
return WINED3D_OK;
}
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 34df7ff..c0688b5 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -250,6 +250,23 @@ static const struct wined3d_typed_format_info typed_formats[] =
{WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_B8G8R8X8_TYPELESS, "uuu"},
};
+struct wined3d_format_ddi_info
+{
+ enum wined3d_format_id id;
+ D3DDDIFORMAT ddi_format;
+};
+
+static const struct wined3d_format_ddi_info ddi_formats[] =
+{
+ {WINED3DFMT_B8G8R8_UNORM, D3DDDIFMT_R8G8B8},
+ {WINED3DFMT_B8G8R8A8_UNORM, D3DDDIFMT_A8R8G8B8},
+ {WINED3DFMT_B8G8R8X8_UNORM, D3DDDIFMT_X8R8G8B8},
+ {WINED3DFMT_B5G6R5_UNORM, D3DDDIFMT_R5G6B5},
+ {WINED3DFMT_B5G5R5X1_UNORM, D3DDDIFMT_X1R5G5B5},
+ {WINED3DFMT_B5G5R5A1_UNORM, D3DDDIFMT_A1R5G5B5},
+ {WINED3DFMT_P8_UINT, D3DDDIFMT_P8},
+};
+
struct wined3d_format_base_flags
{
enum wined3d_format_id id;
@@ -261,17 +278,6 @@ struct wined3d_format_base_flags
* resource size. */
static const struct wined3d_format_base_flags format_base_flags[] =
{
- {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
- {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
{WINED3DFMT_ATI1N, WINED3DFMT_FLAG_BROKEN_PITCH},
{WINED3DFMT_ATI2N, WINED3DFMT_FLAG_BROKEN_PITCH},
{WINED3DFMT_R11G11B10_FLOAT, WINED3DFMT_FLAG_FLOAT},
@@ -1663,6 +1669,19 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
format_set_flag(format, flags);
}
+ for (i = 0; i < ARRAY_SIZE(ddi_formats); ++i)
+ {
+ int fmt_idx = get_format_idx(ddi_formats[i].id);
+
+ if (fmt_idx == -1)
+ {
+ ERR("Format %s (%#x) not found.\n", debug_d3dformat(ddi_formats[i].id), ddi_formats[i].id);
+ goto fail;
+ }
+
+ gl_info->formats[fmt_idx].ddi_format = ddi_formats[i].ddi_format;
+ }
+
for (i = 0; i < ARRAY_SIZE(format_base_flags); ++i)
{
int fmt_idx = get_format_idx(format_base_flags[i].id);
@@ -5444,7 +5463,6 @@ const char *wined3d_debug_location(DWORD location)
LOCATION_TO_STR(WINED3D_LOCATION_DISCARDED);
LOCATION_TO_STR(WINED3D_LOCATION_SYSMEM);
LOCATION_TO_STR(WINED3D_LOCATION_USER_MEMORY);
- LOCATION_TO_STR(WINED3D_LOCATION_DIB);
LOCATION_TO_STR(WINED3D_LOCATION_BUFFER);
LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_RGB);
LOCATION_TO_STR(WINED3D_LOCATION_TEXTURE_SRGB);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 4f0a9f3..6fd93e9 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -34,6 +34,8 @@
#include <stdarg.h>
#include <math.h>
#include <limits.h>
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#define COBJMACROS
@@ -42,6 +44,8 @@
#include "winreg.h"
#include "wingdi.h"
#include "winuser.h"
+#include "winternl.h"
+#include "ddk/d3dkmthk.h"
#include "wine/debug.h"
#include "wine/unicode.h"
@@ -2553,6 +2557,8 @@ void wined3d_texture_invalidate_location(struct wined3d_texture *texture,
unsigned int sub_resource_idx, DWORD location) DECLSPEC_HIDDEN;
void wined3d_texture_load(struct wined3d_texture *texture,
struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
+void *wined3d_texture_map_bo_address(const struct wined3d_bo_address *data, size_t size,
+ const struct wined3d_gl_info *gl_info, GLenum binding, DWORD flags) DECLSPEC_HIDDEN;
void wined3d_texture_prepare_buffer_object(struct wined3d_texture *texture,
unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
void wined3d_texture_prepare_texture(struct wined3d_texture *texture,
@@ -2562,6 +2568,8 @@ void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture,
void wined3d_texture_set_dirty(struct wined3d_texture *texture) DECLSPEC_HIDDEN;
void wined3d_texture_set_swapchain(struct wined3d_texture *texture,
struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
+void wined3d_texture_unmap_bo_address(const struct wined3d_bo_address *data,
+ const struct wined3d_gl_info *gl_info, GLenum binding) DECLSPEC_HIDDEN;
BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture,
const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
void wined3d_texture_validate_location(struct wined3d_texture *texture,
@@ -2570,13 +2578,12 @@ void wined3d_texture_validate_location(struct wined3d_texture *texture,
#define WINED3D_LOCATION_DISCARDED 0x00000001
#define WINED3D_LOCATION_SYSMEM 0x00000002
#define WINED3D_LOCATION_USER_MEMORY 0x00000004
-#define WINED3D_LOCATION_DIB 0x00000008
-#define WINED3D_LOCATION_BUFFER 0x00000010
-#define WINED3D_LOCATION_TEXTURE_RGB 0x00000020
-#define WINED3D_LOCATION_TEXTURE_SRGB 0x00000040
-#define WINED3D_LOCATION_DRAWABLE 0x00000080
-#define WINED3D_LOCATION_RB_MULTISAMPLE 0x00000100
-#define WINED3D_LOCATION_RB_RESOLVED 0x00000200
+#define WINED3D_LOCATION_BUFFER 0x00000008
+#define WINED3D_LOCATION_TEXTURE_RGB 0x00000010
+#define WINED3D_LOCATION_TEXTURE_SRGB 0x00000020
+#define WINED3D_LOCATION_DRAWABLE 0x00000040
+#define WINED3D_LOCATION_RB_MULTISAMPLE 0x00000080
+#define WINED3D_LOCATION_RB_RESOLVED 0x00000100
const char *wined3d_debug_location(DWORD location) DECLSPEC_HIDDEN;
@@ -2603,13 +2610,6 @@ BOOL wined3d_volume_prepare_location(struct wined3d_volume *volume,
void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context,
const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN;
-struct wined3d_surface_dib
-{
- HBITMAP DIBsection;
- void *bitmap_data;
- UINT bitmap_size;
-};
-
struct wined3d_renderbuffer_entry
{
struct list entry;
@@ -2657,8 +2657,8 @@ struct wined3d_surface
unsigned int texture_layer;
/* For GetDC */
- struct wined3d_surface_dib dib;
- HDC hDC;
+ HBITMAP bitmap;
+ HDC dc;
struct list renderbuffers;
const struct wined3d_renderbuffer_entry *current_renderbuffer;
@@ -2706,7 +2706,8 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
void wined3d_surface_cleanup(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
HRESULT surface_color_fill(struct wined3d_surface *s,
const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN;
-HRESULT surface_create_dib_section(struct wined3d_surface *surface) 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_get_drawable_size(const struct wined3d_surface *surface, const struct wined3d_context *context,
unsigned int *width, unsigned int *height) DECLSPEC_HIDDEN;
HRESULT wined3d_surface_init(struct wined3d_surface *surface,
@@ -2734,7 +2735,6 @@ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3
const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
/* Surface flags: */
-#define SFLAG_DIBSECTION 0x00000001 /* Has a DIB section attached for GetDC. */
#define SFLAG_DISCARD 0x00000002 /* ??? */
struct wined3d_sampler
@@ -3451,6 +3451,7 @@ struct wined3d_format
{
enum wined3d_format_id id;
+ D3DDDIFORMAT ddi_format;
DWORD red_size;
DWORD green_size;
DWORD blue_size;
--
2.1.4
More information about the wine-patches
mailing list