[PATCH 1/2] wined3d: Add support for setting multiple scissor rectangles.
Henri Verbeet
hverbeet at gmail.com
Thu Apr 19 09:42:04 CDT 2018
On 19 April 2018 at 08:50, Nikolay Sivov <nsivov at codeweavers.com> wrote:
> @@ -4770,25 +4770,44 @@ static void light(struct wined3d_context *context, const struct wined3d_state *s
> static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
> {
> const struct wined3d_gl_info *gl_info = context->gl_info;
> - const RECT *r = &state->scissor_rect;
> + unsigned int height = 0;
> + const RECT *r;
>
> /* Warning: glScissor uses window coordinates, not viewport coordinates,
> * so our viewport correction does not apply. Warning2: Even in windowed
> * mode the coords are relative to the window, not the screen. */
> - TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r));
>
> - if (context->render_offscreen)
> - {
> - gl_info->gl_ops.gl.p_glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top);
> - }
> - else
> + if (!context->render_offscreen)
> {
> const struct wined3d_rendertarget_view *target = state->fb->render_targets[0];
> - UINT height;
> - UINT width;
> + unsigned int width;
>
> wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height);
> - gl_info->gl_ops.gl.p_glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
> + }
> +
> + if (gl_info->supported[ARB_VIEWPORT_ARRAY])
> + {
> + unsigned int i;
> +
> + for (i = 0; i < state->scissor_rect_count; ++i)
> + {
> + r = &state->scissor_rects[i];
> + GL_EXTCALL(glScissorIndexed(i, r->left, height ? height - r->top : r->top,
> + r->right - r->left, r->bottom - r->top));
> + }
> +
> + if (state->viewport_count > state->scissor_rect_count)
> + {
> + static const GLint reset[4 * WINED3D_MAX_VIEWPORTS];
> + unsigned int reset_count = state->viewport_count - state->scissor_rect_count;
> + GL_EXTCALL(glScissorArrayv(state->scissor_rect_count, reset_count, reset));
> + }
Does this also do the right thing if the viewport count is changed
after setting the scissor rectangles?
> @@ -825,12 +825,17 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock)
> memset(stateblock->state.viewports, 0, sizeof(*stateblock->state.viewports));
> }
>
> - if (stateblock->changed.scissorRect && memcmp(&src_state->scissor_rect,
> - &stateblock->state.scissor_rect, sizeof(stateblock->state.scissor_rect)))
> + if (stateblock->changed.scissorRect
> + && (src_state->scissor_rect_count != stateblock->state.scissor_rect_count
> + || memcmp(src_state->scissor_rects, stateblock->state.scissor_rects,
> + src_state->scissor_rect_count * sizeof(*stateblock->state.scissor_rects))))
> {
> - TRACE("Updating scissor rect.\n");
> + TRACE("Updating scissor rects.\n");
>
> - stateblock->state.scissor_rect = src_state->scissor_rect;
> + if ((stateblock->state.scissor_rect_count = src_state->scissor_rect_count))
> + memcpy(stateblock->state.scissor_rects, src_state->scissor_rects, sizeof(src_state->scissor_rects));
> + else
> + SetRectEmpty(stateblock->state.scissor_rects);
This works, but is it intentional to copy the entire array in the
non-zero scissor rect count case?
More information about the wine-devel
mailing list