i965: Port gen6+ 3DSTATE_SF to genxml.
[mesa.git] / src / mesa / drivers / dri / i965 / gen8_sf_state.c
1 /*
2 * Copyright © 2011 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
24 #include "compiler/nir/nir.h"
25 #include "brw_context.h"
26 #include "brw_state.h"
27 #include "brw_defines.h"
28 #include "brw_util.h"
29 #include "main/macros.h"
30 #include "main/fbobject.h"
31 #include "intel_batchbuffer.h"
32
33 static void
34 upload_sbe(struct brw_context *brw)
35 {
36 struct gl_context *ctx = &brw->ctx;
37 /* BRW_NEW_FS_PROG_DATA */
38 const struct brw_wm_prog_data *wm_prog_data =
39 brw_wm_prog_data(brw->wm.base.prog_data);
40 uint32_t num_outputs = wm_prog_data->num_varying_inputs;
41 uint16_t attr_overrides[VARYING_SLOT_MAX];
42 uint32_t urb_entry_read_length;
43 uint32_t urb_entry_read_offset;
44 uint32_t point_sprite_enables;
45 int sbe_cmd_length;
46
47 uint32_t dw1 =
48 GEN7_SBE_SWIZZLE_ENABLE |
49 num_outputs << GEN7_SBE_NUM_OUTPUTS_SHIFT;
50 uint32_t dw4 = 0;
51 uint32_t dw5 = 0;
52
53 /* _NEW_BUFFERS */
54 bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
55
56 /* _NEW_POINT
57 *
58 * Window coordinates in an FBO are inverted, which means point
59 * sprite origin must be inverted.
60 */
61 if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo)
62 dw1 |= GEN6_SF_POINT_SPRITE_LOWERLEFT;
63 else
64 dw1 |= GEN6_SF_POINT_SPRITE_UPPERLEFT;
65
66 /* _NEW_POINT | _NEW_LIGHT | _NEW_PROGRAM,
67 * BRW_NEW_FS_PROG_DATA | BRW_NEW_FRAGMENT_PROGRAM |
68 * BRW_NEW_GS_PROG_DATA | BRW_NEW_PRIMITIVE | BRW_NEW_TES_PROG_DATA |
69 * BRW_NEW_VUE_MAP_GEOM_OUT
70 */
71 calculate_attr_overrides(brw, attr_overrides,
72 &point_sprite_enables,
73 &urb_entry_read_length,
74 &urb_entry_read_offset);
75
76 /* Typically, the URB entry read length and offset should be programmed in
77 * 3DSTATE_VS and 3DSTATE_GS; SBE inherits it from the last active stage
78 * which produces geometry. However, we don't know the proper value until
79 * we call calculate_attr_overrides().
80 *
81 * To fit with our existing code, we override the inherited values and
82 * specify it here directly, as we did on previous generations.
83 */
84 dw1 |=
85 urb_entry_read_length << GEN7_SBE_URB_ENTRY_READ_LENGTH_SHIFT |
86 urb_entry_read_offset << GEN8_SBE_URB_ENTRY_READ_OFFSET_SHIFT |
87 GEN8_SBE_FORCE_URB_ENTRY_READ_LENGTH |
88 GEN8_SBE_FORCE_URB_ENTRY_READ_OFFSET;
89
90 if (brw->gen == 8) {
91 sbe_cmd_length = 4;
92 } else {
93 sbe_cmd_length = 6;
94
95 /* prepare the active component dwords */
96 int input_index = 0;
97 for (int attr = 0; attr < VARYING_SLOT_MAX; attr++) {
98 if (!(brw->fragment_program->info.inputs_read &
99 BITFIELD64_BIT(attr))) {
100 continue;
101 }
102
103 assert(input_index < 32);
104
105 if (input_index < 16)
106 dw4 |= (GEN9_SBE_ACTIVE_COMPONENT_XYZW << (input_index << 1));
107 else
108 dw5 |= (GEN9_SBE_ACTIVE_COMPONENT_XYZW << ((input_index - 16) << 1));
109
110 ++input_index;
111 }
112 }
113 BEGIN_BATCH(sbe_cmd_length);
114 OUT_BATCH(_3DSTATE_SBE << 16 | (sbe_cmd_length - 2));
115 OUT_BATCH(dw1);
116 OUT_BATCH(point_sprite_enables);
117 OUT_BATCH(wm_prog_data->flat_inputs);
118 if (sbe_cmd_length >= 6) {
119 OUT_BATCH(dw4);
120 OUT_BATCH(dw5);
121 }
122 ADVANCE_BATCH();
123
124 BEGIN_BATCH(11);
125 OUT_BATCH(_3DSTATE_SBE_SWIZ << 16 | (11 - 2));
126
127 /* Output DWords 1 through 8: */
128 for (int i = 0; i < 8; i++) {
129 OUT_BATCH(attr_overrides[i * 2] | attr_overrides[i * 2 + 1] << 16);
130 }
131
132 OUT_BATCH(0); /* wrapshortest enables 0-7 */
133 OUT_BATCH(0); /* wrapshortest enables 8-15 */
134 ADVANCE_BATCH();
135 }
136
137 const struct brw_tracked_state gen8_sbe_state = {
138 .dirty = {
139 .mesa = _NEW_BUFFERS |
140 _NEW_LIGHT |
141 _NEW_POINT |
142 _NEW_POLYGON |
143 _NEW_PROGRAM,
144 .brw = BRW_NEW_BLORP |
145 BRW_NEW_CONTEXT |
146 BRW_NEW_FRAGMENT_PROGRAM |
147 BRW_NEW_FS_PROG_DATA |
148 BRW_NEW_GS_PROG_DATA |
149 BRW_NEW_TES_PROG_DATA |
150 BRW_NEW_VUE_MAP_GEOM_OUT,
151 },
152 .emit = upload_sbe,
153 };