wined3d: Move device_clear_render_targets() to texture.c.
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
cd94aa8fa8
commit
ee8e4d2010
|
@ -257,251 +257,6 @@ void device_context_remove(struct wined3d_device *device, struct wined3d_context
|
|||
device->contexts = new_array;
|
||||
}
|
||||
|
||||
static BOOL is_full_clear(const struct wined3d_texture *texture, unsigned int sub_resource_idx,
|
||||
const RECT *draw_rect, const RECT *clear_rect)
|
||||
{
|
||||
unsigned int width, height, level;
|
||||
|
||||
level = sub_resource_idx % texture->level_count;
|
||||
width = wined3d_texture_get_level_width(texture, level);
|
||||
height = wined3d_texture_get_level_height(texture, level);
|
||||
|
||||
/* partial draw rect */
|
||||
if (draw_rect->left || draw_rect->top || draw_rect->right < width || draw_rect->bottom < height)
|
||||
return FALSE;
|
||||
|
||||
/* partial clear rect */
|
||||
if (clear_rect && (clear_rect->left > 0 || clear_rect->top > 0
|
||||
|| clear_rect->right < width || clear_rect->bottom < height))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, const struct wined3d_fb_state *fb,
|
||||
UINT rect_count, const RECT *clear_rect, const RECT *draw_rect, DWORD flags, const struct wined3d_color *color,
|
||||
float depth, DWORD stencil)
|
||||
{
|
||||
struct wined3d_rendertarget_view *rtv = rt_count ? fb->render_targets[0] : NULL;
|
||||
struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
|
||||
const struct wined3d_state *state = &device->cs->state;
|
||||
struct wined3d_texture *depth_stencil = NULL;
|
||||
const struct wined3d_gl_info *gl_info;
|
||||
struct wined3d_context_gl *context_gl;
|
||||
struct wined3d_texture *target = NULL;
|
||||
UINT drawable_width, drawable_height;
|
||||
struct wined3d_color colour_srgb;
|
||||
struct wined3d_context *context;
|
||||
GLbitfield clear_mask = 0;
|
||||
BOOL render_offscreen;
|
||||
unsigned int i;
|
||||
|
||||
if (rtv && rtv->resource->type != WINED3D_RTYPE_BUFFER)
|
||||
{
|
||||
target = texture_from_resource(rtv->resource);
|
||||
context = context_acquire(device, target, rtv->sub_resource_idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = context_acquire(device, NULL, 0);
|
||||
}
|
||||
context_gl = wined3d_context_gl(context);
|
||||
|
||||
if (dsv && dsv->resource->type != WINED3D_RTYPE_BUFFER)
|
||||
depth_stencil = texture_from_resource(dsv->resource);
|
||||
|
||||
if (!context_gl->valid)
|
||||
{
|
||||
context_release(context);
|
||||
WARN("Invalid context, skipping clear.\n");
|
||||
return;
|
||||
}
|
||||
gl_info = context_gl->gl_info;
|
||||
|
||||
/* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the
|
||||
* drawable. After the clear we'll mark the drawable up to date, so we have to make sure that this is true
|
||||
* for the cleared parts, and the untouched parts.
|
||||
*
|
||||
* If we're clearing the whole target there is no need to copy it into the drawable, it will be overwritten
|
||||
* anyway. If we're not clearing the color buffer we don't have to copy either since we're not going to set
|
||||
* the drawable up to date. We have to check all settings that limit the clear area though. Do not bother
|
||||
* checking all this if the dest surface is in the drawable anyway. */
|
||||
for (i = 0; i < rt_count; ++i)
|
||||
{
|
||||
struct wined3d_rendertarget_view *rtv = fb->render_targets[i];
|
||||
|
||||
if (rtv && rtv->format->id != WINED3DFMT_NULL)
|
||||
{
|
||||
struct wined3d_texture *rt = wined3d_texture_from_resource(rtv->resource);
|
||||
|
||||
if (flags & WINED3DCLEAR_TARGET && !is_full_clear(rt, rtv->sub_resource_idx,
|
||||
draw_rect, rect_count ? clear_rect : NULL))
|
||||
wined3d_texture_load_location(rt, rtv->sub_resource_idx, context, rtv->resource->draw_binding);
|
||||
else
|
||||
wined3d_texture_prepare_location(rt, rtv->sub_resource_idx, context, rtv->resource->draw_binding);
|
||||
}
|
||||
}
|
||||
|
||||
if (target)
|
||||
{
|
||||
render_offscreen = context->render_offscreen;
|
||||
wined3d_rendertarget_view_get_drawable_size(rtv, context, &drawable_width, &drawable_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int ds_level = dsv->sub_resource_idx % depth_stencil->level_count;
|
||||
|
||||
render_offscreen = TRUE;
|
||||
drawable_width = wined3d_texture_get_level_pow2_width(depth_stencil, ds_level);
|
||||
drawable_height = wined3d_texture_get_level_pow2_height(depth_stencil, ds_level);
|
||||
}
|
||||
|
||||
if (depth_stencil)
|
||||
{
|
||||
DWORD ds_location = render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE;
|
||||
struct wined3d_texture *ds = wined3d_texture_from_resource(dsv->resource);
|
||||
|
||||
if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)
|
||||
&& !is_full_clear(ds, dsv->sub_resource_idx, draw_rect, rect_count ? clear_rect : NULL))
|
||||
wined3d_texture_load_location(ds, dsv->sub_resource_idx, context, ds_location);
|
||||
else
|
||||
wined3d_texture_prepare_location(ds, dsv->sub_resource_idx, context, ds_location);
|
||||
|
||||
if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
|
||||
{
|
||||
wined3d_texture_validate_location(ds, dsv->sub_resource_idx, ds_location);
|
||||
wined3d_texture_invalidate_location(ds, dsv->sub_resource_idx, ~ds_location);
|
||||
}
|
||||
}
|
||||
|
||||
if (!wined3d_context_gl_apply_clear_state(context_gl, state, rt_count, fb))
|
||||
{
|
||||
context_release(context);
|
||||
WARN("Failed to apply clear state, skipping clear.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only set the values up once, as they are not changing. */
|
||||
if (flags & WINED3DCLEAR_STENCIL)
|
||||
{
|
||||
if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
|
||||
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE));
|
||||
}
|
||||
gl_info->gl_ops.gl.p_glStencilMask(~0U);
|
||||
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK));
|
||||
gl_info->gl_ops.gl.p_glClearStencil(stencil);
|
||||
checkGLcall("glClearStencil");
|
||||
clear_mask = clear_mask | GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if (flags & WINED3DCLEAR_ZBUFFER)
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glDepthMask(GL_TRUE);
|
||||
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZWRITEENABLE));
|
||||
gl_info->gl_ops.gl.p_glClearDepth(depth);
|
||||
checkGLcall("glClearDepth");
|
||||
clear_mask = clear_mask | GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if (flags & WINED3DCLEAR_TARGET)
|
||||
{
|
||||
for (i = 0; i < rt_count; ++i)
|
||||
{
|
||||
struct wined3d_rendertarget_view *rtv = fb->render_targets[i];
|
||||
struct wined3d_texture *texture;
|
||||
|
||||
if (!rtv)
|
||||
continue;
|
||||
|
||||
if (rtv->resource->type == WINED3D_RTYPE_BUFFER)
|
||||
{
|
||||
FIXME("Not supported on buffer resources.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
texture = texture_from_resource(rtv->resource);
|
||||
wined3d_texture_validate_location(texture, rtv->sub_resource_idx, rtv->resource->draw_binding);
|
||||
wined3d_texture_invalidate_location(texture, rtv->sub_resource_idx, ~rtv->resource->draw_binding);
|
||||
}
|
||||
|
||||
if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && needs_srgb_write(context->d3d_info, state, fb))
|
||||
{
|
||||
if (rt_count > 1)
|
||||
WARN("Clearing multiple sRGB render targets without GL_ARB_framebuffer_sRGB "
|
||||
"support, this might cause graphical issues.\n");
|
||||
|
||||
wined3d_colour_srgb_from_linear(&colour_srgb, color);
|
||||
color = &colour_srgb;
|
||||
}
|
||||
|
||||
gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
context_invalidate_state(context, STATE_BLEND);
|
||||
gl_info->gl_ops.gl.p_glClearColor(color->r, color->g, color->b, color->a);
|
||||
checkGLcall("glClearColor");
|
||||
clear_mask = clear_mask | GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if (!rect_count)
|
||||
{
|
||||
if (render_offscreen)
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glScissor(draw_rect->left, draw_rect->top,
|
||||
draw_rect->right - draw_rect->left, draw_rect->bottom - draw_rect->top);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glScissor(draw_rect->left, drawable_height - draw_rect->bottom,
|
||||
draw_rect->right - draw_rect->left, draw_rect->bottom - draw_rect->top);
|
||||
}
|
||||
gl_info->gl_ops.gl.p_glClear(clear_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
RECT current_rect;
|
||||
|
||||
/* Now process each rect in turn. */
|
||||
for (i = 0; i < rect_count; ++i)
|
||||
{
|
||||
/* Note that GL uses lower left, width/height. */
|
||||
IntersectRect(¤t_rect, draw_rect, &clear_rect[i]);
|
||||
|
||||
TRACE("clear_rect[%u] %s, current_rect %s.\n", i,
|
||||
wine_dbgstr_rect(&clear_rect[i]),
|
||||
wine_dbgstr_rect(¤t_rect));
|
||||
|
||||
/* Tests show that rectangles where x1 > x2 or y1 > y2 are ignored silently.
|
||||
* The rectangle is not cleared, no error is returned, but further rectangles are
|
||||
* still cleared if they are valid. */
|
||||
if (current_rect.left > current_rect.right || current_rect.top > current_rect.bottom)
|
||||
{
|
||||
TRACE("Rectangle with negative dimensions, ignoring.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (render_offscreen)
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glScissor(current_rect.left, current_rect.top,
|
||||
current_rect.right - current_rect.left, current_rect.bottom - current_rect.top);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glScissor(current_rect.left, drawable_height - current_rect.bottom,
|
||||
current_rect.right - current_rect.left, current_rect.bottom - current_rect.top);
|
||||
}
|
||||
gl_info->gl_ops.gl.p_glClear(clear_mask);
|
||||
}
|
||||
}
|
||||
context->scissor_rect_count = WINED3D_MAX_VIEWPORTS;
|
||||
checkGLcall("clear");
|
||||
|
||||
if (flags & WINED3DCLEAR_TARGET && target->swapchain && target->swapchain->front_buffer == target)
|
||||
gl_info->gl_ops.gl.p_glFlush();
|
||||
|
||||
context_release(context);
|
||||
}
|
||||
|
||||
ULONG CDECL wined3d_device_incref(struct wined3d_device *device)
|
||||
{
|
||||
ULONG refcount = InterlockedIncrement(&device->ref);
|
||||
|
|
|
@ -5176,6 +5176,254 @@ static bool ffp_blit_supported(enum wined3d_blit_op blit_op, const struct wined3
|
|||
}
|
||||
}
|
||||
|
||||
static bool is_full_clear(const struct wined3d_texture *texture, unsigned int sub_resource_idx,
|
||||
const RECT *draw_rect, const RECT *clear_rect)
|
||||
{
|
||||
unsigned int width, height, level;
|
||||
|
||||
level = sub_resource_idx % texture->level_count;
|
||||
width = wined3d_texture_get_level_width(texture, level);
|
||||
height = wined3d_texture_get_level_height(texture, level);
|
||||
|
||||
/* partial draw rect */
|
||||
if (draw_rect->left || draw_rect->top || draw_rect->right < width || draw_rect->bottom < height)
|
||||
return false;
|
||||
|
||||
/* partial clear rect */
|
||||
if (clear_rect && (clear_rect->left > 0 || clear_rect->top > 0
|
||||
|| clear_rect->right < width || clear_rect->bottom < height))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ffp_blitter_clear_rendertargets(struct wined3d_device *device, unsigned int rt_count,
|
||||
const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rect, const RECT *draw_rect,
|
||||
uint32_t flags, const struct wined3d_color *colour, float depth, unsigned int stencil)
|
||||
{
|
||||
struct wined3d_rendertarget_view *rtv = rt_count ? fb->render_targets[0] : NULL;
|
||||
struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
|
||||
const struct wined3d_state *state = &device->cs->state;
|
||||
struct wined3d_texture *depth_stencil = NULL;
|
||||
unsigned int drawable_width, drawable_height;
|
||||
const struct wined3d_gl_info *gl_info;
|
||||
struct wined3d_context_gl *context_gl;
|
||||
struct wined3d_texture *target = NULL;
|
||||
struct wined3d_color colour_srgb;
|
||||
struct wined3d_context *context;
|
||||
GLbitfield clear_mask = 0;
|
||||
bool render_offscreen;
|
||||
unsigned int i;
|
||||
|
||||
if (rtv && rtv->resource->type != WINED3D_RTYPE_BUFFER)
|
||||
{
|
||||
target = texture_from_resource(rtv->resource);
|
||||
context = context_acquire(device, target, rtv->sub_resource_idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = context_acquire(device, NULL, 0);
|
||||
}
|
||||
context_gl = wined3d_context_gl(context);
|
||||
|
||||
if (dsv && dsv->resource->type != WINED3D_RTYPE_BUFFER)
|
||||
depth_stencil = texture_from_resource(dsv->resource);
|
||||
|
||||
if (!context_gl->valid)
|
||||
{
|
||||
context_release(context);
|
||||
WARN("Invalid context, skipping clear.\n");
|
||||
return;
|
||||
}
|
||||
gl_info = context_gl->gl_info;
|
||||
|
||||
/* When we're clearing parts of the drawable, make sure that the target
|
||||
* surface is well up to date in the drawable. After the clear we'll mark
|
||||
* the drawable up to date, so we have to make sure that this is true for
|
||||
* the cleared parts, and the untouched parts.
|
||||
*
|
||||
* If we're clearing the whole target there is no need to copy it into the
|
||||
* drawable, it will be overwritten anyway. If we're not clearing the
|
||||
* colour buffer we don't have to copy either since we're not going to set
|
||||
* the drawable up to date. We have to check all settings that limit the
|
||||
* clear area though. Do not bother checking all this if the destination
|
||||
* surface is in the drawable anyway. */
|
||||
for (i = 0; i < rt_count; ++i)
|
||||
{
|
||||
struct wined3d_rendertarget_view *rtv = fb->render_targets[i];
|
||||
|
||||
if (rtv && rtv->format->id != WINED3DFMT_NULL)
|
||||
{
|
||||
struct wined3d_texture *rt = wined3d_texture_from_resource(rtv->resource);
|
||||
|
||||
if (flags & WINED3DCLEAR_TARGET && !is_full_clear(rt, rtv->sub_resource_idx,
|
||||
draw_rect, rect_count ? clear_rect : NULL))
|
||||
wined3d_texture_load_location(rt, rtv->sub_resource_idx, context, rtv->resource->draw_binding);
|
||||
else
|
||||
wined3d_texture_prepare_location(rt, rtv->sub_resource_idx, context, rtv->resource->draw_binding);
|
||||
}
|
||||
}
|
||||
|
||||
if (target)
|
||||
{
|
||||
render_offscreen = context->render_offscreen;
|
||||
wined3d_rendertarget_view_get_drawable_size(rtv, context, &drawable_width, &drawable_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int ds_level = dsv->sub_resource_idx % depth_stencil->level_count;
|
||||
|
||||
render_offscreen = true;
|
||||
drawable_width = wined3d_texture_get_level_pow2_width(depth_stencil, ds_level);
|
||||
drawable_height = wined3d_texture_get_level_pow2_height(depth_stencil, ds_level);
|
||||
}
|
||||
|
||||
if (depth_stencil)
|
||||
{
|
||||
DWORD ds_location = render_offscreen ? dsv->resource->draw_binding : WINED3D_LOCATION_DRAWABLE;
|
||||
struct wined3d_texture *ds = wined3d_texture_from_resource(dsv->resource);
|
||||
|
||||
if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)
|
||||
&& !is_full_clear(ds, dsv->sub_resource_idx, draw_rect, rect_count ? clear_rect : NULL))
|
||||
wined3d_texture_load_location(ds, dsv->sub_resource_idx, context, ds_location);
|
||||
else
|
||||
wined3d_texture_prepare_location(ds, dsv->sub_resource_idx, context, ds_location);
|
||||
|
||||
if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
|
||||
{
|
||||
wined3d_texture_validate_location(ds, dsv->sub_resource_idx, ds_location);
|
||||
wined3d_texture_invalidate_location(ds, dsv->sub_resource_idx, ~ds_location);
|
||||
}
|
||||
}
|
||||
|
||||
if (!wined3d_context_gl_apply_clear_state(context_gl, state, rt_count, fb))
|
||||
{
|
||||
context_release(context);
|
||||
WARN("Failed to apply clear state, skipping clear.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only set the values up once, as they are not changing. */
|
||||
if (flags & WINED3DCLEAR_STENCIL)
|
||||
{
|
||||
if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
|
||||
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE));
|
||||
}
|
||||
gl_info->gl_ops.gl.p_glStencilMask(~0u);
|
||||
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK));
|
||||
gl_info->gl_ops.gl.p_glClearStencil(stencil);
|
||||
checkGLcall("glClearStencil");
|
||||
clear_mask = clear_mask | GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if (flags & WINED3DCLEAR_ZBUFFER)
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glDepthMask(GL_TRUE);
|
||||
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZWRITEENABLE));
|
||||
gl_info->gl_ops.gl.p_glClearDepth(depth);
|
||||
checkGLcall("glClearDepth");
|
||||
clear_mask = clear_mask | GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if (flags & WINED3DCLEAR_TARGET)
|
||||
{
|
||||
for (i = 0; i < rt_count; ++i)
|
||||
{
|
||||
struct wined3d_rendertarget_view *rtv = fb->render_targets[i];
|
||||
struct wined3d_texture *texture;
|
||||
|
||||
if (!rtv)
|
||||
continue;
|
||||
|
||||
if (rtv->resource->type == WINED3D_RTYPE_BUFFER)
|
||||
{
|
||||
FIXME("Not supported on buffer resources.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
texture = texture_from_resource(rtv->resource);
|
||||
wined3d_texture_validate_location(texture, rtv->sub_resource_idx, rtv->resource->draw_binding);
|
||||
wined3d_texture_invalidate_location(texture, rtv->sub_resource_idx, ~rtv->resource->draw_binding);
|
||||
}
|
||||
|
||||
if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && needs_srgb_write(context->d3d_info, state, fb))
|
||||
{
|
||||
if (rt_count > 1)
|
||||
WARN("Clearing multiple sRGB render targets without GL_ARB_framebuffer_sRGB "
|
||||
"support, this might cause graphical issues.\n");
|
||||
|
||||
wined3d_colour_srgb_from_linear(&colour_srgb, colour);
|
||||
colour = &colour_srgb;
|
||||
}
|
||||
|
||||
gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
context_invalidate_state(context, STATE_BLEND);
|
||||
gl_info->gl_ops.gl.p_glClearColor(colour->r, colour->g, colour->b, colour->a);
|
||||
checkGLcall("glClearColor");
|
||||
clear_mask = clear_mask | GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if (!rect_count)
|
||||
{
|
||||
if (render_offscreen)
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glScissor(draw_rect->left, draw_rect->top,
|
||||
draw_rect->right - draw_rect->left, draw_rect->bottom - draw_rect->top);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glScissor(draw_rect->left, drawable_height - draw_rect->bottom,
|
||||
draw_rect->right - draw_rect->left, draw_rect->bottom - draw_rect->top);
|
||||
}
|
||||
gl_info->gl_ops.gl.p_glClear(clear_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
RECT current_rect;
|
||||
|
||||
/* Now process each rect in turn. */
|
||||
for (i = 0; i < rect_count; ++i)
|
||||
{
|
||||
/* Note that GL uses lower left, width/height. */
|
||||
IntersectRect(¤t_rect, draw_rect, &clear_rect[i]);
|
||||
|
||||
TRACE("clear_rect[%u] %s, current_rect %s.\n", i,
|
||||
wine_dbgstr_rect(&clear_rect[i]),
|
||||
wine_dbgstr_rect(¤t_rect));
|
||||
|
||||
/* Tests show that rectangles where x1 > x2 or y1 > y2 are ignored
|
||||
* silently. The rectangle is not cleared, no error is returned,
|
||||
* but further rectangles are still cleared if they are valid. */
|
||||
if (current_rect.left > current_rect.right || current_rect.top > current_rect.bottom)
|
||||
{
|
||||
TRACE("Rectangle with negative dimensions, ignoring.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (render_offscreen)
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glScissor(current_rect.left, current_rect.top,
|
||||
current_rect.right - current_rect.left, current_rect.bottom - current_rect.top);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glScissor(current_rect.left, drawable_height - current_rect.bottom,
|
||||
current_rect.right - current_rect.left, current_rect.bottom - current_rect.top);
|
||||
}
|
||||
gl_info->gl_ops.gl.p_glClear(clear_mask);
|
||||
}
|
||||
}
|
||||
context->scissor_rect_count = WINED3D_MAX_VIEWPORTS;
|
||||
checkGLcall("clear");
|
||||
|
||||
if (flags & WINED3DCLEAR_TARGET && target->swapchain && target->swapchain->front_buffer == target)
|
||||
gl_info->gl_ops.gl.p_glFlush();
|
||||
|
||||
context_release(context);
|
||||
}
|
||||
|
||||
static bool ffp_blitter_use_cpu_clear(struct wined3d_rendertarget_view *view)
|
||||
{
|
||||
struct wined3d_resource *resource;
|
||||
|
@ -5262,7 +5510,7 @@ static void ffp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de
|
|||
|
||||
if (have_identical_size)
|
||||
{
|
||||
device_clear_render_targets(device, rt_count, fb, rect_count,
|
||||
ffp_blitter_clear_rendertargets(device, rt_count, fb, rect_count,
|
||||
clear_rects, draw_rect, flags, colour, depth, stencil);
|
||||
}
|
||||
else
|
||||
|
@ -5274,14 +5522,14 @@ static void ffp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de
|
|||
|
||||
tmp_fb.render_targets[0] = view;
|
||||
tmp_fb.depth_stencil = NULL;
|
||||
device_clear_render_targets(device, 1, &tmp_fb, rect_count,
|
||||
ffp_blitter_clear_rendertargets(device, 1, &tmp_fb, rect_count,
|
||||
clear_rects, draw_rect, WINED3DCLEAR_TARGET, colour, depth, stencil);
|
||||
}
|
||||
if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
|
||||
{
|
||||
tmp_fb.render_targets[0] = NULL;
|
||||
tmp_fb.depth_stencil = fb->depth_stencil;
|
||||
device_clear_render_targets(device, 0, &tmp_fb, rect_count,
|
||||
ffp_blitter_clear_rendertargets(device, 0, &tmp_fb, rect_count,
|
||||
clear_rects, draw_rect, flags & ~WINED3DCLEAR_TARGET, colour, depth, stencil);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3431,9 +3431,6 @@ struct wined3d_device
|
|||
};
|
||||
|
||||
void wined3d_device_cleanup(struct wined3d_device *device) DECLSPEC_HIDDEN;
|
||||
void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, const struct wined3d_fb_state *fb,
|
||||
UINT rect_count, const RECT *rects, const RECT *draw_rect, DWORD flags,
|
||||
const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN;
|
||||
BOOL device_context_add(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
|
||||
void device_context_remove(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
|
||||
void wined3d_device_create_default_samplers(struct wined3d_device *device,
|
||||
|
|
Loading…
Reference in New Issue