gen6_clip_state.c revision a864b82a04efd0642f5b2a9489b3c20dac46551f
1/*
2 * Copyright © 2009 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 *    Eric Anholt <eric@anholt.net>
25 *
26 */
27
28#include "brw_context.h"
29#include "brw_state.h"
30#include "brw_defines.h"
31#include "brw_util.h"
32#include "intel_batchbuffer.h"
33
34uint32_t
35brw_compute_userclip_flags(bool uses_clip_distance,
36                           GLbitfield clip_planes_enabled)
37{
38   if (uses_clip_distance) {
39      /* When using gl_ClipDistance, it is up to the shader to decide which
40       * clip distance values to use.
41       */
42      return clip_planes_enabled;
43   } else {
44      /* When using clipping planes, we compact the ones that are in use so
45       * that they are always numbered consecutively from zero, so we need to
46       * enable clipping planes 0 through n-1 in the hardware regardless of
47       * which planes the user has selected.
48       */
49      return (1 << brw_count_bits(clip_planes_enabled)) - 1;
50   }
51}
52
53static void
54upload_clip_state(struct brw_context *brw)
55{
56   struct intel_context *intel = &brw->intel;
57   struct gl_context *ctx = &intel->ctx;
58   uint32_t depth_clamp = 0;
59   uint32_t provoking, userclip;
60
61   /* BRW_NEW_VERTEX_PROGRAM */
62   struct brw_vertex_program *vp =
63      (struct brw_vertex_program *)brw->vertex_program;
64
65   if (!ctx->Transform.DepthClamp)
66      depth_clamp = GEN6_CLIP_Z_TEST;
67
68   /* _NEW_LIGHT */
69   if (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION) {
70      provoking =
71	 (0 << GEN6_CLIP_TRI_PROVOKE_SHIFT) |
72	 (1 << GEN6_CLIP_TRIFAN_PROVOKE_SHIFT) |
73	 (0 << GEN6_CLIP_LINE_PROVOKE_SHIFT);
74   } else {
75      provoking =
76	 (2 << GEN6_CLIP_TRI_PROVOKE_SHIFT) |
77	 (2 << GEN6_CLIP_TRIFAN_PROVOKE_SHIFT) |
78	 (1 << GEN6_CLIP_LINE_PROVOKE_SHIFT);
79   }
80
81   /* _NEW_TRANSFORM */
82   userclip = brw_compute_userclip_flags(vp->program.UsesClipDistance,
83                                         ctx->Transform.ClipPlanesEnabled);
84
85   BEGIN_BATCH(4);
86   OUT_BATCH(_3DSTATE_CLIP << 16 | (4 - 2));
87   OUT_BATCH(GEN6_CLIP_STATISTICS_ENABLE);
88   OUT_BATCH(GEN6_CLIP_ENABLE |
89	     GEN6_CLIP_API_OGL |
90	     GEN6_CLIP_MODE_NORMAL |
91	     GEN6_CLIP_XY_TEST |
92	     userclip << GEN6_USER_CLIP_CLIP_DISTANCES_SHIFT |
93	     depth_clamp |
94	     provoking);
95   OUT_BATCH(U_FIXED(0.125, 3) << GEN6_CLIP_MIN_POINT_WIDTH_SHIFT |
96             U_FIXED(255.875, 3) << GEN6_CLIP_MAX_POINT_WIDTH_SHIFT |
97             GEN6_CLIP_FORCE_ZERO_RTAINDEX);
98   ADVANCE_BATCH();
99}
100
101const struct brw_tracked_state gen6_clip_state = {
102   .dirty = {
103      .mesa  = _NEW_TRANSFORM | _NEW_LIGHT,
104      .brw   = BRW_NEW_CONTEXT | BRW_NEW_VERTEX_PROGRAM,
105      .cache = 0
106   },
107   .emit = upload_clip_state,
108};
109