From 243db4980c77e9d55b016ea79c4ddf075101bde0 Mon Sep 17 00:00:00 2001 From: Jan Zielinski Date: Tue, 2 Jul 2019 16:44:34 +0200 Subject: [PATCH] swr/swr: Enable ARB_viewport_array The rasterizer core supported ARB_viewport_array, but the swr layer connecting core to Gallium state tracker only allowed one viewport. We add support for multiple viewports to swr layer. Reviewed-by: Alok Hota --- docs/features.txt | 2 +- src/gallium/drivers/swr/swr_clear.cpp | 2 +- src/gallium/drivers/swr/swr_context.cpp | 5 +- src/gallium/drivers/swr/swr_context.h | 6 +- src/gallium/drivers/swr/swr_screen.cpp | 2 +- src/gallium/drivers/swr/swr_shader.cpp | 3 + src/gallium/drivers/swr/swr_state.cpp | 88 ++++++++++++++----------- src/gallium/drivers/swr/swr_state.h | 2 +- 8 files changed, 61 insertions(+), 49 deletions(-) diff --git a/docs/features.txt b/docs/features.txt index acb59113ac4..a0952dd4663 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -146,7 +146,7 @@ GL 4.1, GLSL 4.10 --- all DONE: i965/gen7+, nvc0, r600, radeonsi, virgl GL_ARB_separate_shader_objects DONE (all drivers) GL_ARB_shader_precision DONE (i965/gen7+, all drivers that support GLSL 4.10) GL_ARB_vertex_attrib_64bit DONE (i965/gen7+, llvmpipe, softpipe, swr) - GL_ARB_viewport_array DONE (i965, nv50, llvmpipe, softpipe) + GL_ARB_viewport_array DONE (i965, nv50, llvmpipe, softpipe, swr) GL 4.2, GLSL 4.20 -- all DONE: i965/gen7+, nvc0, r600, radeonsi, virgl diff --git a/src/gallium/drivers/swr/swr_clear.cpp b/src/gallium/drivers/swr/swr_clear.cpp index 233432ee34a..3e02bda19c9 100644 --- a/src/gallium/drivers/swr/swr_clear.cpp +++ b/src/gallium/drivers/swr/swr_clear.cpp @@ -71,7 +71,7 @@ swr_clear(struct pipe_context *pipe, SWR_RECT clear_rect; /* If enabled, clear to scissor; otherwise clear full surface */ if (ctx->rasterizer && ctx->rasterizer->scissor) { - clear_rect = ctx->swr_scissor; + clear_rect = ctx->swr_scissors[0]; } else { clear_rect = {0, 0, (int32_t)fb->width, (int32_t)fb->height}; } diff --git a/src/gallium/drivers/swr/swr_context.cpp b/src/gallium/drivers/swr/swr_context.cpp index 7aa14d60710..ea3ab6a657d 100644 --- a/src/gallium/drivers/swr/swr_context.cpp +++ b/src/gallium/drivers/swr/swr_context.cpp @@ -325,8 +325,8 @@ swr_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info) ctx->num_so_targets, (struct pipe_stream_output_target **)ctx->so_targets); util_blitter_save_rasterizer(ctx->blitter, (void *)ctx->rasterizer); - util_blitter_save_viewport(ctx->blitter, &ctx->viewport); - util_blitter_save_scissor(ctx->blitter, &ctx->scissor); + util_blitter_save_viewport(ctx->blitter, &ctx->viewports[0]); + util_blitter_save_scissor(ctx->blitter, &ctx->scissors[0]); util_blitter_save_fragment_shader(ctx->blitter, ctx->fs); util_blitter_save_blend(ctx->blitter, (void *)ctx->blend); util_blitter_save_depth_stencil_alpha(ctx->blitter, @@ -403,6 +403,7 @@ swr_destroy(struct pipe_context *pipe) swr_destroy_scratch_buffers(ctx); + /* Only update screen->pipe if current context is being destroyed */ assert(screen); if (screen->pipe == pipe) diff --git a/src/gallium/drivers/swr/swr_context.h b/src/gallium/drivers/swr/swr_context.h index 5c280ee365c..b207c02ca8a 100644 --- a/src/gallium/drivers/swr/swr_context.h +++ b/src/gallium/drivers/swr/swr_context.h @@ -132,12 +132,12 @@ struct swr_context { constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; struct pipe_framebuffer_state framebuffer; struct swr_poly_stipple poly_stipple; - struct pipe_scissor_state scissor; - SWR_RECT swr_scissor; + struct pipe_scissor_state scissors[KNOB_NUM_VIEWPORTS_SCISSORS]; + SWR_RECT swr_scissors[KNOB_NUM_VIEWPORTS_SCISSORS]; struct pipe_sampler_view * sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS]; - struct pipe_viewport_state viewport; + struct pipe_viewport_state viewports[KNOB_NUM_VIEWPORTS_SCISSORS]; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; struct blitter_context *blitter; diff --git a/src/gallium/drivers/swr/swr_screen.cpp b/src/gallium/drivers/swr/swr_screen.cpp index 5789af152fb..464cbf4f3fb 100644 --- a/src/gallium/drivers/swr/swr_screen.cpp +++ b/src/gallium/drivers/swr/swr_screen.cpp @@ -218,7 +218,7 @@ swr_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: return 1; case PIPE_CAP_MAX_VIEWPORTS: - return 1; + return KNOB_NUM_VIEWPORTS_SCISSORS; case PIPE_CAP_ENDIANNESS: return PIPE_ENDIAN_NATIVE; case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE: diff --git a/src/gallium/drivers/swr/swr_shader.cpp b/src/gallium/drivers/swr/swr_shader.cpp index afa184fc466..6ec492c4102 100644 --- a/src/gallium/drivers/swr/swr_shader.cpp +++ b/src/gallium/drivers/swr/swr_shader.cpp @@ -424,6 +424,9 @@ BuilderSWR::swr_gs_llvm_emit_vertex(const struct lp_build_tgsi_gs_iface *gs_base } else if (iface->info->output_semantic_name[attrib] == TGSI_SEMANTIC_LAYER) { attribSlot = VERTEX_SGV_SLOT; sgvChannel = VERTEX_SGV_RTAI_COMP; + } else if (iface->info->output_semantic_name[attrib] == TGSI_SEMANTIC_VIEWPORT_INDEX) { + attribSlot = VERTEX_SGV_SLOT; + sgvChannel = VERTEX_SGV_VAI_COMP; } else if (iface->info->output_semantic_name[attrib] == TGSI_SEMANTIC_POSITION) { attribSlot = VERTEX_POSITION_SLOT; } else { diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp index e7f1c99b974..42b3fe4d68d 100644 --- a/src/gallium/drivers/swr/swr_state.cpp +++ b/src/gallium/drivers/swr/swr_state.cpp @@ -425,9 +425,7 @@ swr_create_gs_state(struct pipe_context *pipe, return NULL; swr_gs->pipe.tokens = tgsi_dup_tokens(gs->tokens); - lp_build_tgsi_info(gs->tokens, &swr_gs->info); - return swr_gs; } @@ -615,16 +613,21 @@ swr_set_clip_state(struct pipe_context *pipe, static void swr_set_scissor_states(struct pipe_context *pipe, unsigned start_slot, - unsigned num_viewports, - const struct pipe_scissor_state *scissor) + unsigned num_scissors, + const struct pipe_scissor_state *scissors) { struct swr_context *ctx = swr_context(pipe); - ctx->scissor = *scissor; - ctx->swr_scissor.xmin = scissor->minx; - ctx->swr_scissor.xmax = scissor->maxx; - ctx->swr_scissor.ymin = scissor->miny; - ctx->swr_scissor.ymax = scissor->maxy; + memcpy(ctx->scissors + start_slot, scissors, + sizeof(struct pipe_scissor_state) * num_scissors); + + for (unsigned i = 0; i < num_scissors; i++) { + auto idx = start_slot + i; + ctx->swr_scissors[idx].xmin = scissors[idx].minx; + ctx->swr_scissors[idx].xmax = scissors[idx].maxx; + ctx->swr_scissors[idx].ymin = scissors[idx].miny; + ctx->swr_scissors[idx].ymax = scissors[idx].maxy; + } ctx->dirty |= SWR_NEW_SCISSOR; } @@ -636,7 +639,7 @@ swr_set_viewport_states(struct pipe_context *pipe, { struct swr_context *ctx = swr_context(pipe); - ctx->viewport = *vpt; + memcpy(ctx->viewports + start_slot, vpt, sizeof(struct pipe_viewport_state) * num_viewports); ctx->dirty |= SWR_NEW_VIEWPORT; } @@ -1202,41 +1205,46 @@ swr_update_derived(struct pipe_context *pipe, /* Viewport */ if (ctx->dirty & (SWR_NEW_VIEWPORT | SWR_NEW_FRAMEBUFFER | SWR_NEW_RASTERIZER)) { - pipe_viewport_state *state = &ctx->viewport; + pipe_viewport_state *state = &ctx->viewports[0]; pipe_framebuffer_state *fb = &ctx->framebuffer; pipe_rasterizer_state *rasterizer = ctx->rasterizer; - SWR_VIEWPORT *vp = &ctx->derived.vp; + SWR_VIEWPORT *vp = &ctx->derived.vp[0]; SWR_VIEWPORT_MATRICES *vpm = &ctx->derived.vpm; - vp->x = state->translate[0] - state->scale[0]; - vp->width = 2 * state->scale[0]; - vp->y = state->translate[1] - fabs(state->scale[1]); - vp->height = 2 * fabs(state->scale[1]); - util_viewport_zmin_zmax(state, rasterizer->clip_halfz, - &vp->minZ, &vp->maxZ); - - vpm->m00[0] = state->scale[0]; - vpm->m11[0] = state->scale[1]; - vpm->m22[0] = state->scale[2]; - vpm->m30[0] = state->translate[0]; - vpm->m31[0] = state->translate[1]; - vpm->m32[0] = state->translate[2]; - - /* Now that the matrix is calculated, clip the view coords to screen - * size. OpenGL allows for -ve x,y in the viewport. */ - if (vp->x < 0.0f) { - vp->width += vp->x; - vp->x = 0.0f; - } - if (vp->y < 0.0f) { - vp->height += vp->y; - vp->y = 0.0f; - } - vp->width = std::min(vp->width, (float)fb->width - vp->x); - vp->height = std::min(vp->height, (float)fb->height - vp->y); + for (unsigned i = 0; i < KNOB_NUM_VIEWPORTS_SCISSORS; i++) { + vp->x = state->translate[0] - state->scale[0]; + vp->width = 2 * state->scale[0]; + vp->y = state->translate[1] - fabs(state->scale[1]); + vp->height = 2 * fabs(state->scale[1]); + util_viewport_zmin_zmax(state, rasterizer->clip_halfz, + &vp->minZ, &vp->maxZ); + + vpm->m00[i] = state->scale[0]; + vpm->m11[i] = state->scale[1]; + vpm->m22[i] = state->scale[2]; + vpm->m30[i] = state->translate[0]; + vpm->m31[i] = state->translate[1]; + vpm->m32[i] = state->translate[2]; + + /* Now that the matrix is calculated, clip the view coords to screen + * size. OpenGL allows for -ve x,y in the viewport. */ + if (vp->x < 0.0f) { + vp->width += vp->x; + vp->x = 0.0f; + } + if (vp->y < 0.0f) { + vp->height += vp->y; + vp->y = 0.0f; + } + vp->width = std::min(vp->width, (float) fb->width - vp->x); + vp->height = std::min(vp->height, (float) fb->height - vp->y); - ctx->api.pfnSwrSetViewports(ctx->swrContext, 1, vp, vpm); + vp++; + state++; + } + ctx->api.pfnSwrSetViewports(ctx->swrContext, KNOB_NUM_VIEWPORTS_SCISSORS, + &ctx->derived.vp[0], &ctx->derived.vpm); } /* When called from swr_clear (p_draw_info = null), render targets, @@ -1253,7 +1261,7 @@ swr_update_derived(struct pipe_context *pipe, /* Scissor */ if (ctx->dirty & SWR_NEW_SCISSOR) { - ctx->api.pfnSwrSetScissorRects(ctx->swrContext, 1, &ctx->swr_scissor); + ctx->api.pfnSwrSetScissorRects(ctx->swrContext, KNOB_NUM_VIEWPORTS_SCISSORS, ctx->swr_scissors); } /* Set vertex & index buffers */ diff --git a/src/gallium/drivers/swr/swr_state.h b/src/gallium/drivers/swr/swr_state.h index 7940a960d93..45d0925e8e7 100644 --- a/src/gallium/drivers/swr/swr_state.h +++ b/src/gallium/drivers/swr/swr_state.h @@ -103,7 +103,7 @@ struct swr_poly_stipple { */ struct swr_derived_state { SWR_RASTSTATE rastState; - SWR_VIEWPORT vp; + SWR_VIEWPORT vp[KNOB_NUM_VIEWPORTS_SCISSORS]; SWR_VIEWPORT_MATRICES vpm; }; -- 2.30.2