Functionally identical but much simpler. Should also better integrate with future layer/viewport changes/fixes. Cc: 10.1 <mesa-stable at lists.freedesktop.org> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu> --- Not *strictly* necessary in stable, but it will make backporting later fixes easier. No regressions in piglit. src/gallium/drivers/nouveau/nv50/nv50_program.c | 5 +---- src/gallium/drivers/nouveau/nv50/nv50_program.h | 1 - src/gallium/drivers/nouveau/nv50/nv50_shader_state.c | 4 +++- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/nouveau/nv50/nv50_program.c b/src/gallium/drivers/nouveau/nv50/nv50_program.c index 636ef87..f14d3ef 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_program.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_program.c @@ -170,10 +170,8 @@ nv50_fragprog_assign_slots(struct nv50_ir_prog_info *info) if (info->in[i].sn == TGSI_SEMANTIC_COLOR) prog->vp.bfc[info->in[i].si] = j; - else if (info->in[i].sn == TGSI_SEMANTIC_PRIMID) { + else if (info->in[i].sn == TGSI_SEMANTIC_PRIMID) prog->vp.attrs[2] |= NV50_3D_VP_GP_BUILTIN_ATTR_EN_PRIMITIVE_ID; - prog->gp.primid = j; - } prog->in[j].id = i; prog->in[j].mask = info->in[i].mask; @@ -345,7 +343,6 @@ nv50_program_translate(struct nv50_program *prog, uint16_t chipset) prog->vp.clpd[0] = map_undef; prog->vp.clpd[1] = map_undef; prog->vp.psiz = map_undef; - prog->gp.primid = 0x80; prog->gp.has_layer = 0; info->driverPriv = prog; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_program.h b/src/gallium/drivers/nouveau/nv50/nv50_program.h index 5b092bd..75de007 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_program.h +++ b/src/gallium/drivers/nouveau/nv50/nv50_program.h @@ -88,7 +88,6 @@ struct nv50_program { struct { uint32_t vert_count; - ubyte primid; /* primitive id output register */ uint8_t prim_type; /* point, line strip or tri strip */ bool has_layer; ubyte layerid; /* hw value of layer output */ diff --git a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c index 9a43502..f8b1c1b 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c @@ -401,8 +401,10 @@ nv50_fp_linkage_validate(struct nv50_context *nv50) if (vp->out[n].sn == fp->in[i].sn && vp->out[n].si == fp->in[i].si) break; - if (i == fp->gp.primid) { + switch (fp->in[i].sn) { + case TGSI_SEMANTIC_PRIMID: primid = m; + break; } m = nv50_vec4_map(map, m, lin, &fp->in[i], (n < vp->out_nr) ? &vp->out[n] : &dummy); -- 1.8.3.2
Ilia Mirkin
2014-Feb-04 07:06 UTC
[Nouveau] [PATCH 2/3] nv50: fix layerid to be the fp input number rather than vp output number
In the tests they were the same so it didn't matter, but indications are that this is the correct behaviour. Also take this opportunity to (trivially) support using gl_Layer in fp. Cc: 10.1 <mesa-stable at lists.freedesktop.org> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu> --- No regressions in piglit. Pretty sure that rewriting some of the gl_Layer-using tests to have gp out's would have caused failures. Also this gets rid of C99 stuff. src/gallium/drivers/nouveau/nv50/nv50_program.c | 2 +- src/gallium/drivers/nouveau/nv50/nv50_program.h | 2 +- src/gallium/drivers/nouveau/nv50/nv50_shader_state.c | 12 +++++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/nouveau/nv50/nv50_program.c b/src/gallium/drivers/nouveau/nv50/nv50_program.c index f14d3ef..e506438 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_program.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_program.c @@ -104,7 +104,7 @@ nv50_vertprog_assign_slots(struct nv50_ir_prog_info *info) prog->vp.bfc[info->out[i].si] = i; break; case TGSI_SEMANTIC_LAYER: - prog->gp.has_layer = true; + prog->gp.has_layer = TRUE; prog->gp.layerid = n; break; default: diff --git a/src/gallium/drivers/nouveau/nv50/nv50_program.h b/src/gallium/drivers/nouveau/nv50/nv50_program.h index 75de007..8c1b327 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_program.h +++ b/src/gallium/drivers/nouveau/nv50/nv50_program.h @@ -89,7 +89,7 @@ struct nv50_program { struct { uint32_t vert_count; uint8_t prim_type; /* point, line strip or tri strip */ - bool has_layer; + uint8_t has_layer; ubyte layerid; /* hw value of layer output */ } gp; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c index f8b1c1b..129ed2a 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c @@ -346,7 +346,7 @@ nv50_fp_linkage_validate(struct nv50_context *nv50) struct nv50_varying dummy; int i, n, c, m; uint32_t primid = 0; - uint32_t layerid = vp->gp.layerid; + uint32_t layerid = 0; uint32_t psiz = 0x000; uint32_t interp = fp->fp.interp; uint32_t colors = fp->fp.colors; @@ -405,15 +405,17 @@ nv50_fp_linkage_validate(struct nv50_context *nv50) case TGSI_SEMANTIC_PRIMID: primid = m; break; + case TGSI_SEMANTIC_LAYER: + layerid = m; + break; } m = nv50_vec4_map(map, m, lin, &fp->in[i], (n < vp->out_nr) ? &vp->out[n] : &dummy); } - if (vp->gp.has_layer) { - // In GL4.x, layer can be an fp input, but not in 3.x. Make sure to add - // it to the output map. - map[m++] = layerid; + if (vp->gp.has_layer && !layerid) { + layerid = m; + map[m++] = vp->gp.layerid; } if (nv50->rast->pipe.point_size_per_vertex) { -- 1.8.3.2
Ilia Mirkin
2014-Feb-04 07:06 UTC
[Nouveau] [PATCH 3/3] nv50: implement multiple viewports/scissors, enable ARB_viewport_array
Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu> --- This was tested along with airlied's patches to add support to mesa/st. With the piglit tests modified to emit the viewport index for every vertex, this passes all but the minmax test (it wants a viewport of 16K while we only offer 8K). No apparent piglit regressions. .../drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | 1 + src/gallium/drivers/nouveau/nv50/nv50_context.h | 6 +- src/gallium/drivers/nouveau/nv50/nv50_program.c | 5 + src/gallium/drivers/nouveau/nv50/nv50_program.h | 2 + src/gallium/drivers/nouveau/nv50/nv50_screen.c | 20 ++-- src/gallium/drivers/nouveau/nv50/nv50_screen.h | 2 + .../drivers/nouveau/nv50/nv50_shader_state.c | 15 ++- src/gallium/drivers/nouveau/nv50/nv50_state.c | 28 +++-- .../drivers/nouveau/nv50/nv50_state_validate.c | 113 +++++++++++++-------- 9 files changed, 136 insertions(+), 56 deletions(-) diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp index 33ebb54..51d3d08 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp @@ -1031,6 +1031,7 @@ bool Source::scanInstruction(const struct tgsi_full_instruction *inst) if (info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_PSIZE || info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_PRIMID || info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_LAYER || + info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_VIEWPORT_INDEX || info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_FOG) info->out[dst.getIndex(0)].mask &= 1; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.h b/src/gallium/drivers/nouveau/nv50/nv50_context.h index 1ce52c9..57a3090 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_context.h +++ b/src/gallium/drivers/nouveau/nv50/nv50_context.h @@ -163,8 +163,10 @@ struct nv50_context { struct pipe_blend_color blend_colour; struct pipe_stencil_ref stencil_ref; struct pipe_poly_stipple stipple; - struct pipe_scissor_state scissor; - struct pipe_viewport_state viewport; + struct pipe_scissor_state scissors[NV50_MAX_VIEWPORTS]; + unsigned scissors_dirty; + struct pipe_viewport_state viewports[NV50_MAX_VIEWPORTS]; + unsigned viewports_dirty; struct pipe_clip_state clip; unsigned sample_mask; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_program.c b/src/gallium/drivers/nouveau/nv50/nv50_program.c index e506438..0e06125 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_program.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_program.c @@ -107,6 +107,10 @@ nv50_vertprog_assign_slots(struct nv50_ir_prog_info *info) prog->gp.has_layer = TRUE; prog->gp.layerid = n; break; + case TGSI_SEMANTIC_VIEWPORT_INDEX: + prog->gp.has_viewport = true; + prog->gp.viewportid = n; + break; default: break; } @@ -344,6 +348,7 @@ nv50_program_translate(struct nv50_program *prog, uint16_t chipset) prog->vp.clpd[1] = map_undef; prog->vp.psiz = map_undef; prog->gp.has_layer = 0; + prog->gp.has_viewport = 0; info->driverPriv = prog; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_program.h b/src/gallium/drivers/nouveau/nv50/nv50_program.h index 8c1b327..87b0679 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_program.h +++ b/src/gallium/drivers/nouveau/nv50/nv50_program.h @@ -91,6 +91,8 @@ struct nv50_program { uint8_t prim_type; /* point, line strip or tri strip */ uint8_t has_layer; ubyte layerid; /* hw value of layer output */ + uint8_t has_viewport; + ubyte viewportid; /* hw value of viewport index output */ } gp; void *fixups; /* relocation records */ diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c index 5bb341d..bdfb931 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -196,6 +196,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return PIPE_ENDIAN_LITTLE; case PIPE_CAP_TGSI_VS_LAYER: return 0; + case PIPE_CAP_MAX_VIEWPORTS: + return NV50_MAX_VIEWPORTS; default: NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); return 0; @@ -524,9 +526,11 @@ nv50_screen_init_hwctx(struct nv50_screen *screen) BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1); PUSH_DATA (push, 1); - BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2); - PUSH_DATAf(push, 0.0f); - PUSH_DATAf(push, 1.0f); + for (i = 0; i < NV50_MAX_VIEWPORTS; i++) { + BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(i)), 2); + PUSH_DATAf(push, 0.0f); + PUSH_DATAf(push, 1.0f); + } BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1); #ifdef NV50_SCISSORS_CLIPPING @@ -541,10 +545,12 @@ nv50_screen_init_hwctx(struct nv50_screen *screen) /* We use scissors instead of exact view volume clipping, * so they're always enabled. */ - BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 3); - PUSH_DATA (push, 1); - PUSH_DATA (push, 8192 << 16); - PUSH_DATA (push, 8192 << 16); + for (i = 0; i < NV50_MAX_VIEWPORTS; i++) { + BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(i)), 3); + PUSH_DATA (push, 1); + PUSH_DATA (push, 8192 << 16); + PUSH_DATA (push, 8192 << 16); + } BEGIN_NV04(push, NV50_3D(RASTERIZE_ENABLE), 1); PUSH_DATA (push, 1); diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.h b/src/gallium/drivers/nouveau/nv50/nv50_screen.h index 091a392..f8ce365 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.h +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.h @@ -21,6 +21,8 @@ struct nv50_context; #define NV50_SCREEN_RESIDENT_BO_COUNT 5 +#define NV50_MAX_VIEWPORTS 16 + struct nv50_blitter; struct nv50_screen { diff --git a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c index 129ed2a..28cff8b 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c @@ -347,6 +347,7 @@ nv50_fp_linkage_validate(struct nv50_context *nv50) int i, n, c, m; uint32_t primid = 0; uint32_t layerid = 0; + uint32_t viewportid = 0; uint32_t psiz = 0x000; uint32_t interp = fp->fp.interp; uint32_t colors = fp->fp.colors; @@ -408,6 +409,9 @@ nv50_fp_linkage_validate(struct nv50_context *nv50) case TGSI_SEMANTIC_LAYER: layerid = m; break; + case TGSI_SEMANTIC_VIEWPORT_INDEX: + viewportid = m; + break; } m = nv50_vec4_map(map, m, lin, &fp->in[i], (n < vp->out_nr) ? &vp->out[n] : &dummy); @@ -418,6 +422,11 @@ nv50_fp_linkage_validate(struct nv50_context *nv50) map[m++] = vp->gp.layerid; } + if (vp->gp.has_viewport && !viewportid) { + viewportid = m; + map[m++] = vp->gp.viewportid; + } + if (nv50->rast->pipe.point_size_per_vertex) { psiz = (m << 4) | 1; map[m++] = vp->vp.psiz; @@ -472,12 +481,16 @@ nv50_fp_linkage_validate(struct nv50_context *nv50) PUSH_DATAp(push, map, n); } - BEGIN_NV04(push, NV50_3D(SEMANTIC_COLOR), 4); + BEGIN_NV04(push, NV50_3D(GP_VIEWPORT_ID_ENABLE), 5); + PUSH_DATA (push, vp->gp.has_viewport); PUSH_DATA (push, colors); PUSH_DATA (push, (vp->vp.clpd_nr << 8) | 4); PUSH_DATA (push, layerid); PUSH_DATA (push, psiz); + BEGIN_NV04(push, NV50_3D(SEMANTIC_VIEWPORT), 1); + PUSH_DATA (push, viewportid); + BEGIN_NV04(push, NV50_3D(LAYER), 1); PUSH_DATA (push, vp->gp.has_layer << 16); diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state.c b/src/gallium/drivers/nouveau/nv50/nv50_state.c index 247f295..288ba46 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_state.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_state.c @@ -235,8 +235,10 @@ nv50_rasterizer_state_create(struct pipe_context *pipe, so->pipe = *cso; #ifndef NV50_SCISSORS_CLIPPING - SB_BEGIN_3D(so, SCISSOR_ENABLE(0), 1); - SB_DATA (so, cso->scissor); + for (int i = 0; i < NV50_MAX_VIEWPORTS; i++) { + SB_BEGIN_3D(so, SCISSOR_ENABLE(i), 1); + SB_DATA (so, cso->scissor); + } #endif SB_BEGIN_3D(so, SHADE_MODEL, 1); @@ -903,9 +905,16 @@ nv50_set_scissor_states(struct pipe_context *pipe, const struct pipe_scissor_state *scissor) { struct nv50_context *nv50 = nv50_context(pipe); + int i; - nv50->scissor = *scissor; - nv50->dirty |= NV50_NEW_SCISSOR; + assert(start_slot + num_scissors <= NV50_MAX_VIEWPORTS); + for (i = 0; i < num_scissors; i++) { + if (!memcmp(&nv50->scissors[start_slot + i], &scissor[i], sizeof(*scissor))) + continue; + nv50->scissors[start_slot + i] = scissor[i]; + nv50->scissors_dirty |= 1 << (start_slot + i); + nv50->dirty |= NV50_NEW_SCISSOR; + } } static void @@ -915,9 +924,16 @@ nv50_set_viewport_states(struct pipe_context *pipe, const struct pipe_viewport_state *vpt) { struct nv50_context *nv50 = nv50_context(pipe); + int i; - nv50->viewport = *vpt; - nv50->dirty |= NV50_NEW_VIEWPORT; + assert(start_slot + num_viewports <= NV50_MAX_VIEWPORTS); + for (i = 0; i < num_viewports; i++) { + if (!memcmp(&nv50->viewports[start_slot + i], &vpt[i], sizeof(*vpt))) + continue; + nv50->viewports[start_slot + i] = vpt[i]; + nv50->viewports_dirty |= 1 << (start_slot + i); + nv50->dirty |= NV50_NEW_VIEWPORT; + } } static void diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c index 9559253..fdc2e63 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c @@ -124,9 +124,11 @@ nv50_validate_fb(struct nv50_context *nv50) BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1); PUSH_DATA (push, ms_mode); - BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2); - PUSH_DATA (push, fb->width << 16); - PUSH_DATA (push, fb->height << 16); + for (i = 0; i < NV50_MAX_VIEWPORTS; i++) { + BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(i)), 2); + PUSH_DATA (push, fb->width << 16); + PUSH_DATA (push, fb->height << 16); + } } static void @@ -167,42 +169,63 @@ static void nv50_validate_scissor(struct nv50_context *nv50) { struct nouveau_pushbuf *push = nv50->base.pushbuf; - struct pipe_scissor_state *s = &nv50->scissor; #ifdef NV50_SCISSORS_CLIPPING - struct pipe_viewport_state *vp = &nv50->viewport; - int minx, maxx, miny, maxy; + int minx, maxx, miny, maxy, i; if (!(nv50->dirty & (NV50_NEW_SCISSOR | NV50_NEW_VIEWPORT | NV50_NEW_FRAMEBUFFER)) && nv50->state.scissor == nv50->rast->pipe.scissor) return; + + if (nv50->state.scissor != nv50->rast->pipe.scissor) + nv50->scissors_dirty = (1 << NV50_MAX_VIEWPORTS) - 1; + nv50->state.scissor = nv50->rast->pipe.scissor; - if (nv50->state.scissor) { - minx = s->minx; - maxx = s->maxx; - miny = s->miny; - maxy = s->maxy; - } else { - minx = 0; - maxx = nv50->framebuffer.width; - miny = 0; - maxy = nv50->framebuffer.height; - } + if ((nv50->dirty & NV50_NEW_FRAMEBUFFER) && !nv50->state.scissor) + nv50->scissors_dirty = (1 << NV50_MAX_VIEWPORTS) - 1; + + for (i = 0; i < NV50_MAX_VIEWPORTS; i++) { + struct pipe_scissor_state *s = &nv50->scissors[i]; + struct pipe_viewport_state *vp = &nv50->viewports[i]; - minx = MAX2(minx, (int)(vp->translate[0] - fabsf(vp->scale[0]))); - maxx = MIN2(maxx, (int)(vp->translate[0] + fabsf(vp->scale[0]))); - miny = MAX2(miny, (int)(vp->translate[1] - fabsf(vp->scale[1]))); - maxy = MIN2(maxy, (int)(vp->translate[1] + fabsf(vp->scale[1]))); + if (!(nv50->scissors_dirty & (1 << i)) && + !(nv50->viewports_dirty & (1 << i))) + continue; - BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2); - PUSH_DATA (push, (maxx << 16) | minx); - PUSH_DATA (push, (maxy << 16) | miny); + if (nv50->state.scissor) { + minx = s->minx; + maxx = s->maxx; + miny = s->miny; + maxy = s->maxy; + } else { + minx = 0; + maxx = nv50->framebuffer.width; + miny = 0; + maxy = nv50->framebuffer.height; + } + + minx = MAX2(minx, (int)(vp->translate[0] - fabsf(vp->scale[0]))); + maxx = MIN2(maxx, (int)(vp->translate[0] + fabsf(vp->scale[0]))); + miny = MAX2(miny, (int)(vp->translate[1] - fabsf(vp->scale[1]))); + maxy = MIN2(maxy, (int)(vp->translate[1] + fabsf(vp->scale[1]))); + + minx = MIN2(minx, 8192); + maxx = MAX2(maxx, 0); + miny = MIN2(miny, 8192); + maxy = MAX2(maxy, 0); + + BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(i)), 2); + PUSH_DATA (push, (maxx << 16) | minx); + PUSH_DATA (push, (maxy << 16) | miny); #else - BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2); - PUSH_DATA (push, (s->maxx << 16) | s->minx); - PUSH_DATA (push, (s->maxy << 16) | s->miny); + BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(i)), 2); + PUSH_DATA (push, (s->maxx << 16) | s->minx); + PUSH_DATA (push, (s->maxy << 16) | s->miny); #endif + } + + nv50->scissors_dirty = 0; } static void @@ -210,24 +233,34 @@ nv50_validate_viewport(struct nv50_context *nv50) { struct nouveau_pushbuf *push = nv50->base.pushbuf; float zmin, zmax; + int i; - BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSLATE_X(0)), 3); - PUSH_DATAf(push, nv50->viewport.translate[0]); - PUSH_DATAf(push, nv50->viewport.translate[1]); - PUSH_DATAf(push, nv50->viewport.translate[2]); - BEGIN_NV04(push, NV50_3D(VIEWPORT_SCALE_X(0)), 3); - PUSH_DATAf(push, nv50->viewport.scale[0]); - PUSH_DATAf(push, nv50->viewport.scale[1]); - PUSH_DATAf(push, nv50->viewport.scale[2]); + for (i = 0; i < NV50_MAX_VIEWPORTS; i++) { + struct pipe_viewport_state *vpt = &nv50->viewports[i]; - zmin = nv50->viewport.translate[2] - fabsf(nv50->viewport.scale[2]); - zmax = nv50->viewport.translate[2] + fabsf(nv50->viewport.scale[2]); + if (!(nv50->viewports_dirty & (1 << i))) + continue; + + BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSLATE_X(i)), 3); + PUSH_DATAf(push, vpt->translate[0]); + PUSH_DATAf(push, vpt->translate[1]); + PUSH_DATAf(push, vpt->translate[2]); + BEGIN_NV04(push, NV50_3D(VIEWPORT_SCALE_X(i)), 3); + PUSH_DATAf(push, vpt->scale[0]); + PUSH_DATAf(push, vpt->scale[1]); + PUSH_DATAf(push, vpt->scale[2]); + + zmin = vpt->translate[2] - fabsf(vpt->scale[2]); + zmax = vpt->translate[2] + fabsf(vpt->scale[2]); #ifdef NV50_SCISSORS_CLIPPING - BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2); - PUSH_DATAf(push, zmin); - PUSH_DATAf(push, zmax); + BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(i)), 2); + PUSH_DATAf(push, zmin); + PUSH_DATAf(push, zmax); #endif + } + + nv50->viewports_dirty = 0; } static INLINE void -- 1.8.3.2
Possibly Parallel Threads
- [PATCH 00/19] nv50: add sampler2DMS/GP support to get OpenGL 3.2
- [PATCH v2 0/3] ARB_viewport_array for nvc0
- [PATCH 0/3] ARB_viewport_array for nvc0
- [Bug 69155] New: codegen/nv50_ir_emit_nv50.cpp:169:srcAddr8: Assertion `(offset <= 0x1fc || offset == 0x3fc) && !(offset & 0x3)' failed.
- [PATCH] nv50, nvc0: don't base decisions on available pushbuf space