[PATCH 4/5] wined3d: Store palettes in textures instead of in surfaces.
Stefan Dösinger
stefan at codeweavers.com
Thu Apr 24 05:10:14 CDT 2014
Since palettes only really matter on frontbuffers we could also consider
removing them from wined3d entirely and performing the ddraw frontbuffer
present with a d3d draw and d3d shaders. This would mean that the shadow
frontbuffer remains in ddraw, and that Shader Model 2 cards are required
for hardware P8 conversion. (Unless we implement full d3d shader support
for older HW, which I consider unlikely.)
---
dlls/ddraw/ddraw.c | 4 ++-
dlls/ddraw/ddraw_private.h | 1 +
dlls/ddraw/device.c | 2 +-
dlls/ddraw/surface.c | 16 ++++++------
dlls/wined3d/palette.c | 10 +++++---
dlls/wined3d/surface.c | 55 ++++++++++++++----------------------------
dlls/wined3d/texture.c | 37 ++++++++++++++++++++++++++++
dlls/wined3d/utils.c | 9 ++++---
dlls/wined3d/wined3d.spec | 3 +--
dlls/wined3d/wined3d_private.h | 5 +++-
include/wine/wined3d.h | 3 +--
11 files changed, 85 insertions(+), 60 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index aa74a1e..3a43618 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -364,6 +364,8 @@ void ddraw_destroy_swapchain(struct ddraw *ddraw)
{
TRACE("Destroying the swapchain.\n");
+ wined3d_texture_decref(ddraw->wined3d_frontbuffer_texture);
+ ddraw->wined3d_frontbuffer_texture = NULL;
wined3d_swapchain_decref(ddraw->wined3d_swapchain);
ddraw->wined3d_swapchain = NULL;
@@ -4815,8 +4817,8 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic
*surface = wined3d_surface_from_resource(wined3d_texture_get_sub_resource(texture, 0));
ddraw->wined3d_frontbuffer = *surface;
+ ddraw->wined3d_frontbuffer_texture = texture;
wined3d_surface_incref(*surface);
- wined3d_texture_decref(texture);
return hr;
}
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 2bf8132..e9a46db 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -80,6 +80,7 @@ struct ddraw
struct ddraw_surface *primary;
RECT primary_lock;
+ struct wined3d_texture *wined3d_frontbuffer_texture;
struct wined3d_surface *wined3d_frontbuffer;
struct wined3d_swapchain *wined3d_swapchain;
HWND swapchain_window;
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index e6f40a0..31655ec 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -1802,7 +1802,7 @@ static BOOL validate_surface_palette(struct ddraw_surface *surface)
& (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2
| DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8
| DDPF_PALETTEINDEXEDTO8))
- || wined3d_surface_get_palette(surface->wined3d_surface);
+ || surface->palette;
}
static HRESULT d3d_device_set_render_target(struct d3d_device *device,
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index b561af4..a3a13f0 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -469,7 +469,7 @@ static HRESULT WINAPI ddraw_surface_set_palette(struct ddraw_surface *surface, I
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,
+ wined3d_texture_set_palette(surface->ddraw->wined3d_frontbuffer_texture,
palette_impl ? palette_impl->wineD3DPalette : NULL);
}
if (palette_impl)
@@ -477,7 +477,8 @@ static HRESULT WINAPI ddraw_surface_set_palette(struct ddraw_surface *surface, I
if (prev)
IDirectDrawPalette_Release(&prev->IDirectDrawPalette_iface);
surface->palette = palette_impl;
- wined3d_surface_set_palette(surface->wined3d_surface, palette_impl ? palette_impl->wineD3DPalette : NULL);
+ if (surface->wined3d_texture)
+ wined3d_texture_set_palette(surface->wined3d_texture, palette_impl ? palette_impl->wineD3DPalette : NULL);
wined3d_mutex_unlock();
@@ -4975,7 +4976,6 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
for (;;)
{
- struct wined3d_palette *wined3d_dst_pal, *wined3d_src_pal;
DDSURFACEDESC *src_desc, *dst_desc;
TRACE("Copying surface %p to surface %p (mipmap level %d).\n",
@@ -4984,19 +4984,19 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
/* Suppress the ALLOCONLOAD flag */
dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
- /* Get the palettes */
- wined3d_dst_pal = wined3d_surface_get_palette(dst_surface->wined3d_surface);
- wined3d_src_pal = wined3d_surface_get_palette(src_surface->wined3d_surface);
- if (wined3d_src_pal)
+ if (src_surface->palette)
{
+ struct wined3d_palette *wined3d_dst_pal, *wined3d_src_pal;
PALETTEENTRY palent[256];
- if (!wined3d_dst_pal)
+ if (!dst_surface->palette)
{
wined3d_mutex_unlock();
return DDERR_NOPALETTEATTACHED;
}
+ wined3d_src_pal = src_surface->palette->wineD3DPalette;
+ wined3d_dst_pal = dst_surface->palette->wineD3DPalette;
wined3d_palette_get_entries(wined3d_src_pal, 0, 0, 256, palent);
wined3d_palette_set_entries(wined3d_dst_pal, 0, 0, 256, palent);
}
diff --git a/dlls/wined3d/palette.c b/dlls/wined3d/palette.c
index e659952..28fc650 100644
--- a/dlls/wined3d/palette.c
+++ b/dlls/wined3d/palette.c
@@ -119,11 +119,13 @@ 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)
+ enum wined3d_resource_type type = resource->type;
+ if (type == WINED3D_RTYPE_TEXTURE || type == WINED3D_RTYPE_CUBE_TEXTURE
+ || type == WINED3D_RTYPE_VOLUME_TEXTURE)
{
- struct wined3d_surface *surface = surface_from_resource(resource);
- if (surface->palette == palette)
- surface->surface_ops->surface_realize_palette(surface);
+ struct wined3d_texture *texture = wined3d_texture_from_resource(resource);
+ if (texture->palette == palette)
+ wined3d_texture_realize_palette(texture);
}
}
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 680a815..657bb16 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -391,6 +391,7 @@ static HRESULT surface_create_dib_section(struct wined3d_surface *surface)
BITMAPINFO *b_info;
int extraline = 0;
DWORD *masks;
+ const struct wined3d_palette *palette = surface->container->palette;
TRACE("surface %p.\n", surface);
@@ -498,8 +499,8 @@ 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);
- SelectPalette(surface->hDC, surface->palette ? surface->palette->hpal : 0, FALSE);
+ TRACE("Using wined3d palette %p.\n", palette);
+ SelectPalette(surface->hDC, palette ? palette->hpal : 0, FALSE);
surface->flags |= SFLAG_DIBSECTION;
@@ -757,7 +758,7 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface)
static void surface_realize_palette(struct wined3d_surface *surface)
{
- struct wined3d_palette *palette = surface->palette;
+ struct wined3d_palette *palette = surface->container->palette;
TRACE("surface %p.\n", surface);
@@ -1117,15 +1118,17 @@ static BOOL surface_convert_color_to_float(const struct wined3d_surface *surface
{
const struct wined3d_format *format = surface->resource.format;
const struct wined3d_device *device = surface->resource.device;
+ struct wined3d_palette *palette;
switch (format->id)
{
case WINED3DFMT_P8_UINT:
- if (surface->palette)
+ palette = surface->container->palette;
+ if (palette)
{
- float_color->r = surface->palette->palents[color].peRed / 255.0f;
- float_color->g = surface->palette->palents[color].peGreen / 255.0f;
- float_color->b = surface->palette->palents[color].peBlue / 255.0f;
+ float_color->r = palette->palents[color].peRed / 255.0f;
+ float_color->g = palette->palents[color].peGreen / 255.0f;
+ float_color->b = palette->palents[color].peBlue / 255.0f;
}
else
{
@@ -1386,7 +1389,7 @@ static HRESULT gdi_surface_private_setup(struct wined3d_surface *surface)
static void gdi_surface_realize_palette(struct wined3d_surface *surface)
{
- struct wined3d_palette *palette = surface->palette;
+ struct wined3d_palette *palette = surface->container->palette;
TRACE("surface %p.\n", surface);
@@ -2389,28 +2392,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);
-}
-
-struct wined3d_palette * CDECL wined3d_surface_get_palette(const struct wined3d_surface *surface)
-{
- TRACE("surface %p.\n", surface);
-
- return surface->palette;
-}
-
DWORD CDECL wined3d_surface_get_pitch(const struct wined3d_surface *surface)
{
unsigned int alignment;
@@ -3180,17 +3161,17 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc)
* surfaces (with non-device palettes). */
const PALETTEENTRY *pal = NULL;
- if (surface->palette)
+ if (surface->container->palette)
{
- pal = surface->palette->palents;
+ pal = surface->container->palette->palents;
}
else
{
struct wined3d_swapchain *swapchain = surface->resource.device->swapchains[0];
struct wined3d_surface *dds_primary = swapchain->front_buffer;
- if (dds_primary && dds_primary->palette)
- pal = dds_primary->palette->palents;
+ if (dds_primary && dds_primary->container->palette)
+ pal = dds_primary->container->palette->palents;
}
if (pal)
@@ -3411,9 +3392,9 @@ static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_loc
DWORD width = pitch / 3;
int x, y, c;
- if (surface->palette)
+ if (surface->container->palette)
{
- pal = surface->palette->palents;
+ pal = surface->container->palette->palents;
}
else
{
@@ -3553,7 +3534,7 @@ static BOOL color_in_range(const struct wined3d_color_key *color_key, DWORD colo
void d3dfmt_p8_init_palette(const struct wined3d_surface *surface, BYTE table[256][4], BOOL colorkey)
{
const struct wined3d_device *device = surface->resource.device;
- const struct wined3d_palette *pal = surface->palette;
+ const struct wined3d_palette *pal = surface->container->palette;
BOOL index_in_alpha = FALSE;
unsigned int i;
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 4291fd0..b9e571e 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -684,6 +684,30 @@ HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture,
return WINED3D_OK;
}
+void wined3d_texture_realize_palette(struct wined3d_texture *texture)
+{
+ UINT i, sub_count = texture->level_count * texture->layer_count;
+
+ for (i = 0; i < sub_count; ++i)
+ texture->texture_ops->texture_realize_palette(texture->sub_resources[i]);
+}
+
+void CDECL wined3d_texture_set_palette(struct wined3d_texture *texture,
+ struct wined3d_palette *palette)
+{
+ TRACE("texture %p, palette %p.\n", texture, palette);
+
+ if (texture->palette == palette)
+ {
+ TRACE("Nop palette change.\n");
+ return;
+ }
+
+ texture->palette = palette;
+ if (palette)
+ wined3d_texture_realize_palette(texture);
+}
+
void CDECL wined3d_texture_generate_mipmaps(struct wined3d_texture *texture)
{
/* TODO: Implement filters using GL_SGI_generate_mipmaps. */
@@ -748,11 +772,18 @@ static void texture2d_sub_resource_cleanup(struct wined3d_resource *sub_resource
wined3d_surface_decref(surface);
}
+static void texture2d_sub_resource_realize_palette(struct wined3d_resource *sub_resource)
+{
+ struct wined3d_surface *surface = surface_from_resource(sub_resource);
+ surface->surface_ops->surface_realize_palette(surface);
+}
+
static const struct wined3d_texture_ops texture2d_ops =
{
texture2d_sub_resource_load,
texture2d_sub_resource_add_dirty_region,
texture2d_sub_resource_cleanup,
+ texture2d_sub_resource_realize_palette,
};
static void wined3d_texture_unload(struct wined3d_resource *resource)
@@ -1071,11 +1102,17 @@ static void texture3d_sub_resource_cleanup(struct wined3d_resource *sub_resource
wined3d_volume_decref(volume);
}
+static void texture3d_sub_resource_realize_palette(struct wined3d_resource *sub_resource)
+{
+ FIXME("Palettized volumes are not implemented.\n");
+}
+
static const struct wined3d_texture_ops texture3d_ops =
{
texture3d_sub_resource_load,
texture3d_sub_resource_add_dirty_region,
texture3d_sub_resource_cleanup,
+ texture3d_sub_resource_realize_palette,
};
static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 78060e2..dee84aa 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -3089,10 +3089,11 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, c
if (format->id == WINED3DFMT_P8_UINT)
{
- PALETTEENTRY *e;
+ const PALETTEENTRY *e;
BYTE r, g, b, a;
+ const struct wined3d_palette *palette = surface->container->palette;
- if (!surface->palette)
+ if (!palette)
{
WARN("Surface doesn't have a palette, returning 0.\n");
return 0;
@@ -3103,7 +3104,7 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, c
b = (BYTE)((color->b * 255.0f) + 0.5f);
a = (BYTE)((color->a * 255.0f) + 0.5f);
- e = &surface->palette->palents[a];
+ e = &palette->palents[a];
if (e->peRed == r && e->peGreen == g && e->peBlue == b)
return a;
@@ -3111,7 +3112,7 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, c
for (i = 0; i < 256; ++i)
{
- e = &surface->palette->palents[i];
+ e = &palette->palents[i];
if (e->peRed == r && e->peGreen == g && e->peBlue == b)
return i;
}
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 99cf6bf..e01c3b1 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -207,7 +207,6 @@
@ cdecl wined3d_surface_get_blt_status(ptr long)
@ cdecl wined3d_surface_get_flip_status(ptr long)
@ cdecl wined3d_surface_get_overlay_position(ptr ptr ptr)
-@ cdecl wined3d_surface_get_palette(ptr)
@ cdecl wined3d_surface_get_parent(ptr)
@ cdecl wined3d_surface_get_pitch(ptr)
@ cdecl wined3d_surface_get_priority(ptr)
@@ -221,7 +220,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)
@@ -258,6 +256,7 @@
@ cdecl wined3d_texture_preload(ptr)
@ cdecl wined3d_texture_set_autogen_filter_type(ptr long)
@ cdecl wined3d_texture_set_color_key(ptr long ptr)
+@ cdecl wined3d_texture_set_palette(ptr ptr)
@ cdecl wined3d_texture_set_lod(ptr long)
@ cdecl wined3d_texture_set_priority(ptr long)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 7e67f1e..25b9ac4 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2083,6 +2083,7 @@ struct wined3d_texture_ops
void (*texture_sub_resource_add_dirty_region)(struct wined3d_resource *sub_resource,
const struct wined3d_box *dirty_region);
void (*texture_sub_resource_cleanup)(struct wined3d_resource *sub_resource);
+ void (*texture_realize_palette)(struct wined3d_resource *sub_resource);
};
#define WINED3D_TEXTURE_COND_NP2 0x00000001
@@ -2114,6 +2115,8 @@ struct wined3d_texture
struct wined3d_color_key dst_overlay_color_key;
struct wined3d_color_key src_overlay_color_key;
DWORD color_key_flags;
+
+ struct wined3d_palette *palette;
};
static inline struct wined3d_texture *wined3d_texture_from_resource(struct wined3d_resource *resource)
@@ -2136,6 +2139,7 @@ void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture,
struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
void wined3d_texture_load(struct wined3d_texture *texture,
struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
+void wined3d_texture_realize_palette(struct wined3d_texture *texture) DECLSPEC_HIDDEN;
void wined3d_texture_set_dirty(struct wined3d_texture *texture) DECLSPEC_HIDDEN;
#define WINED3D_VFLAG_ALLOCATED 0x00000001
@@ -2220,7 +2224,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;
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 56bedce..806a2c8 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2397,7 +2397,6 @@ struct wined3d_surface * __cdecl wined3d_surface_from_resource(struct wined3d_re
HRESULT __cdecl wined3d_surface_get_blt_status(const struct wined3d_surface *surface, DWORD flags);
HRESULT __cdecl wined3d_surface_get_flip_status(const struct wined3d_surface *surface, DWORD flags);
HRESULT __cdecl wined3d_surface_get_overlay_position(const struct wined3d_surface *surface, LONG *x, LONG *y);
-struct wined3d_palette * __cdecl wined3d_surface_get_palette(const struct wined3d_surface *surface);
void * __cdecl wined3d_surface_get_parent(const struct wined3d_surface *surface);
DWORD __cdecl wined3d_surface_get_pitch(const struct wined3d_surface *surface);
DWORD __cdecl wined3d_surface_get_priority(const struct wined3d_surface *surface);
@@ -2413,7 +2412,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,
@@ -2472,6 +2470,7 @@ HRESULT __cdecl wined3d_texture_set_autogen_filter_type(struct wined3d_texture *
HRESULT __cdecl wined3d_texture_set_color_key(struct wined3d_texture *texture,
DWORD flags, const struct wined3d_color_key *color_key);
DWORD __cdecl wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod);
+void __cdecl wined3d_texture_set_palette(struct wined3d_texture *texture, struct wined3d_palette *palette);
DWORD __cdecl wined3d_texture_set_priority(struct wined3d_texture *texture, DWORD priority);
HRESULT __cdecl wined3d_vertex_declaration_create(struct wined3d_device *device,
--
1.8.3.2
More information about the wine-patches
mailing list