wined3d: Store the context's current rendertarget as a texture and sub-resource index.
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5f05acfcff
commit
d6e2f650d5
|
@ -852,22 +852,26 @@ static void context_queue_fbo_entry_destruction(struct wined3d_context *context,
|
|||
void context_resource_released(const struct wined3d_device *device,
|
||||
struct wined3d_resource *resource, enum wined3d_resource_type type)
|
||||
{
|
||||
struct wined3d_texture *texture;
|
||||
UINT i;
|
||||
struct wined3d_surface *surface;
|
||||
|
||||
if (!device->d3d_initialized)
|
||||
return;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case WINED3D_RTYPE_SURFACE:
|
||||
surface = surface_from_resource(resource);
|
||||
case WINED3D_RTYPE_TEXTURE_2D:
|
||||
case WINED3D_RTYPE_TEXTURE_3D:
|
||||
texture = wined3d_texture_from_resource(resource);
|
||||
|
||||
for (i = 0; i < device->context_count; ++i)
|
||||
{
|
||||
struct wined3d_context *context = device->contexts[i];
|
||||
if (context->current_rt == surface)
|
||||
context->current_rt = NULL;
|
||||
if (context->current_rt.texture == texture)
|
||||
{
|
||||
context->current_rt.texture = NULL;
|
||||
context->current_rt.sub_resource_idx = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1318,7 +1322,8 @@ void context_release(struct wined3d_context *context)
|
|||
* A to avoid breaking caller code. */
|
||||
void context_restore(struct wined3d_context *context, struct wined3d_surface *restore)
|
||||
{
|
||||
if (context->current_rt != restore)
|
||||
if (context->current_rt.texture != restore->container
|
||||
|| context->current_rt.sub_resource_idx != surface_get_sub_resource_idx(restore))
|
||||
{
|
||||
context_release(context);
|
||||
context = context_acquire(restore->container->resource.device, restore);
|
||||
|
@ -1777,7 +1782,8 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
|
|||
}
|
||||
|
||||
ret->swapchain = swapchain;
|
||||
ret->current_rt = target->sub_resources[0].u.surface;
|
||||
ret->current_rt.texture = target;
|
||||
ret->current_rt.sub_resource_idx = 0;
|
||||
ret->tid = GetCurrentThreadId();
|
||||
|
||||
ret->render_offscreen = wined3d_resource_is_offscreen(&target->resource);
|
||||
|
@ -2032,9 +2038,10 @@ static void set_blit_dimension(const struct wined3d_gl_info *gl_info, UINT width
|
|||
|
||||
static void context_get_rt_size(const struct wined3d_context *context, SIZE *size)
|
||||
{
|
||||
const struct wined3d_surface *rt = context->current_rt;
|
||||
const struct wined3d_texture *rt = context->current_rt.texture;
|
||||
unsigned int level;
|
||||
|
||||
if (rt->container->swapchain && rt->container->swapchain->front_buffer == rt->container)
|
||||
if (rt->swapchain && rt->swapchain->front_buffer == rt)
|
||||
{
|
||||
RECT window_size;
|
||||
|
||||
|
@ -2045,8 +2052,9 @@ static void context_get_rt_size(const struct wined3d_context *context, SIZE *siz
|
|||
return;
|
||||
}
|
||||
|
||||
size->cx = rt->resource.width;
|
||||
size->cy = rt->resource.height;
|
||||
level = context->current_rt.sub_resource_idx % rt->level_count;
|
||||
size->cx = wined3d_texture_get_level_width(rt, level);
|
||||
size->cy = wined3d_texture_get_level_height(rt, level);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -2413,7 +2421,8 @@ static void context_validate_onscreen_formats(struct wined3d_context *context,
|
|||
const struct wined3d_rendertarget_view *depth_stencil)
|
||||
{
|
||||
/* Onscreen surfaces are always in a swapchain */
|
||||
struct wined3d_swapchain *swapchain = context->current_rt->container->swapchain;
|
||||
struct wined3d_swapchain *swapchain = context->current_rt.texture->swapchain;
|
||||
struct wined3d_surface *surface;
|
||||
|
||||
if (context->render_offscreen || !depth_stencil) return;
|
||||
if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->format)) return;
|
||||
|
@ -2424,7 +2433,8 @@ static void context_validate_onscreen_formats(struct wined3d_context *context,
|
|||
WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n");
|
||||
|
||||
/* The currently active context is the necessary context to access the swapchain's onscreen buffers */
|
||||
surface_load_location(context->current_rt, context, WINED3D_LOCATION_TEXTURE_RGB);
|
||||
surface = context->current_rt.texture->sub_resources[context->current_rt.sub_resource_idx].u.surface;
|
||||
surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB);
|
||||
swapchain->render_to_fbo = TRUE;
|
||||
swapchain_update_draw_bindings(swapchain);
|
||||
context_set_render_offscreen(context, TRUE);
|
||||
|
@ -2459,7 +2469,8 @@ static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *conte
|
|||
/* Context activation is done by the caller. */
|
||||
void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device)
|
||||
{
|
||||
struct wined3d_surface *rt = context->current_rt;
|
||||
struct wined3d_texture *rt = context->current_rt.texture;
|
||||
struct wined3d_surface *surface;
|
||||
DWORD rt_mask, *cur_mask;
|
||||
|
||||
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
|
||||
|
@ -2468,10 +2479,11 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine
|
|||
|
||||
if (context->render_offscreen)
|
||||
{
|
||||
wined3d_texture_load(rt->container, context, FALSE);
|
||||
wined3d_texture_load(rt, context, FALSE);
|
||||
|
||||
context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, rt, NULL, rt->container->resource.draw_binding);
|
||||
if (rt->container->resource.format->id != WINED3DFMT_NULL)
|
||||
surface = rt->sub_resources[context->current_rt.sub_resource_idx].u.surface;
|
||||
context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, surface, NULL, rt->resource.draw_binding);
|
||||
if (rt->resource.format->id != WINED3DFMT_NULL)
|
||||
rt_mask = 1;
|
||||
else
|
||||
rt_mask = 0;
|
||||
|
@ -2480,12 +2492,12 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine
|
|||
{
|
||||
context->current_fbo = NULL;
|
||||
context_bind_fbo(context, GL_FRAMEBUFFER, 0);
|
||||
rt_mask = context_generate_rt_mask_from_resource(&rt->container->resource);
|
||||
rt_mask = context_generate_rt_mask_from_resource(&rt->resource);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_mask = context_generate_rt_mask_no_fbo(context, rt->container);
|
||||
rt_mask = context_generate_rt_mask_no_fbo(context, rt);
|
||||
}
|
||||
|
||||
cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask;
|
||||
|
@ -3419,34 +3431,38 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void context_setup_target(struct wined3d_context *context, struct wined3d_surface *target)
|
||||
static void context_setup_target(struct wined3d_context *context,
|
||||
struct wined3d_texture *texture, unsigned int sub_resource_idx)
|
||||
{
|
||||
BOOL old_render_offscreen = context->render_offscreen, render_offscreen;
|
||||
|
||||
render_offscreen = wined3d_resource_is_offscreen(&target->container->resource);
|
||||
if (context->current_rt == target && render_offscreen == old_render_offscreen) return;
|
||||
render_offscreen = wined3d_resource_is_offscreen(&texture->resource);
|
||||
if (context->current_rt.texture == texture
|
||||
&& context->current_rt.sub_resource_idx == sub_resource_idx
|
||||
&& render_offscreen == old_render_offscreen)
|
||||
return;
|
||||
|
||||
/* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers
|
||||
* the alpha blend state changes with different render target formats. */
|
||||
if (!context->current_rt)
|
||||
if (!context->current_rt.texture)
|
||||
{
|
||||
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
|
||||
}
|
||||
else
|
||||
{
|
||||
const struct wined3d_format *old = context->current_rt->container->resource.format;
|
||||
const struct wined3d_format *new = target->container->resource.format;
|
||||
const struct wined3d_format *old = context->current_rt.texture->resource.format;
|
||||
const struct wined3d_format *new = texture->resource.format;
|
||||
|
||||
if (old->id != new->id)
|
||||
{
|
||||
/* Disable blending when the alpha mask has changed and when a format doesn't support blending. */
|
||||
if ((old->alpha_size && !new->alpha_size) || (!old->alpha_size && new->alpha_size)
|
||||
|| !(target->container->resource.format_flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
|
||||
|| !(texture->resource.format_flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
|
||||
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
|
||||
|
||||
/* Update sRGB writing when switching between formats that do/do not support sRGB writing */
|
||||
if ((context->current_rt->container->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE)
|
||||
!= (target->container->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE))
|
||||
if ((context->current_rt.texture->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE)
|
||||
!= (texture->resource.format_flags & WINED3DFMT_FLAG_SRGB_WRITE))
|
||||
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE));
|
||||
}
|
||||
|
||||
|
@ -3458,25 +3474,32 @@ static void context_setup_target(struct wined3d_context *context, struct wined3d
|
|||
* has to be called with the old rendertarget active, otherwise a
|
||||
* wrong drawable is read. */
|
||||
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
|
||||
&& old_render_offscreen && context->current_rt != target)
|
||||
&& old_render_offscreen && (context->current_rt.texture != texture
|
||||
|| context->current_rt.sub_resource_idx != sub_resource_idx))
|
||||
{
|
||||
struct wined3d_texture *texture = context->current_rt->container;
|
||||
unsigned int prev_sub_resource_idx = context->current_rt.sub_resource_idx;
|
||||
struct wined3d_texture *prev_texture = context->current_rt.texture;
|
||||
struct wined3d_surface *prev_surface;
|
||||
|
||||
/* Read the back buffer of the old drawable into the destination texture. */
|
||||
if (texture->texture_srgb.name)
|
||||
wined3d_texture_load(texture, context, TRUE);
|
||||
wined3d_texture_load(texture, context, FALSE);
|
||||
surface_invalidate_location(context->current_rt, WINED3D_LOCATION_DRAWABLE);
|
||||
if (prev_texture->texture_srgb.name)
|
||||
wined3d_texture_load(prev_texture, context, TRUE);
|
||||
wined3d_texture_load(prev_texture, context, FALSE);
|
||||
prev_surface = prev_texture->sub_resources[prev_sub_resource_idx].u.surface;
|
||||
surface_invalidate_location(prev_surface, WINED3D_LOCATION_DRAWABLE);
|
||||
}
|
||||
}
|
||||
|
||||
context->current_rt = target;
|
||||
context->current_rt.texture = texture;
|
||||
context->current_rt.sub_resource_idx = sub_resource_idx;
|
||||
context_set_render_offscreen(context, render_offscreen);
|
||||
}
|
||||
|
||||
struct wined3d_context *context_acquire(const struct wined3d_device *device, struct wined3d_surface *target)
|
||||
{
|
||||
struct wined3d_context *current_context = context_get_current();
|
||||
struct wined3d_texture *target_texture;
|
||||
unsigned int target_sub_resource_idx;
|
||||
struct wined3d_context *context;
|
||||
|
||||
TRACE("device %p, target %p.\n", device, target);
|
||||
|
@ -3484,33 +3507,41 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, str
|
|||
if (current_context && current_context->destroyed)
|
||||
current_context = NULL;
|
||||
|
||||
if (!target)
|
||||
if (target)
|
||||
{
|
||||
target_texture = target->container;
|
||||
target_sub_resource_idx = surface_get_sub_resource_idx(target);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (current_context
|
||||
&& current_context->current_rt
|
||||
&& current_context->current_rt.texture
|
||||
&& current_context->swapchain->device == device)
|
||||
{
|
||||
target = current_context->current_rt;
|
||||
target_texture = current_context->current_rt.texture;
|
||||
target_sub_resource_idx = current_context->current_rt.sub_resource_idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct wined3d_swapchain *swapchain = device->swapchains[0];
|
||||
|
||||
if (swapchain->back_buffers)
|
||||
target = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0));
|
||||
target_texture = swapchain->back_buffers[0];
|
||||
else
|
||||
target = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0));
|
||||
target_texture = swapchain->front_buffer;
|
||||
target_sub_resource_idx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_context && current_context->current_rt == target)
|
||||
if (current_context && current_context->current_rt.texture == target_texture)
|
||||
{
|
||||
context = current_context;
|
||||
}
|
||||
else if (target->container->swapchain)
|
||||
else if (target_texture->swapchain)
|
||||
{
|
||||
TRACE("Rendering onscreen.\n");
|
||||
|
||||
context = swapchain_get_context(target->container->swapchain);
|
||||
context = swapchain_get_context(target_texture->swapchain);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3526,7 +3557,7 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, str
|
|||
|
||||
context_enter(context);
|
||||
context_update_window(context);
|
||||
context_setup_target(context, target);
|
||||
context_setup_target(context, target_texture, target_sub_resource_idx);
|
||||
if (!context->valid) return context;
|
||||
|
||||
if (context != current_context)
|
||||
|
|
|
@ -58,7 +58,7 @@ static enum wined3d_event_query_result wined3d_event_query_test(const struct win
|
|||
return WINED3D_EVENT_QUERY_WRONG_THREAD;
|
||||
}
|
||||
|
||||
context = context_acquire(device, query->context->current_rt);
|
||||
context = context_acquire(device, context_get_rt_surface(query->context));
|
||||
gl_info = context->gl_info;
|
||||
|
||||
if (gl_info->supported[ARB_SYNC])
|
||||
|
@ -132,7 +132,7 @@ enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_
|
|||
return WINED3D_EVENT_QUERY_WRONG_THREAD;
|
||||
}
|
||||
|
||||
context = context_acquire(device, query->context->current_rt);
|
||||
context = context_acquire(device, context_get_rt_surface(query->context));
|
||||
|
||||
if (gl_info->supported[ARB_SYNC])
|
||||
{
|
||||
|
@ -192,7 +192,7 @@ void wined3d_event_query_issue(struct wined3d_event_query *query, const struct w
|
|||
}
|
||||
else
|
||||
{
|
||||
context = context_acquire(device, query->context->current_rt);
|
||||
context = context_acquire(device, context_get_rt_surface(query->context));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -348,7 +348,7 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
context = context_acquire(query->device, oq->context->current_rt);
|
||||
context = context_acquire(device, context_get_rt_surface(oq->context));
|
||||
|
||||
GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT_AVAILABLE, &available));
|
||||
checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)");
|
||||
|
@ -490,7 +490,7 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW
|
|||
}
|
||||
else
|
||||
{
|
||||
context = context_acquire(query->device, oq->context->current_rt);
|
||||
context = context_acquire(device, context_get_rt_surface(oq->context));
|
||||
|
||||
GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED));
|
||||
checkGLcall("glEndQuery()");
|
||||
|
@ -522,7 +522,7 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW
|
|||
}
|
||||
else
|
||||
{
|
||||
context = context_acquire(query->device, oq->context->current_rt);
|
||||
context = context_acquire(device, context_get_rt_surface(oq->context));
|
||||
|
||||
GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED));
|
||||
checkGLcall("glEndQuery()");
|
||||
|
@ -578,7 +578,7 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
context = context_acquire(query->device, tq->context->current_rt);
|
||||
context = context_acquire(device, context_get_rt_surface(tq->context));
|
||||
|
||||
GL_EXTCALL(glGetQueryObjectuiv(tq->id, GL_QUERY_RESULT_AVAILABLE, &available));
|
||||
checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)");
|
||||
|
|
|
@ -108,8 +108,8 @@ void surface_get_drawable_size(const struct wined3d_surface *surface, const stru
|
|||
/* The drawable size of an onscreen drawable is the surface size.
|
||||
* (Actually: The window size, but the surface is created in window
|
||||
* size.) */
|
||||
*width = context->current_rt->resource.width;
|
||||
*height = context->current_rt->resource.height;
|
||||
*width = context->current_rt.texture->resource.width;
|
||||
*height = context->current_rt.texture->resource.height;
|
||||
}
|
||||
else if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER)
|
||||
{
|
||||
|
@ -123,10 +123,13 @@ void surface_get_drawable_size(const struct wined3d_surface *surface, const stru
|
|||
}
|
||||
else
|
||||
{
|
||||
struct wined3d_surface *rt;
|
||||
|
||||
/* The drawable size of an FBO target is the OpenGL texture size,
|
||||
* which is the power of two size. */
|
||||
*width = context->current_rt->pow2Width;
|
||||
*height = context->current_rt->pow2Height;
|
||||
rt = context->current_rt.texture->sub_resources[context->current_rt.sub_resource_idx].u.surface;
|
||||
*width = rt->pow2Width;
|
||||
*height = rt->pow2Height;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -675,11 +678,11 @@ static void surface_blt_fbo(const struct wined3d_device *device,
|
|||
else if (dst_location == WINED3D_LOCATION_DRAWABLE) required_rt = dst_surface;
|
||||
else required_rt = NULL;
|
||||
|
||||
if (required_rt && required_rt != old_ctx->current_rt)
|
||||
{
|
||||
restore_rt = old_ctx->current_rt;
|
||||
restore_rt = context_get_rt_surface(old_ctx);
|
||||
if (restore_rt != required_rt)
|
||||
context = context_acquire(device, required_rt);
|
||||
}
|
||||
else
|
||||
restore_rt = NULL;
|
||||
|
||||
if (!context->valid)
|
||||
{
|
||||
|
@ -1852,11 +1855,11 @@ static void read_from_framebuffer(struct wined3d_surface *surface,
|
|||
|
||||
surface_get_memory(surface, &data, dst_location);
|
||||
|
||||
if (surface != old_ctx->current_rt)
|
||||
{
|
||||
restore_rt = old_ctx->current_rt;
|
||||
restore_rt = context_get_rt_surface(old_ctx);
|
||||
if (restore_rt != surface)
|
||||
context = context_acquire(device, surface);
|
||||
}
|
||||
else
|
||||
restore_rt = NULL;
|
||||
|
||||
context_apply_blit_state(context, device);
|
||||
gl_info = context->gl_info;
|
||||
|
@ -1962,11 +1965,11 @@ void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct
|
|||
struct wined3d_context *context = old_ctx;
|
||||
struct wined3d_surface *restore_rt = NULL;
|
||||
|
||||
if (old_ctx->current_rt != surface)
|
||||
{
|
||||
restore_rt = old_ctx->current_rt;
|
||||
restore_rt = context_get_rt_surface(old_ctx);
|
||||
if (restore_rt != surface)
|
||||
context = context_acquire(device, surface);
|
||||
}
|
||||
else
|
||||
restore_rt = NULL;
|
||||
|
||||
gl_info = context->gl_info;
|
||||
device_invalidate_state(device, STATE_FRAMEBUFFER);
|
||||
|
@ -2485,12 +2488,11 @@ static void surface_blt_to_drawable(const struct wined3d_device *device,
|
|||
src_rect = *src_rect_in;
|
||||
dst_rect = *dst_rect_in;
|
||||
|
||||
|
||||
if (old_ctx->current_rt != dst_surface)
|
||||
{
|
||||
restore_rt = old_ctx->current_rt;
|
||||
restore_rt = context_get_rt_surface(old_ctx);
|
||||
if (restore_rt != dst_surface)
|
||||
context = context_acquire(device, dst_surface);
|
||||
}
|
||||
else
|
||||
restore_rt = NULL;
|
||||
|
||||
gl_info = context->gl_info;
|
||||
|
||||
|
|
|
@ -1282,7 +1282,11 @@ struct wined3d_context
|
|||
DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */
|
||||
|
||||
struct wined3d_swapchain *swapchain;
|
||||
struct wined3d_surface *current_rt;
|
||||
struct
|
||||
{
|
||||
struct wined3d_texture *texture;
|
||||
unsigned int sub_resource_idx;
|
||||
} current_rt;
|
||||
DWORD tid; /* Thread ID which owns this context at the moment */
|
||||
|
||||
/* Stores some information about the context state for optimization */
|
||||
|
@ -3473,6 +3477,15 @@ static inline BOOL can_use_texture_swizzle(const struct wined3d_gl_info *gl_info
|
|||
&& !is_scaling_fixup(format->color_fixup);
|
||||
}
|
||||
|
||||
static inline struct wined3d_surface *context_get_rt_surface(const struct wined3d_context *context)
|
||||
{
|
||||
struct wined3d_texture *texture = context->current_rt.texture;
|
||||
|
||||
if (!texture)
|
||||
return NULL;
|
||||
return texture->sub_resources[context->current_rt.sub_resource_idx].u.surface;
|
||||
}
|
||||
|
||||
/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
|
||||
#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
|
||||
|
||||
|
|
Loading…
Reference in New Issue