[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