X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fgen6_clip_state.c;h=2fffb673bfc918dbdf979cf372eaea06147a6697;hb=cee5585da7e8a164952347c8dbf72844cad85d9d;hp=26de633bae6d9e2e15cb0b5640a1b9145b1c9fdf;hpb=c564348a2ec601b28ae607ca0f77054ea53f6912;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/gen6_clip_state.c b/src/mesa/drivers/dri/i965/gen6_clip_state.c index 26de633bae6..2fffb673bfc 100644 --- a/src/mesa/drivers/dri/i965/gen6_clip_state.c +++ b/src/mesa/drivers/dri/i965/gen6_clip_state.c @@ -28,206 +28,63 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" +#include "compiler/brw_eu_defines.h" #include "brw_util.h" #include "intel_batchbuffer.h" #include "main/fbobject.h" #include "main/framebuffer.h" -static void -upload_clip_state(struct brw_context *brw) +bool +brw_is_drawing_points(const struct brw_context *brw) { - struct gl_context *ctx = &brw->ctx; - /* BRW_NEW_META_IN_PROGRESS */ - uint32_t dw1 = brw->meta_in_progress ? 0 : GEN6_CLIP_STATISTICS_ENABLE; - uint32_t dw2 = 0; - - /* _NEW_BUFFERS */ - struct gl_framebuffer *fb = ctx->DrawBuffer; - - /* BRW_NEW_FS_PROG_DATA */ - if (brw->wm.prog_data->barycentric_interp_modes & - BRW_WM_NONPERSPECTIVE_BARYCENTRIC_BITS) { - dw2 |= GEN6_CLIP_NON_PERSPECTIVE_BARYCENTRIC_ENABLE; - } - - dw1 |= brw->vs.prog_data->base.cull_distance_mask; - - if (brw->gen >= 7) - dw1 |= GEN7_CLIP_EARLY_CULL; - - if (brw->gen == 7) { - /* _NEW_POLYGON */ - if (ctx->Polygon._FrontBit == _mesa_is_user_fbo(fb)) - dw1 |= GEN7_CLIP_WINDING_CCW; - - if (ctx->Polygon.CullFlag) { - switch (ctx->Polygon.CullFaceMode) { - case GL_FRONT: - dw1 |= GEN7_CLIP_CULLMODE_FRONT; - break; - case GL_BACK: - dw1 |= GEN7_CLIP_CULLMODE_BACK; - break; - case GL_FRONT_AND_BACK: - dw1 |= GEN7_CLIP_CULLMODE_BOTH; - break; - default: - unreachable("Should not get here: invalid CullFlag"); - } - } else { - dw1 |= GEN7_CLIP_CULLMODE_NONE; - } + /* Determine if the primitives *reaching the SF* are points */ + /* _NEW_POLYGON */ + if (brw->ctx.Polygon.FrontMode == GL_POINT || + brw->ctx.Polygon.BackMode == GL_POINT) { + return true; } - if (brw->gen < 8 && !ctx->Transform.DepthClamp) - dw2 |= GEN6_CLIP_Z_TEST; - - /* _NEW_LIGHT */ - if (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION) { - dw2 |= - (0 << GEN6_CLIP_TRI_PROVOKE_SHIFT) | - (1 << GEN6_CLIP_TRIFAN_PROVOKE_SHIFT) | - (0 << GEN6_CLIP_LINE_PROVOKE_SHIFT); + if (brw->gs.base.prog_data) { + /* BRW_NEW_GS_PROG_DATA */ + return brw_gs_prog_data(brw->gs.base.prog_data)->output_topology == + _3DPRIM_POINTLIST; + } else if (brw->tes.base.prog_data) { + /* BRW_NEW_TES_PROG_DATA */ + return brw_tes_prog_data(brw->tes.base.prog_data)->output_topology == + BRW_TESS_OUTPUT_TOPOLOGY_POINT; } else { - dw2 |= - (2 << GEN6_CLIP_TRI_PROVOKE_SHIFT) | - (2 << GEN6_CLIP_TRIFAN_PROVOKE_SHIFT) | - (1 << GEN6_CLIP_LINE_PROVOKE_SHIFT); + /* BRW_NEW_PRIMITIVE */ + return brw->primitive == _3DPRIM_POINTLIST; } +} - /* _NEW_TRANSFORM */ - dw2 |= (ctx->Transform.ClipPlanesEnabled << - GEN6_USER_CLIP_CLIP_DISTANCES_SHIFT); - if (ctx->Transform.ClipDepthMode == GL_ZERO_TO_ONE) - dw2 |= GEN6_CLIP_API_D3D; - else - dw2 |= GEN6_CLIP_API_OGL; - - dw2 |= GEN6_CLIP_GB_TEST; - - /* We need to disable guardband clipping if the guardband (which we always - * program to the maximum screen-space bounding box of 8K x 8K) will be - * smaller than the viewport. - * - * Closely examining the clip determination formulas in the documentation - * reveals that objects will be discarded entirely if they're outside the - * (small) guardband, even if they're within the (large) viewport: - * - * TR = TR_GB || TR_VPXY || TR_VPZ || TR_UC || TR_NEGW - * TA = !TR && TA_GB && TA_VPZ && TA_NEGW - * MC = !(TA || TR) - * - * (TA is "Trivial Accept", TR is "Trivial Reject", MC is "Must Clip".) - * - * Disabling guardband clipping removes the TR_GB condition, which means - * they'll be considered MC ("Must Clip") unless they're rejected for - * some other reason. - * - * Note that there is no TA_VPXY condition. If there were, objects entirely - * inside a 16384x16384 viewport would be trivially accepted, breaking the - * "objects must have a screenspace bounding box not exceeding 8K in the X - * or Y direction" restriction. Instead, they're clipped. - */ - for (unsigned i = 0; i < ctx->Const.MaxViewports; i++) { - if (ctx->ViewportArray[i].Width > 8192 || - ctx->ViewportArray[i].Height > 8192) { - dw2 &= ~GEN6_CLIP_GB_TEST; - break; - } +bool +brw_is_drawing_lines(const struct brw_context *brw) +{ + /* Determine if the primitives *reaching the SF* are points */ + /* _NEW_POLYGON */ + if (brw->ctx.Polygon.FrontMode == GL_LINE || + brw->ctx.Polygon.BackMode == GL_LINE) { + return true; } - /* If the viewport dimensions are smaller than the drawable dimensions, - * we have to disable guardband clipping prior to Gen8. We always program - * the guardband to a fixed size, which is almost always larger than the - * viewport. Any geometry which intersects the viewport but lies within - * the guardband would bypass the 3D clipping stage, so it wouldn't be - * clipped to the viewport. Rendering would happen beyond the viewport, - * but still inside the drawable. - * - * Gen8+ introduces a viewport extents test which restricts rendering to - * the viewport, so we can ignore this restriction. - */ - if (brw->gen < 8) { - const float fb_width = (float)_mesa_geometric_width(fb); - const float fb_height = (float)_mesa_geometric_height(fb); - - for (unsigned i = 0; i < ctx->Const.MaxViewports; i++) { - if (ctx->ViewportArray[i].X != 0 || - ctx->ViewportArray[i].Y != 0 || - ctx->ViewportArray[i].Width != fb_width || - ctx->ViewportArray[i].Height != fb_height) { - dw2 &= ~GEN6_CLIP_GB_TEST; - break; - } + if (brw->gs.base.prog_data) { + /* BRW_NEW_GS_PROG_DATA */ + return brw_gs_prog_data(brw->gs.base.prog_data)->output_topology == + _3DPRIM_LINESTRIP; + } else if (brw->tes.base.prog_data) { + /* BRW_NEW_TES_PROG_DATA */ + return brw_tes_prog_data(brw->tes.base.prog_data)->output_topology == + BRW_TESS_OUTPUT_TOPOLOGY_LINE; + } else { + /* BRW_NEW_PRIMITIVE */ + switch (brw->primitive) { + case _3DPRIM_LINELIST: + case _3DPRIM_LINESTRIP: + case _3DPRIM_LINELOOP: + return true; } } - - /* BRW_NEW_RASTERIZER_DISCARD */ - if (ctx->RasterDiscard) { - dw2 |= GEN6_CLIP_MODE_REJECT_ALL; - perf_debug("Rasterizer discard is currently implemented via the clipper; " - "%s be faster.\n", brw->gen >= 7 ? "using the SOL unit may" : - "having the GS not write primitives would likely"); - } - - uint32_t enable; - if (brw->primitive == _3DPRIM_RECTLIST) - enable = 0; - else - enable = GEN6_CLIP_ENABLE; - - if (!is_drawing_points(brw) && !is_drawing_lines(brw)) - dw2 |= GEN6_CLIP_XY_TEST; - - /* BRW_NEW_VUE_MAP_GEOM_OUT */ - const int max_vp_index = - (brw->vue_map_geom_out.slots_valid & VARYING_BIT_VIEWPORT) != 0 ? - ctx->Const.MaxViewports : 1; - - BEGIN_BATCH(4); - OUT_BATCH(_3DSTATE_CLIP << 16 | (4 - 2)); - OUT_BATCH(dw1); - OUT_BATCH(enable | - GEN6_CLIP_MODE_NORMAL | - dw2); - OUT_BATCH(U_FIXED(0.125, 3) << GEN6_CLIP_MIN_POINT_WIDTH_SHIFT | - U_FIXED(255.875, 3) << GEN6_CLIP_MAX_POINT_WIDTH_SHIFT | - (_mesa_geometric_layers(fb) > 0 ? 0 : GEN6_CLIP_FORCE_ZERO_RTAINDEX) | - ((max_vp_index - 1) & GEN6_CLIP_MAX_VP_INDEX_MASK)); - ADVANCE_BATCH(); + return false; } -const struct brw_tracked_state gen6_clip_state = { - .dirty = { - .mesa = _NEW_BUFFERS | - _NEW_LIGHT | - _NEW_TRANSFORM, - .brw = BRW_NEW_BLORP | - BRW_NEW_CONTEXT | - BRW_NEW_FS_PROG_DATA | - BRW_NEW_GEOMETRY_PROGRAM | - BRW_NEW_META_IN_PROGRESS | - BRW_NEW_PRIMITIVE | - BRW_NEW_RASTERIZER_DISCARD | - BRW_NEW_VUE_MAP_GEOM_OUT, - }, - .emit = upload_clip_state, -}; - -const struct brw_tracked_state gen7_clip_state = { - .dirty = { - .mesa = _NEW_BUFFERS | - _NEW_LIGHT | - _NEW_POLYGON | - _NEW_TRANSFORM, - .brw = BRW_NEW_BLORP | - BRW_NEW_CONTEXT | - BRW_NEW_FS_PROG_DATA | - BRW_NEW_GEOMETRY_PROGRAM | - BRW_NEW_META_IN_PROGRESS | - BRW_NEW_PRIMITIVE | - BRW_NEW_RASTERIZER_DISCARD | - BRW_NEW_VUE_MAP_GEOM_OUT, - }, - .emit = upload_clip_state, -};