From 9d49b7a9be6d4ed59a69c3453de4eadb0101ea09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Sat, 28 Jun 2014 10:49:32 +0200 Subject: [PATCH] wined3d: Set palettes on the swapchain. --- dlls/ddraw/ddraw_private.h | 2 + dlls/ddraw/palette.c | 4 ++ dlls/ddraw/surface.c | 10 ++-- dlls/ddraw/tests/ddraw1.c | 6 +-- dlls/ddraw/tests/ddraw2.c | 6 +-- dlls/ddraw/tests/ddraw4.c | 6 +-- dlls/ddraw/tests/ddraw7.c | 6 +-- dlls/wined3d/arb_program_shader.c | 2 +- dlls/wined3d/palette.c | 12 ----- dlls/wined3d/surface.c | 89 ++++--------------------------- dlls/wined3d/swapchain.c | 9 ++++ dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 3 +- include/wine/wined3d.h | 2 +- 14 files changed, 44 insertions(+), 115 deletions(-) diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index ac232a388a8..5a7c3c36325 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -200,6 +200,8 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture, struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; ULONG ddraw_surface_release_iface(struct ddraw_surface *This) DECLSPEC_HIDDEN; +HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, + const RECT *rect, BOOL read) DECLSPEC_HIDDEN; static inline struct ddraw_surface *impl_from_IDirect3DTexture(IDirect3DTexture *iface) { diff --git a/dlls/ddraw/palette.c b/dlls/ddraw/palette.c index d04f42606e0..e62f737e434 100644 --- a/dlls/ddraw/palette.c +++ b/dlls/ddraw/palette.c @@ -175,6 +175,10 @@ static HRESULT WINAPI ddraw_palette_SetEntries(IDirectDrawPalette *iface, wined3d_mutex_lock(); hr = wined3d_palette_set_entries(palette->wineD3DPalette, flags, start, count, entries); + + if (SUCCEEDED(hr) && palette->flags & DDPCAPS_PRIMARYSURFACE) + ddraw_surface_update_frontbuffer(palette->ddraw->primary, NULL, FALSE); + wined3d_mutex_unlock(); return hr; diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index f2a656c16a2..6452a9bedd9 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -40,7 +40,7 @@ static inline struct ddraw_surface *impl_from_IDirectDrawGammaControl(IDirectDra * applications from drawing to the screen while we've locked the frontbuffer. * We'd like to do this in wined3d instead, but for that to work wined3d needs * to support windowless rendering first. */ -static HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read) +HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read) { HDC surface_dc, screen_dc; int x, y, w, h; @@ -473,17 +473,15 @@ static HRESULT ddraw_surface_set_palette(struct ddraw_surface *surface, IDirectD prev->flags &= ~DDPCAPS_PRIMARYSURFACE; if (palette_impl) palette_impl->flags |= DDPCAPS_PRIMARYSURFACE; - /* Update the wined3d frontbuffer if this is the primary. */ - if (surface->ddraw->wined3d_frontbuffer) - wined3d_surface_set_palette(surface->ddraw->wined3d_frontbuffer, - palette_impl ? palette_impl->wineD3DPalette : NULL); + wined3d_swapchain_set_palette(surface->ddraw->wined3d_swapchain, + palette_impl ? palette_impl->wineD3DPalette : NULL); + ddraw_surface_update_frontbuffer(surface, NULL, FALSE); } if (palette_impl) IDirectDrawPalette_AddRef(&palette_impl->IDirectDrawPalette_iface); if (prev) IDirectDrawPalette_Release(&prev->IDirectDrawPalette_iface); surface->palette = palette_impl; - wined3d_surface_set_palette(surface->wined3d_surface, palette_impl ? palette_impl->wineD3DPalette : NULL); wined3d_mutex_unlock(); diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 094d0a13da3..ad60606966c 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -4777,10 +4777,10 @@ static void test_p8_rgb_blit(void) HRESULT hr; PALETTEENTRY palette_entries[256]; unsigned int x; - static const BYTE src_data[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80}; + static const BYTE src_data[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80}; static const D3DCOLOR expected[] = { - 0x00000000, 0x00010101, 0x00020202, 0x00030303, + 0x00101010, 0x00010101, 0x00020202, 0x00030303, 0x00040404, 0x00050505, 0x00ffffff, 0x00808080, }; D3DCOLOR color; @@ -4793,10 +4793,10 @@ static void test_p8_rgb_blit(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); memset(palette_entries, 0, sizeof(palette_entries)); - palette_entries[0].peRed = 0xff; palette_entries[1].peGreen = 0xff; palette_entries[2].peBlue = 0xff; palette_entries[3].peFlags = 0xff; + palette_entries[4].peRed = 0xff; hr = IDirectDraw_CreatePalette(ddraw, DDPCAPS_8BIT | DDPCAPS_ALLOW256, palette_entries, &palette, NULL); ok(SUCCEEDED(hr), "Failed to create palette, hr %#x.\n", hr); diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index 9704ce92d18..1a5d9de0cfe 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -5862,10 +5862,10 @@ static void test_p8_rgb_blit(void) HRESULT hr; PALETTEENTRY palette_entries[256]; unsigned int x; - static const BYTE src_data[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80}; + static const BYTE src_data[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80}; static const D3DCOLOR expected[] = { - 0x00000000, 0x00010101, 0x00020202, 0x00030303, + 0x00101010, 0x00010101, 0x00020202, 0x00030303, 0x00040404, 0x00050505, 0x00ffffff, 0x00808080, }; D3DCOLOR color; @@ -5878,10 +5878,10 @@ static void test_p8_rgb_blit(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); memset(palette_entries, 0, sizeof(palette_entries)); - palette_entries[0].peRed = 0xff; palette_entries[1].peGreen = 0xff; palette_entries[2].peBlue = 0xff; palette_entries[3].peFlags = 0xff; + palette_entries[4].peRed = 0xff; hr = IDirectDraw2_CreatePalette(ddraw, DDPCAPS_8BIT | DDPCAPS_ALLOW256, palette_entries, &palette, NULL); ok(SUCCEEDED(hr), "Failed to create palette, hr %#x.\n", hr); diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 28f41bbd960..655fbfbda52 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -6850,10 +6850,10 @@ static void test_p8_rgb_blit(void) HRESULT hr; PALETTEENTRY palette_entries[256]; unsigned int x; - static const BYTE src_data[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80}; + static const BYTE src_data[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80}; static const D3DCOLOR expected[] = { - 0x00000000, 0x00010101, 0x00020202, 0x00030303, + 0x00101010, 0x00010101, 0x00020202, 0x00030303, 0x00040404, 0x00050505, 0x00ffffff, 0x00808080, }; D3DCOLOR color; @@ -6866,10 +6866,10 @@ static void test_p8_rgb_blit(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); memset(palette_entries, 0, sizeof(palette_entries)); - palette_entries[0].peRed = 0xff; palette_entries[1].peGreen = 0xff; palette_entries[2].peBlue = 0xff; palette_entries[3].peFlags = 0xff; + palette_entries[4].peRed = 0xff; hr = IDirectDraw4_CreatePalette(ddraw, DDPCAPS_8BIT | DDPCAPS_ALLOW256, palette_entries, &palette, NULL); ok(SUCCEEDED(hr), "Failed to create palette, hr %#x.\n", hr); diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 3b1553e4745..53c525df819 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -6680,10 +6680,10 @@ static void test_p8_rgb_blit(void) HRESULT hr; PALETTEENTRY palette_entries[256]; unsigned int x; - static const BYTE src_data[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80}; + static const BYTE src_data[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80}; static const D3DCOLOR expected[] = { - 0x00000000, 0x00010101, 0x00020202, 0x00030303, + 0x00101010, 0x00010101, 0x00020202, 0x00030303, 0x00040404, 0x00050505, 0x00ffffff, 0x00808080, }; D3DCOLOR color; @@ -6696,10 +6696,10 @@ static void test_p8_rgb_blit(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); memset(palette_entries, 0, sizeof(palette_entries)); - palette_entries[0].peRed = 0xff; palette_entries[1].peGreen = 0xff; palette_entries[2].peBlue = 0xff; palette_entries[3].peFlags = 0xff; + palette_entries[4].peRed = 0xff; hr = IDirectDraw7_CreatePalette(ddraw, DDPCAPS_8BIT | DDPCAPS_ALLOW256, palette_entries, &palette, NULL); ok(SUCCEEDED(hr), "Failed to create palette, hr %#x.\n", hr); diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index fa15b1e0720..819a04fa218 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -7283,7 +7283,7 @@ static void upload_palette(const struct wined3d_surface *surface, struct wined3d struct wined3d_device *device = surface->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; struct arbfp_blit_priv *priv = device->blit_priv; - const struct wined3d_palette *palette = surface->palette; + const struct wined3d_palette *palette = surface->swapchain ? surface->swapchain->palette : NULL; if (!priv->palette_texture) gl_info->gl_ops.gl.p_glGenTextures(1, &priv->palette_texture); diff --git a/dlls/wined3d/palette.c b/dlls/wined3d/palette.c index 24b344cf543..1ebeb115684 100644 --- a/dlls/wined3d/palette.c +++ b/dlls/wined3d/palette.c @@ -92,7 +92,6 @@ void CDECL wined3d_palette_apply_to_dc(const struct wined3d_palette *palette, HD HRESULT CDECL wined3d_palette_set_entries(struct wined3d_palette *palette, DWORD flags, DWORD start, DWORD count, const PALETTEENTRY *entries) { - struct wined3d_resource *resource; unsigned int i; TRACE("palette %p, flags %#x, start %u, count %u, entries %p.\n", @@ -130,17 +129,6 @@ HRESULT CDECL wined3d_palette_set_entries(struct wined3d_palette *palette, } } - /* If the palette is attached to the render target, update all render targets */ - LIST_FOR_EACH_ENTRY(resource, &palette->device->resources, struct wined3d_resource, resource_list_entry) - { - if (resource->type == WINED3D_RTYPE_SURFACE) - { - struct wined3d_surface *surface = surface_from_resource(resource); - if (surface->palette == palette) - surface->surface_ops->surface_realize_palette(surface); - } - } - return WINED3D_OK; } diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index ce9563130f9..5cd245eb9fa 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -498,7 +498,6 @@ static HRESULT surface_create_dib_section(struct wined3d_surface *surface) /* Now allocate a DC. */ surface->hDC = CreateCompatibleDC(0); SelectObject(surface->hDC, surface->dib.DIBsection); - TRACE("Using wined3d palette %p.\n", surface->palette); surface->flags |= SFLAG_DIBSECTION; @@ -754,44 +753,6 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface) return WINED3D_OK; } -static void surface_realize_palette(struct wined3d_surface *surface) -{ - struct wined3d_palette *palette = surface->palette; - - TRACE("surface %p.\n", surface); - - if (!palette) return; - - if (surface->resource.format->id == WINED3DFMT_P8_UINT - || surface->resource.format->id == WINED3DFMT_P8_UINT_A8_UNORM) - { - if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET) - { - /* Make sure the texture is up to date. This call doesn't do - * anything if the texture is already up to date. */ - surface_load_location(surface, WINED3D_LOCATION_TEXTURE_RGB); - - /* We want to force a palette refresh, so mark the drawable as not being up to date */ - if (!surface_is_offscreen(surface)) - surface_invalidate_location(surface, WINED3D_LOCATION_DRAWABLE); - } - else - { - if (!(surface->locations & surface->map_binding)) - { - TRACE("Palette changed with surface that does not have an up to date system memory copy.\n"); - surface_prepare_map_memory(surface); - surface_load_location(surface, surface->map_binding); - } - surface_invalidate_location(surface, ~surface->map_binding); - } - } - - /* Propagate the changes to the drawable when we have a palette. */ - if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET) - surface_load_location(surface, surface->draw_binding); -} - static void surface_unmap(struct wined3d_surface *surface) { struct wined3d_device *device = surface->resource.device; @@ -1098,15 +1059,18 @@ static BOOL surface_convert_color_to_float(const struct wined3d_surface *surface DWORD color, struct wined3d_color *float_color) { const struct wined3d_format *format = surface->resource.format; + const struct wined3d_palette *palette; switch (format->id) { case WINED3DFMT_P8_UINT: - if (surface->palette) + palette = surface->swapchain ? surface->swapchain->palette : NULL; + + if (palette) { - float_color->r = surface->palette->colors[color].rgbRed / 255.0f; - float_color->g = surface->palette->colors[color].rgbGreen / 255.0f; - float_color->b = surface->palette->colors[color].rgbBlue / 255.0f; + float_color->r = palette->colors[color].rgbRed / 255.0f; + float_color->g = palette->colors[color].rgbGreen / 255.0f; + float_color->b = palette->colors[color].rgbBlue / 255.0f; } else { @@ -1320,7 +1284,6 @@ static const struct wined3d_resource_ops surface_resource_ops = static const struct wined3d_surface_ops surface_ops = { surface_private_setup, - surface_realize_palette, surface_unmap, }; @@ -1365,24 +1328,6 @@ static HRESULT gdi_surface_private_setup(struct wined3d_surface *surface) return WINED3D_OK; } -static void gdi_surface_realize_palette(struct wined3d_surface *surface) -{ - struct wined3d_palette *palette = surface->palette; - - TRACE("surface %p.\n", surface); - - if (!palette) return; - - /* Update the image because of the palette change. Some games like e.g. - * Red Alert call SetEntries a lot to implement fading. */ - /* Tell the swapchain to update the screen. */ - if (surface->swapchain && surface == surface->swapchain->front_buffer) - { - wined3d_palette_apply_to_dc(palette, surface->hDC); - x11_copy_to_screen(surface->swapchain, NULL); - } -} - static void gdi_surface_unmap(struct wined3d_surface *surface) { TRACE("surface %p.\n", surface); @@ -1397,7 +1342,6 @@ static void gdi_surface_unmap(struct wined3d_surface *surface) static const struct wined3d_surface_ops gdi_surface_ops = { gdi_surface_private_setup, - gdi_surface_realize_palette, gdi_surface_unmap, }; @@ -2346,21 +2290,6 @@ HRESULT CDECL wined3d_surface_restore(struct wined3d_surface *surface) return WINED3D_OK; } -void CDECL wined3d_surface_set_palette(struct wined3d_surface *surface, struct wined3d_palette *palette) -{ - TRACE("surface %p, palette %p.\n", surface, palette); - - if (surface->palette == palette) - { - TRACE("Nop palette change.\n"); - return; - } - - surface->palette = palette; - if (palette) - surface->surface_ops->surface_realize_palette(surface); -} - DWORD CDECL wined3d_surface_get_pitch(const struct wined3d_surface *surface) { unsigned int alignment; @@ -3388,10 +3317,10 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI } case WINED3D_CT_PALETTED: - if (surface->palette) + if (surface->swapchain && surface->swapchain->palette) { unsigned int x, y; - const struct wined3d_palette *palette = surface->palette; + const struct wined3d_palette *palette = surface->swapchain->palette; for (y = 0; y < height; y++) { source = src + pitch * y; diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 75e6628c0c1..bf0bbc67b90 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -258,6 +258,12 @@ HRESULT CDECL wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain *s return WINED3D_OK; } +void CDECL wined3d_swapchain_set_palette(struct wined3d_swapchain *swapchain, struct wined3d_palette *palette) +{ + TRACE("swapchain %p, palette %p.\n", swapchain, palette); + swapchain->palette = palette; +} + HRESULT CDECL wined3d_swapchain_get_gamma_ramp(const struct wined3d_swapchain *swapchain, struct wined3d_gamma_ramp *ramp) { @@ -619,6 +625,9 @@ void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *r TRACE("swapchain %p, rect %s.\n", swapchain, wine_dbgstr_rect(rect)); + if (swapchain->palette) + wined3d_palette_apply_to_dc(swapchain->palette, swapchain->front_buffer->hDC); + front = swapchain->front_buffer; if (front->resource.map_count) ERR("Trying to blit a mapped surface.\n"); diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index f1a45ddf43a..1a41f8c107a 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -221,7 +221,6 @@ @ cdecl wined3d_surface_releasedc(ptr ptr) @ cdecl wined3d_surface_restore(ptr) @ cdecl wined3d_surface_set_overlay_position(ptr long long) -@ cdecl wined3d_surface_set_palette(ptr ptr) @ cdecl wined3d_surface_set_priority(ptr long) @ cdecl wined3d_surface_unmap(ptr) @ cdecl wined3d_surface_update_desc(ptr long long long long long ptr long) @@ -241,6 +240,7 @@ @ cdecl wined3d_swapchain_incref(ptr) @ cdecl wined3d_swapchain_present(ptr ptr ptr ptr ptr long) @ cdecl wined3d_swapchain_set_gamma_ramp(ptr long ptr) +@ cdecl wined3d_swapchain_set_palette(ptr ptr) @ cdecl wined3d_swapchain_set_window(ptr ptr) @ cdecl wined3d_texture_add_dirty_region(ptr long ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index b1c70891989..8f411cda92c 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2212,7 +2212,6 @@ struct fbo_entry struct wined3d_surface_ops { HRESULT (*surface_private_setup)(struct wined3d_surface *surface); - void (*surface_realize_palette)(struct wined3d_surface *surface); void (*surface_unmap)(struct wined3d_surface *surface); }; @@ -2222,7 +2221,6 @@ struct wined3d_surface const struct wined3d_surface_ops *surface_ops; struct wined3d_texture *container; struct wined3d_swapchain *swapchain; - struct wined3d_palette *palette; /* D3D7 style palette handling */ DWORD draw_binding, map_binding; void *user_memory; DWORD locations; @@ -2622,6 +2620,7 @@ struct wined3d_swapchain struct wined3d_gamma_ramp orig_gamma; BOOL render_to_fbo; const struct wined3d_format *ds_format; + struct wined3d_palette *palette; LONG prev_time, frames; /* Performance tracking */ diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index f21abaf6a73..0695a8127ab 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2414,7 +2414,6 @@ void __cdecl wined3d_surface_preload(struct wined3d_surface *surface); HRESULT __cdecl wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc); HRESULT __cdecl wined3d_surface_restore(struct wined3d_surface *surface); HRESULT __cdecl wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y); -void __cdecl wined3d_surface_set_palette(struct wined3d_surface *surface, struct wined3d_palette *palette); DWORD __cdecl wined3d_surface_set_priority(struct wined3d_surface *surface, DWORD new_priority); HRESULT __cdecl wined3d_surface_unmap(struct wined3d_surface *surface); HRESULT __cdecl wined3d_surface_update_desc(struct wined3d_surface *surface, @@ -2449,6 +2448,7 @@ HRESULT __cdecl wined3d_swapchain_present(struct wined3d_swapchain *swapchain, const RGNDATA *dirty_region, DWORD flags); HRESULT __cdecl wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain *swapchain, DWORD flags, const struct wined3d_gamma_ramp *ramp); +void __cdecl wined3d_swapchain_set_palette(struct wined3d_swapchain *swapchain, struct wined3d_palette *palette); void __cdecl wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWND window); HRESULT __cdecl wined3d_texture_add_dirty_region(struct wined3d_texture *texture,