wined3d: Get rid of wined3d_select_blitter().

Instead, chain the blitters themselves. This also fixes the issue that
currently only a single blitter can store extra data in the "blit_priv" field
of struct wined3d_device.

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Henri Verbeet 2017-04-04 09:07:43 +02:00 committed by Alexandre Julliard
parent 4b8c0d8784
commit cad4badbcf
7 changed files with 314 additions and 288 deletions

View File

@ -6879,8 +6879,9 @@ struct arbfp_blit_desc
#define ARBFP_BLIT_PARAM_COLOR_KEY_LOW 1
#define ARBFP_BLIT_PARAM_COLOR_KEY_HIGH 2
struct arbfp_blit_priv
struct wined3d_arbfp_blitter
{
struct wined3d_blitter blitter;
struct wine_rb_tree shaders;
GLuint palette_texture;
};
@ -6894,44 +6895,39 @@ static int arbfp_blit_type_compare(const void *key, const struct wine_rb_entry *
}
/* Context activation is done by the caller. */
static void arbfp_free_blit_shader(struct wine_rb_entry *entry, void *context)
static void arbfp_free_blit_shader(struct wine_rb_entry *entry, void *ctx)
{
const struct wined3d_gl_info *gl_info = context;
struct arbfp_blit_desc *entry_arb = WINE_RB_ENTRY_VALUE(entry, struct arbfp_blit_desc, entry);
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
context = ctx;
gl_info = context->gl_info;
GL_EXTCALL(glDeleteProgramsARB(1, &entry_arb->shader));
checkGLcall("glDeleteProgramsARB(1, &entry_arb->shader)");
HeapFree(GetProcessHeap(), 0, entry_arb);
}
static HRESULT arbfp_blit_alloc(struct wined3d_device *device)
{
struct arbfp_blit_priv *priv;
if (!(priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv))))
return E_OUTOFMEMORY;
wine_rb_init(&priv->shaders, arbfp_blit_type_compare);
device->blit_priv = priv;
return WINED3D_OK;
}
/* Context activation is done by the caller. */
static void arbfp_blit_free(struct wined3d_device *device)
static void arbfp_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct arbfp_blit_priv *priv = device->blit_priv;
const struct wined3d_gl_info *gl_info = context->gl_info;
struct wined3d_arbfp_blitter *arbfp_blitter;
struct wined3d_blitter *next;
wine_rb_destroy(&priv->shaders, arbfp_free_blit_shader, &device->adapter->gl_info);
if ((next = blitter->next))
next->ops->blitter_destroy(next, context);
arbfp_blitter = CONTAINING_RECORD(blitter, struct wined3d_arbfp_blitter, blitter);
wine_rb_destroy(&arbfp_blitter->shaders, arbfp_free_blit_shader, context);
checkGLcall("Delete blit programs");
if (priv->palette_texture)
gl_info->gl_ops.gl.p_glDeleteTextures(1, &priv->palette_texture);
if (arbfp_blitter->palette_texture)
gl_info->gl_ops.gl.p_glDeleteTextures(1, &arbfp_blitter->palette_texture);
HeapFree(GetProcessHeap(), 0, device->blit_priv);
device->blit_priv = NULL;
HeapFree(GetProcessHeap(), 0, arbfp_blitter);
}
static BOOL gen_planar_yuv_read(struct wined3d_string_buffer *buffer, const struct arbfp_blit_type *type,
@ -7358,18 +7354,17 @@ static GLuint gen_p8_shader(const struct wined3d_gl_info *gl_info, const struct
}
/* Context activation is done by the caller. */
static void upload_palette(const struct wined3d_texture *texture, struct wined3d_context *context)
static void upload_palette(struct wined3d_arbfp_blitter *blitter,
const struct wined3d_texture *texture, struct wined3d_context *context)
{
const struct wined3d_palette *palette = texture->swapchain ? texture->swapchain->palette : NULL;
struct wined3d_device *device = texture->resource.device;
const struct wined3d_gl_info *gl_info = context->gl_info;
struct arbfp_blit_priv *priv = device->blit_priv;
if (!priv->palette_texture)
gl_info->gl_ops.gl.p_glGenTextures(1, &priv->palette_texture);
if (!blitter->palette_texture)
gl_info->gl_ops.gl.p_glGenTextures(1, &blitter->palette_texture);
GL_EXTCALL(glActiveTexture(GL_TEXTURE1));
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, priv->palette_texture);
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, blitter->palette_texture);
gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@ -7573,11 +7568,10 @@ static GLuint arbfp_gen_plain_shader(const struct wined3d_gl_info *gl_info, cons
}
/* Context activation is done by the caller. */
static HRESULT arbfp_blit_set(void *blit_priv, struct wined3d_context *context, const struct wined3d_surface *surface,
const struct wined3d_color_key *color_key)
static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wined3d_context *context,
const struct wined3d_surface *surface, const struct wined3d_color_key *color_key)
{
const struct wined3d_texture *texture = surface->container;
struct arbfp_blit_priv *priv = blit_priv;
enum complex_fixup fixup;
const struct wined3d_gl_info *gl_info = context->gl_info;
struct wine_rb_entry *entry;
@ -7627,8 +7621,7 @@ static HRESULT arbfp_blit_set(void *blit_priv, struct wined3d_context *context,
type.use_color_key = !!color_key;
type.padding = 0;
entry = wine_rb_get(&priv->shaders, &type);
if (entry)
if ((entry = wine_rb_get(&blitter->shaders, &type)))
{
desc = WINE_RB_ENTRY_VALUE(entry, struct arbfp_blit_desc, entry);
shader = desc->shader;
@ -7667,7 +7660,7 @@ static HRESULT arbfp_blit_set(void *blit_priv, struct wined3d_context *context,
desc->type = type;
desc->shader = shader;
if (wine_rb_put(&priv->shaders, &desc->type, &desc->entry) == -1)
if (wine_rb_put(&blitter->shaders, &desc->type, &desc->entry) == -1)
{
err_out:
ERR("Out of memory\n");
@ -7681,7 +7674,7 @@ err_out:
}
if (fixup == COMPLEX_FIXUP_P8)
upload_palette(texture, context);
upload_palette(blitter, texture, context);
gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB);
checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB)");
@ -7711,8 +7704,8 @@ static void arbfp_blit_unset(const struct wined3d_gl_info *gl_info)
static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info,
const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op,
const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
enum wined3d_pool src_pool, const struct wined3d_format *src_format,
enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
{
enum complex_fixup src_fixup;
BOOL decompress;
@ -7786,16 +7779,31 @@ static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info,
}
}
static void arbfp_blit_surface(struct wined3d_device *device, enum wined3d_blit_op op, struct wined3d_context *context,
struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect,
struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect,
static void arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op,
struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location,
const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect,
const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter)
{
struct wined3d_texture *src_texture = src_surface->container;
struct wined3d_texture *dst_texture = dst_surface->container;
struct wined3d_device *device = dst_texture->resource.device;
struct wined3d_arbfp_blitter *arbfp_blitter;
struct wined3d_color_key alpha_test_key;
struct wined3d_blitter *next;
RECT s, d;
if (!arbfp_blit_supported(&device->adapter->gl_info, &device->adapter->d3d_info, op,
src_texture->resource.pool, src_texture->resource.format,
dst_texture->resource.pool, dst_texture->resource.format))
{
if ((next = blitter->next))
next->ops->blitter_blit(next, op, context, src_surface, src_location,
src_rect, dst_surface, dst_location, dst_rect, color_key, filter);
return;
}
arbfp_blitter = CONTAINING_RECORD(blitter, struct wined3d_arbfp_blitter, blitter);
/* Now load the surface */
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
&& (surface_get_sub_resource(src_surface)->locations
@ -7855,7 +7863,7 @@ static void arbfp_blit_surface(struct wined3d_device *device, enum wined3d_blit_
color_key = &alpha_test_key;
}
arbfp_blit_set(device->blit_priv, context, src_surface, color_key);
arbfp_blit_set(arbfp_blitter, context, src_surface, color_key);
/* Draw a textured quad */
draw_textured_quad(src_surface, context, src_rect, dst_rect, filter);
@ -7868,17 +7876,46 @@ static void arbfp_blit_surface(struct wined3d_device *device, enum wined3d_blit_
context->gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
}
static void arbfp_blit_clear(struct wined3d_device *device, struct wined3d_rendertarget_view *view,
const RECT *rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil)
static void arbfp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device,
struct wined3d_rendertarget_view *view, const RECT *rect, DWORD flags,
const struct wined3d_color *colour, float depth, DWORD stencil)
{
ERR("This blitter does not implement clears.\n");
struct wined3d_blitter *next;
if ((next = blitter->next))
next->ops->blitter_clear(next, device, view, rect, flags, colour, depth, stencil);
}
const struct wined3d_blitter_ops arbfp_blit =
static const struct wined3d_blitter_ops arbfp_blitter_ops =
{
arbfp_blit_alloc,
arbfp_blit_free,
arbfp_blit_supported,
arbfp_blit_clear,
arbfp_blit_surface,
arbfp_blitter_destroy,
arbfp_blitter_clear,
arbfp_blitter_blit,
};
void wined3d_arbfp_blitter_create(struct wined3d_blitter **next, const struct wined3d_device *device)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct wined3d_arbfp_blitter *blitter;
if (device->shader_backend != &arb_program_shader_backend
&& device->shader_backend != &glsl_shader_backend)
return;
if (!gl_info->supported[ARB_FRAGMENT_PROGRAM])
return;
if (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter))))
{
ERR("Failed to allocate blitter.\n");
return;
}
TRACE("Created blitter %p.\n", blitter);
blitter->blitter.ops = &arbfp_blitter_ops;
blitter->blitter.next = *next;
wine_rb_init(&blitter->shaders, arbfp_blit_type_compare);
blitter->palette_texture = 0;
*next = &blitter->blitter;
}

View File

@ -979,7 +979,7 @@ static void wined3d_device_delete_opengl_contexts_cs(void *object)
}
context = context_acquire(device, NULL, 0);
device->blitter->free_private(device);
device->blitter->ops->blitter_destroy(device->blitter, context);
device->shader_backend->shader_free_private(device);
destroy_dummy_textures(device, context);
destroy_default_samplers(device, context);
@ -1014,12 +1014,15 @@ static void wined3d_device_create_primary_opengl_context_cs(void *object)
return;
}
if (FAILED(hr = device->blitter->alloc_private(device)))
if (!(device->blitter = wined3d_cpu_blitter_create()))
{
ERR("Failed to allocate blitter private data, hr %#x.\n", hr);
ERR("Failed to create CPU blitter.\n");
device->shader_backend->shader_free_private(device);
return;
}
wined3d_ffp_blitter_create(&device->blitter, &device->adapter->gl_info);
wined3d_arbfp_blitter_create(&device->blitter, device);
wined3d_fbo_blitter_create(&device->blitter, &device->adapter->gl_info);
swapchain = device->swapchains[0];
target = swapchain->back_buffers ? swapchain->back_buffers[0] : swapchain->front_buffer;
@ -4144,9 +4147,7 @@ HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *devi
struct wined3d_rendertarget_view *view, const RECT *rect, DWORD flags,
const struct wined3d_color *color, float depth, DWORD stencil)
{
const struct wined3d_blitter_ops *blitter;
struct wined3d_resource *resource;
enum wined3d_blit_op blit_op;
RECT r;
TRACE("device %p, view %p, rect %s, flags %#x, color %s, depth %.8e, stencil %u.\n",
@ -4184,19 +4185,7 @@ HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *devi
return hr;
}
if (flags & WINED3DCLEAR_TARGET)
blit_op = WINED3D_BLIT_OP_COLOR_FILL;
else
blit_op = WINED3D_BLIT_OP_DEPTH_FILL;
if (!(blitter = wined3d_select_blitter(&device->adapter->gl_info, &device->adapter->d3d_info,
blit_op, NULL, 0, 0, NULL, rect, resource->usage, resource->pool, resource->format)))
{
FIXME("No blitter is capable of performing the requested fill operation.\n");
return WINED3DERR_INVALIDCALL;
}
blitter->blitter_clear(device, view, rect, flags, color, depth, stencil);
device->blitter->ops->blitter_clear(device->blitter, device, view, rect, flags, color, depth, stencil);
return WINED3D_OK;
}
@ -4981,8 +4970,6 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
return hr;
}
device->blitter = adapter->blitter;
state_init(&device->state, &device->fb, &adapter->gl_info,
&adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT);
device->update_state = &device->state;

View File

@ -2599,16 +2599,6 @@ static const struct wined3d_shader_backend_ops *select_shader_backend(const stru
return &none_shader_backend;
}
static const struct wined3d_blitter_ops *select_blit_implementation(const struct wined3d_gl_info *gl_info,
const struct wined3d_shader_backend_ops *shader_backend_ops)
{
if ((shader_backend_ops == &glsl_shader_backend
|| shader_backend_ops == &arb_program_shader_backend)
&& gl_info->supported[ARB_FRAGMENT_PROGRAM])
return &arbfp_blit;
return &ffp_blit;
}
static void parse_extension_string(struct wined3d_gl_info *gl_info, const char *extensions,
const struct wined3d_extension_map *map, UINT entry_count)
{
@ -4169,7 +4159,6 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
adapter->shader_backend = select_shader_backend(gl_info);
adapter->vertex_pipe = select_vertex_implementation(gl_info, adapter->shader_backend);
adapter->fragment_pipe = select_fragment_implementation(gl_info, adapter->shader_backend);
adapter->blitter = select_blit_implementation(gl_info, adapter->shader_backend);
adapter->shader_backend->shader_get_caps(gl_info, &shader_caps);
adapter->d3d_info.vs_clipping = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_VS_CLIPPING;
@ -6567,7 +6556,6 @@ static BOOL wined3d_adapter_init_nogl(struct wined3d_adapter *adapter, UINT ordi
adapter->vertex_pipe = &none_vertex_pipe;
adapter->fragment_pipe = &none_fragment_pipe;
adapter->shader_backend = &none_shader_backend;
adapter->blitter = &cpu_blit;
display_device.cb = sizeof(display_device);
EnumDisplayDevicesW(NULL, ordinal, &display_device, 0);

View File

@ -497,10 +497,9 @@ static void surface_blt_fbo(const struct wined3d_device *device,
context_restore(context, restore_rt);
}
static BOOL fbo_blitter_supported(const struct wined3d_gl_info *gl_info,
const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op,
const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
static BOOL fbo_blitter_supported(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
{
if ((wined3d_settings.offscreen_rendering_mode != ORM_FBO) || !gl_info->fbo_ops.glBlitFramebuffer)
return FALSE;
@ -2196,7 +2195,7 @@ static BOOL surface_load_drawable(struct wined3d_surface *surface,
surface_get_rect(surface, NULL, &r);
wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
device->blitter->blit_surface(device, WINED3D_BLIT_OP_COLOR_BLIT, context,
device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context,
surface, WINED3D_LOCATION_TEXTURE_RGB, &r,
surface, WINED3D_LOCATION_DRAWABLE, &r,
NULL, WINED3D_TEXF_POINT);
@ -2242,9 +2241,9 @@ static BOOL surface_load_texture(struct wined3d_surface *surface,
if (!depth && sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB)
&& (texture->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)
&& fbo_blitter_supported(gl_info, &device->adapter->d3d_info, WINED3D_BLIT_OP_COLOR_BLIT,
NULL, texture->resource.usage, texture->resource.pool, texture->resource.format,
NULL, texture->resource.usage, texture->resource.pool, texture->resource.format))
&& fbo_blitter_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
texture->resource.usage, texture->resource.pool, texture->resource.format,
texture->resource.usage, texture->resource.pool, texture->resource.format))
{
if (srgb)
surface_blt_fbo(device, context, WINED3D_TEXF_POINT, surface, WINED3D_LOCATION_TEXTURE_RGB,
@ -2258,9 +2257,9 @@ static BOOL surface_load_texture(struct wined3d_surface *surface,
if (!depth && sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)
&& (!srgb || (texture->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB))
&& fbo_blitter_supported(gl_info, &device->adapter->d3d_info, WINED3D_BLIT_OP_COLOR_BLIT,
NULL, texture->resource.usage, texture->resource.pool, texture->resource.format,
NULL, texture->resource.usage, texture->resource.pool, texture->resource.format))
&& fbo_blitter_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
texture->resource.usage, texture->resource.pool, texture->resource.format,
texture->resource.usage, texture->resource.pool, texture->resource.format))
{
DWORD src_location = sub_resource->locations & WINED3D_LOCATION_RB_RESOLVED ?
WINED3D_LOCATION_RB_RESOLVED : WINED3D_LOCATION_RB_MULTISAMPLE;
@ -2440,27 +2439,45 @@ BOOL surface_load_location(struct wined3d_surface *surface, struct wined3d_conte
}
}
static HRESULT fbo_blitter_alloc(struct wined3d_device *device)
{
return WINED3D_OK;
}
/* Context activation is done by the caller. */
static void fbo_blitter_free(struct wined3d_device *device)
static void fbo_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context)
{
struct wined3d_blitter *next;
if ((next = blitter->next))
next->ops->blitter_destroy(next, context);
}
static void fbo_blitter_clear(struct wined3d_device *device, struct wined3d_rendertarget_view *view,
const RECT *rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil)
static void fbo_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device,
struct wined3d_rendertarget_view *view, const RECT *rect, DWORD flags,
const struct wined3d_color *colour, float depth, DWORD stencil)
{
ERR("This blitter does not implement clears.\n");
struct wined3d_blitter *next;
if ((next = blitter->next))
next->ops->blitter_clear(next, device, view, rect, flags, colour, depth, stencil);
}
static void fbo_blitter_blit(struct wined3d_device *device, enum wined3d_blit_op op,
static void fbo_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op,
struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location,
const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect,
const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter)
{
struct wined3d_resource *src_resource = &src_surface->container->resource;
struct wined3d_resource *dst_resource = &dst_surface->container->resource;
struct wined3d_device *device = dst_resource->device;
struct wined3d_blitter *next;
if (!fbo_blitter_supported(&device->adapter->gl_info, op,
src_resource->usage, src_resource->pool, src_resource->format,
src_resource->usage, dst_resource->pool, dst_resource->format))
{
if ((next = blitter->next))
next->ops->blitter_blit(next, op, context, src_surface, src_location,
src_rect, dst_surface, dst_location, dst_rect, colour_key, filter);
return;
}
if (op == WINED3D_BLIT_OP_COLOR_BLIT)
{
TRACE("Colour blit.\n");
@ -2479,23 +2496,43 @@ static void fbo_blitter_blit(struct wined3d_device *device, enum wined3d_blit_op
ERR("This blitter does not implement blit op %#x.\n", op);
}
const struct wined3d_blitter_ops fbo_blitter_ops =
static const struct wined3d_blitter_ops fbo_blitter_ops =
{
fbo_blitter_alloc,
fbo_blitter_free,
fbo_blitter_supported,
fbo_blitter_destroy,
fbo_blitter_clear,
fbo_blitter_blit,
};
static HRESULT ffp_blit_alloc(struct wined3d_device *device) { return WINED3D_OK; }
void wined3d_fbo_blitter_create(struct wined3d_blitter **next, const struct wined3d_gl_info *gl_info)
{
struct wined3d_blitter *blitter;
if ((wined3d_settings.offscreen_rendering_mode != ORM_FBO) || !gl_info->fbo_ops.glBlitFramebuffer)
return;
if (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter))))
return;
TRACE("Created blitter %p.\n", blitter);
blitter->ops = &fbo_blitter_ops;
blitter->next = *next;
*next = blitter;
}
/* Context activation is done by the caller. */
static void ffp_blit_free(struct wined3d_device *device) { }
static void ffp_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context)
{
struct wined3d_blitter *next;
if ((next = blitter->next))
next->ops->blitter_destroy(next, context);
}
static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info,
const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op,
const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
{
BOOL decompress;
@ -2517,6 +2554,9 @@ static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info,
}
case WINED3D_BLIT_OP_COLOR_BLIT:
case WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST:
if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
return FALSE;
if (TRACE_ON(d3d))
{
TRACE("Checking support for fixup:\n");
@ -2538,38 +2578,23 @@ static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info,
}
return TRUE;
case WINED3D_BLIT_OP_COLOR_FILL:
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
if (!((dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FBO_ATTACHABLE)
|| (dst_usage & WINED3DUSAGE_RENDERTARGET)))
return FALSE;
}
else if (!(dst_usage & WINED3DUSAGE_RENDERTARGET))
{
TRACE("Color fill not supported\n");
return FALSE;
}
/* FIXME: We should reject color fills on formats with fixups,
* but this would break P8 color fills for example. */
return TRUE;
case WINED3D_BLIT_OP_DEPTH_FILL:
return TRUE;
default:
TRACE("Unsupported blit_op=%d\n", blit_op);
return FALSE;
}
}
static void ffp_blit_clear(struct wined3d_device *device, struct wined3d_rendertarget_view *view,
const RECT *rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil)
static void ffp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device,
struct wined3d_rendertarget_view *view, const RECT *rect, DWORD flags,
const struct wined3d_color *colour, float depth, DWORD stencil)
{
const RECT draw_rect = {0, 0, view->width, view->height};
struct wined3d_resource *resource = view->resource;
struct wined3d_fb_state fb = {&view, NULL};
struct wined3d_blitter *next;
if (resource->pool == WINED3D_POOL_SYSTEM_MEM)
goto next;
if (flags != WINED3DCLEAR_TARGET)
{
@ -2579,10 +2604,29 @@ static void ffp_blit_clear(struct wined3d_device *device, struct wined3d_rendert
return;
}
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
if (!((view->format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)
|| (resource->usage & WINED3DUSAGE_RENDERTARGET)))
goto next;
}
else if (!(resource->usage & WINED3DUSAGE_RENDERTARGET))
{
goto next;
}
/* FIXME: We should reject colour fills on formats with fixups, but this
* would break P8 colour fills for example. */
device_clear_render_targets(device, 1, &fb, 1, rect, &draw_rect, flags, colour, 0.0f, 0);
return;
next:
if ((next = blitter->next))
next->ops->blitter_clear(next, device, view, rect, flags, colour, depth, stencil);
}
static void ffp_blit_blit_surface(struct wined3d_device *device, enum wined3d_blit_op op,
static void ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op,
struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location,
const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect,
const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter)
@ -2590,10 +2634,27 @@ static void ffp_blit_blit_surface(struct wined3d_device *device, enum wined3d_bl
struct wined3d_texture *src_texture = src_surface->container;
struct wined3d_texture *dst_texture = dst_surface->container;
const struct wined3d_gl_info *gl_info = context->gl_info;
struct wined3d_resource *src_resource, *dst_resource;
struct wined3d_color_key old_blt_key;
struct wined3d_device *device;
struct wined3d_blitter *next;
DWORD old_color_key_flags;
RECT r;
src_resource = &src_texture->resource;
dst_resource = &dst_texture->resource;
device = dst_resource->device;
if (!ffp_blit_supported(&device->adapter->gl_info, &device->adapter->d3d_info, op,
src_resource->usage, src_resource->pool, src_resource->format,
dst_resource->usage, dst_resource->pool, dst_resource->format))
{
if ((next = blitter->next))
next->ops->blitter_blit(next, op, context, src_surface, src_location,
src_rect, dst_surface, dst_location, dst_rect, color_key, filter);
return;
}
TRACE("Blt from surface %p to rendertarget %p\n", src_surface, dst_surface);
old_blt_key = src_texture->async.src_blt_color_key;
@ -2688,43 +2749,34 @@ static void ffp_blit_blit_surface(struct wined3d_device *device, enum wined3d_bl
(old_color_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_blt_key : NULL);
}
const struct wined3d_blitter_ops ffp_blit =
static const struct wined3d_blitter_ops ffp_blitter_ops =
{
ffp_blit_alloc,
ffp_blit_free,
ffp_blit_supported,
ffp_blit_clear,
ffp_blit_blit_surface,
ffp_blitter_destroy,
ffp_blitter_clear,
ffp_blitter_blit,
};
static HRESULT cpu_blit_alloc(struct wined3d_device *device)
void wined3d_ffp_blitter_create(struct wined3d_blitter **next, const struct wined3d_gl_info *gl_info)
{
return WINED3D_OK;
struct wined3d_blitter *blitter;
if (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter))))
return;
TRACE("Created blitter %p.\n", blitter);
blitter->ops = &ffp_blitter_ops;
blitter->next = *next;
*next = blitter;
}
/* Context activation is done by the caller. */
static void cpu_blit_free(struct wined3d_device *device)
static void cpu_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context)
{
}
struct wined3d_blitter *next;
static BOOL cpu_blit_supported(const struct wined3d_gl_info *gl_info,
const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op,
const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
{
switch (blit_op)
{
case WINED3D_BLIT_OP_COLOR_BLIT:
case WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST:
case WINED3D_BLIT_OP_COLOR_BLIT_CKEY:
case WINED3D_BLIT_OP_COLOR_FILL:
case WINED3D_BLIT_OP_DEPTH_FILL:
case WINED3D_BLIT_OP_DEPTH_BLIT:
return TRUE;
default:
return FALSE;
}
if ((next = blitter->next))
next->ops->blitter_destroy(next, context);
}
static HRESULT surface_cpu_blt_compressed(const BYTE *src_data, BYTE *dst_data,
@ -3361,8 +3413,9 @@ static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view,
wined3d_resource_unmap(view->resource, view->sub_resource_idx);
}
static void cpu_blit_clear(struct wined3d_device *device, struct wined3d_rendertarget_view *view,
const RECT *rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil)
static void cpu_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device,
struct wined3d_rendertarget_view *view, const RECT *rect, DWORD flags,
const struct wined3d_color *colour, float depth, DWORD stencil)
{
const struct wined3d_box box = {rect->left, rect->top, rect->right, rect->bottom, 0, 1};
struct wined3d_color c = {depth, 0.0f, 0.0f, 0.0f};
@ -3382,7 +3435,7 @@ static void cpu_blit_clear(struct wined3d_device *device, struct wined3d_rendert
FIXME("flags %#x not implemented.\n", flags);
}
static void cpu_blit_blit_surface(struct wined3d_device *device, enum wined3d_blit_op op,
static void cpu_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op,
struct wined3d_context *context, struct wined3d_surface *src_surface, DWORD src_location,
const RECT *src_rect, struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect,
const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter)
@ -3397,14 +3450,21 @@ static void cpu_blit_blit_surface(struct wined3d_device *device, enum wined3d_bl
DWORD flags = 0;
memset(&fx, 0, sizeof(fx));
if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST)
switch (op)
{
flags |= WINED3D_BLT_ALPHA_TEST;
}
else if (op == WINED3D_BLIT_OP_COLOR_BLIT_CKEY)
{
flags |= WINED3D_BLT_SRC_CKEY_OVERRIDE | WINED3D_BLT_FX;
fx.src_color_key = *color_key;
case WINED3D_BLIT_OP_COLOR_BLIT:
case WINED3D_BLIT_OP_DEPTH_BLIT:
break;
case WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST:
flags |= WINED3D_BLT_ALPHA_TEST;
break;
case WINED3D_BLIT_OP_COLOR_BLIT_CKEY:
flags |= WINED3D_BLT_SRC_CKEY_OVERRIDE | WINED3D_BLT_FX;
fx.src_color_key = *color_key;
break;
default:
FIXME("Unhandled op %#x.\n", op);
break;
}
if (FAILED(surface_cpu_blt(dst_texture, dst_sub_resource_idx, &dst_box,
@ -3413,15 +3473,28 @@ static void cpu_blit_blit_surface(struct wined3d_device *device, enum wined3d_bl
wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, dst_location);
}
const struct wined3d_blitter_ops cpu_blit =
static const struct wined3d_blitter_ops cpu_blitter_ops =
{
cpu_blit_alloc,
cpu_blit_free,
cpu_blit_supported,
cpu_blit_clear,
cpu_blit_blit_surface,
cpu_blitter_destroy,
cpu_blitter_clear,
cpu_blitter_blit,
};
struct wined3d_blitter *wined3d_cpu_blitter_create(void)
{
struct wined3d_blitter *blitter;
if (!(blitter = HeapAlloc(GetProcessHeap(), 0, sizeof(*blitter))))
return NULL;
TRACE("Created blitter %p.\n", blitter);
blitter->ops = &cpu_blitter_ops;
blitter->next = NULL;
return blitter;
}
HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect,
struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags,
const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter)
@ -3435,6 +3508,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
struct wined3d_device *device = dst_texture->resource.device;
struct wined3d_swapchain *src_swapchain, *dst_swapchain;
DWORD src_ds_flags, dst_ds_flags;
struct wined3d_context *context;
BOOL scale, convert;
DWORD dst_location;
@ -3533,39 +3607,29 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
if (src_ds_flags || dst_ds_flags)
{
const struct wined3d_blitter_ops *blitter;
struct wined3d_context *context;
TRACE("Depth/stencil blit.\n");
if ((blitter = wined3d_select_blitter(&device->adapter->gl_info,
&device->adapter->d3d_info, WINED3D_BLIT_OP_DEPTH_BLIT,
src_rect, src_texture->resource.usage, src_texture->resource.pool, src_texture->resource.format,
dst_rect, dst_texture->resource.usage, dst_texture->resource.pool, dst_texture->resource.format)))
{
if (dst_texture->resource.pool == WINED3D_POOL_SYSTEM_MEM)
dst_location = dst_texture->resource.map_binding;
else
dst_location = dst_texture->resource.draw_binding;
if (dst_texture->resource.pool == WINED3D_POOL_SYSTEM_MEM)
dst_location = dst_texture->resource.map_binding;
else
dst_location = dst_texture->resource.draw_binding;
context = context_acquire(device, dst_texture, dst_sub_resource_idx);
blitter->blit_surface(device, WINED3D_BLIT_OP_DEPTH_BLIT, context,
src_surface, src_texture->resource.draw_binding, src_rect,
dst_surface, dst_location, dst_rect, NULL, filter);
context_release(context);
context = context_acquire(device, dst_texture, dst_sub_resource_idx);
device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_DEPTH_BLIT, context,
src_surface, src_texture->resource.draw_binding, src_rect,
dst_surface, dst_location, dst_rect, NULL, filter);
context_release(context);
wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, dst_location);
wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~dst_location);
wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, dst_location);
wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~dst_location);
return WINED3D_OK;
}
return WINED3D_OK;
}
else
{
struct wined3d_texture_sub_resource *src_sub_resource, *dst_sub_resource;
enum wined3d_blit_op blit_op = WINED3D_BLIT_OP_COLOR_BLIT;
const struct wined3d_color_key *colour_key = NULL;
const struct wined3d_blitter_ops *blitter;
TRACE("Colour blit.\n");
@ -3615,7 +3679,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
{
if (!wined3d_resource_is_offscreen(&dst_texture->resource))
{
struct wined3d_context *context = context_acquire(device,
context = context_acquire(device,
dst_texture, dst_sub_resource_idx);
wined3d_texture_load_location(dst_texture, dst_sub_resource_idx,
context, dst_texture->resource.draw_binding);
@ -3648,28 +3712,21 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
return WINED3D_OK;
}
if ((blitter = wined3d_select_blitter(&device->adapter->gl_info, &device->adapter->d3d_info, blit_op,
src_rect, src_texture->resource.usage, src_texture->resource.pool, src_texture->resource.format,
dst_rect, dst_texture->resource.usage, dst_texture->resource.pool, dst_texture->resource.format)))
{
struct wined3d_context *context;
if (dst_texture->resource.pool == WINED3D_POOL_SYSTEM_MEM)
dst_location = dst_texture->resource.map_binding;
else
dst_location = dst_texture->resource.draw_binding;
if (dst_texture->resource.pool == WINED3D_POOL_SYSTEM_MEM)
dst_location = dst_texture->resource.map_binding;
else
dst_location = dst_texture->resource.draw_binding;
context = context_acquire(device, dst_texture, dst_sub_resource_idx);
device->blitter->ops->blitter_blit(device->blitter, blit_op, context,
src_surface, src_texture->resource.draw_binding, src_rect,
dst_surface, dst_location, dst_rect, colour_key, filter);
context_release(context);
context = context_acquire(device, dst_texture, dst_sub_resource_idx);
blitter->blit_surface(device, blit_op, context,
src_surface, src_texture->resource.draw_binding, src_rect,
dst_surface, dst_location, dst_rect, colour_key, filter);
context_release(context);
wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, dst_location);
wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~dst_location);
wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, dst_location);
wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~dst_location);
return WINED3D_OK;
}
return WINED3D_OK;
}
fallback:

View File

@ -306,22 +306,12 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain,
struct wined3d_texture *texture = swapchain->back_buffers[0];
struct wined3d_surface *back_buffer = texture->sub_resources[0].u.surface;
struct wined3d_device *device = swapchain->device;
const struct wined3d_blitter_ops *blitter;
enum wined3d_texture_filter_type filter;
DWORD location;
TRACE("swapchain %p, context %p, src_rect %s, dst_rect %s.\n",
swapchain, context, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect));
if (!(blitter = wined3d_select_blitter(&device->adapter->gl_info,
&device->adapter->d3d_info, WINED3D_BLIT_OP_COLOR_BLIT,
src_rect, texture->resource.usage, texture->resource.pool, texture->resource.format,
dst_rect, texture->resource.usage, texture->resource.pool, texture->resource.format)))
{
FIXME("No blitter supports the requested blit.\n");
return;
}
if ((src_rect->right - src_rect->left == dst_rect->right - dst_rect->left
&& src_rect->bottom - src_rect->top == dst_rect->bottom - dst_rect->top)
|| is_complex_fixup(texture->resource.format->color_fixup))
@ -334,8 +324,8 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain,
location = WINED3D_LOCATION_RB_RESOLVED;
wined3d_texture_validate_location(texture, 0, WINED3D_LOCATION_DRAWABLE);
blitter->blit_surface(device, WINED3D_BLIT_OP_COLOR_BLIT, context, back_buffer, location,
src_rect, back_buffer, WINED3D_LOCATION_DRAWABLE, dst_rect, NULL, filter);
device->blitter->ops->blitter_blit(device->blitter, WINED3D_BLIT_OP_COLOR_BLIT, context, back_buffer,
location, src_rect, back_buffer, WINED3D_LOCATION_DRAWABLE, dst_rect, NULL, filter);
wined3d_texture_invalidate_location(texture, 0, WINED3D_LOCATION_DRAWABLE);
}

View File

@ -5794,37 +5794,6 @@ int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb
return memcmp(ka, kb, sizeof(*ka));
}
const struct wined3d_blitter_ops *wined3d_select_blitter(const struct wined3d_gl_info *gl_info,
const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op,
const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
{
static const struct wined3d_blitter_ops * const blitters[] =
{
&fbo_blitter_ops,
&arbfp_blit,
&ffp_blit,
&cpu_blit,
};
unsigned int i;
TRACE("gl_info %p, d3d_info %p, blit_op %#x, src_rect %s, src_usage %s, src_pool %s, src_format %s, "
"dst_rect %s, dst_usage %s, dst_pool %s, dst_format %s.\n", gl_info, d3d_info, blit_op,
wine_dbgstr_rect(src_rect), debug_d3dusage(src_usage), debug_d3dpool(src_pool),
src_format ? debug_d3dformat(src_format->id) : "(null)", wine_dbgstr_rect(dst_rect),
debug_d3dusage(dst_usage), debug_d3dpool(dst_pool), debug_d3dformat(dst_format->id));
for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
{
if (blitters[i]->blit_supported(gl_info, d3d_info, blit_op,
src_rect, src_usage, src_pool, src_format,
dst_rect, dst_usage, dst_pool, dst_format))
return blitters[i];
}
return NULL;
}
void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
{
const struct wined3d_viewport *vp = &state->viewport;

View File

@ -1867,33 +1867,33 @@ enum wined3d_blit_op
WINED3D_BLIT_OP_DEPTH_BLIT,
};
struct wined3d_blitter
{
const struct wined3d_blitter_ops *ops;
struct wined3d_blitter *next;
};
struct wined3d_blitter_ops
{
HRESULT (*alloc_private)(struct wined3d_device *device);
void (*free_private)(struct wined3d_device *device);
BOOL (*blit_supported)(const struct wined3d_gl_info *gl_info,
const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op,
const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format);
void (*blitter_clear)(struct wined3d_device *device, struct wined3d_rendertarget_view *view,
const RECT *rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil);
void (*blit_surface)(struct wined3d_device *device, enum wined3d_blit_op op, struct wined3d_context *context,
void (*blitter_destroy)(struct wined3d_blitter *blitter, struct wined3d_context *context);
void (*blitter_clear)(struct wined3d_blitter *blitter, struct wined3d_device *device,
struct wined3d_rendertarget_view *view, const RECT *rect, DWORD flags,
const struct wined3d_color *colour, float depth, DWORD stencil);
void (*blitter_blit)(struct wined3d_blitter *blitter, enum wined3d_blit_op op, struct wined3d_context *context,
struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect,
struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect,
const struct wined3d_color_key *color_key, enum wined3d_texture_filter_type filter);
};
extern const struct wined3d_blitter_ops fbo_blitter_ops DECLSPEC_HIDDEN;
extern const struct wined3d_blitter_ops arbfp_blit DECLSPEC_HIDDEN;
extern const struct wined3d_blitter_ops ffp_blit DECLSPEC_HIDDEN;
extern const struct wined3d_blitter_ops cpu_blit DECLSPEC_HIDDEN;
void wined3d_arbfp_blitter_create(struct wined3d_blitter **next,
const struct wined3d_device *device) DECLSPEC_HIDDEN;
struct wined3d_blitter *wined3d_cpu_blitter_create(void) DECLSPEC_HIDDEN;
void wined3d_fbo_blitter_create(struct wined3d_blitter **next,
const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
void wined3d_ffp_blitter_create(struct wined3d_blitter **next,
const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
BOOL wined3d_clip_blit(const RECT *clip_rect, RECT *clipped, RECT *other) DECLSPEC_HIDDEN;
const struct wined3d_blitter_ops *wined3d_select_blitter(const struct wined3d_gl_info *gl_info,
const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op,
const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
DECLSPEC_HIDDEN;
struct wined3d_context *context_acquire(const struct wined3d_device *device,
struct wined3d_texture *texture, unsigned int sub_resource_idx) DECLSPEC_HIDDEN;
@ -2361,7 +2361,6 @@ struct wined3d_adapter
const struct wined3d_vertex_pipe_ops *vertex_pipe;
const struct fragment_pipeline *fragment_pipe;
const struct wined3d_shader_backend_ops *shader_backend;
const struct wined3d_blitter_ops *blitter;
};
struct wined3d_caps_gl_ctx
@ -2624,11 +2623,10 @@ struct wined3d_device
void *shader_priv;
void *fragment_priv;
void *vertex_priv;
void *blit_priv;
struct StateEntry StateTable[STATE_HIGHEST + 1];
/* Array of functions for states which are handled by more than one pipeline part */
APPLYSTATEFUNC *multistate_funcs[STATE_HIGHEST + 1];
const struct wined3d_blitter_ops *blitter;
struct wined3d_blitter *blitter;
BYTE vertexBlendUsed : 1; /* To avoid needless setting of the blend matrices */
BYTE bCursorVisible : 1;