Commit 243db498 authored by Jan Zielinski's avatar Jan Zielinski

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's avatarAlok Hota <alok.hota@intel.com>
parent c6cb9b19
......@@ -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
......
......@@ -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};
}
......
......@@ -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)
......
......@@ -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;
......
......@@ -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:
......
......@@ -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 {
......
......@@ -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 */
......
......@@ -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;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment