32
32
#include "main/macros.h"
33
33
#include "intel_batchbuffer.h"
36
* Determine the appropriate attribute override value to store into the
37
* 3DSTATE_SF structure for a given fragment shader attribute. The attribute
38
* override value contains two pieces of information: the location of the
39
* attribute in the VUE (relative to urb_entry_read_offset, see below), and a
40
* flag indicating whether to "swizzle" the attribute based on the direction
41
* the triangle is facing.
43
* If an attribute is "swizzled", then the given VUE location is used for
44
* front-facing triangles, and the VUE location that immediately follows is
45
* used for back-facing triangles. We use this to implement the mapping from
46
* gl_FrontColor/gl_BackColor to gl_Color.
48
* urb_entry_read_offset is the offset into the VUE at which the SF unit is
49
* being instructed to begin reading attribute data. It can be set to a
50
* nonzero value to prevent the SF unit from wasting time reading elements of
51
* the VUE that are not needed by the fragment shader. It is measured in
36
get_attr_override(struct brw_context *brw, int fs_attr, int two_side_color)
55
get_attr_override(struct brw_vue_map *vue_map, int urb_entry_read_offset,
56
int fs_attr, bool two_side_color)
38
int attr_index = 0, i, vs_attr;
41
if (fs_attr <= FRAG_ATTRIB_TEX7)
43
else if (fs_attr == FRAG_ATTRIB_FACE)
44
vs_attr = 0; /* XXX */
45
else if (fs_attr == FRAG_ATTRIB_PNTC)
46
vs_attr = 0; /* XXX */
48
assert(fs_attr >= FRAG_ATTRIB_VAR0);
49
vs_attr = fs_attr - FRAG_ATTRIB_VAR0 + VERT_RESULT_VAR0;
52
/* Find the source index (0 = first attribute after the 4D position)
53
* for this output attribute. attr is currently a VERT_RESULT_* but should
56
for (i = 1; i < vs_attr; i++) {
57
if (i == VERT_RESULT_PSIZ)
59
if (brw->vs.prog_data->outputs_written & BITFIELD64_BIT(i))
63
assert(attr_index < 32);
58
int attr_override, slot;
59
int vs_attr = _mesa_frag_attrib_to_vert_result(fs_attr);
60
if (vs_attr < 0 || vs_attr == VERT_RESULT_HPOS) {
61
/* These attributes will be overwritten by the fragment shader's
62
* interpolation code (see emit_interp() in brw_wm_fp.c), so just let
63
* them reference the first available attribute.
68
/* Find the VUE slot for this attribute. */
69
slot = vue_map->vert_result_to_slot[vs_attr];
71
/* If there was only a back color written but not front, use back
72
* as the color instead of undefined
74
if (slot == -1 && vs_attr == VERT_RESULT_COL0)
75
slot = vue_map->vert_result_to_slot[VERT_RESULT_BFC0];
76
if (slot == -1 && vs_attr == VERT_RESULT_COL1)
77
slot = vue_map->vert_result_to_slot[VERT_RESULT_BFC1];
80
/* This attribute does not exist in the VUE--that means that the vertex
81
* shader did not write to it. Behavior is undefined in this case, so
82
* just reference the first available attribute.
87
/* Compute the location of the attribute relative to urb_entry_read_offset.
88
* Each increment of urb_entry_read_offset represents a 256-bit value, so
89
* it counts for two 128-bit VUE slots.
91
attr_override = slot - 2 * urb_entry_read_offset;
92
assert (attr_override >= 0 && attr_override < 32);
94
/* If we are doing two-sided color, and the VUE slot following this one
95
* represents a back-facing color, then we need to instruct the SF unit to
96
* do back-facing swizzling.
65
98
if (two_side_color) {
66
if ((brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_COL1)) &&
67
(brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_BFC1))) {
68
assert(brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_COL0));
69
assert(brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_BFC0));
71
} else if ((brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_COL0)) &&
72
(brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_BFC0)))
76
if (bfc && (fs_attr <= FRAG_ATTRIB_TEX7 && fs_attr > FRAG_ATTRIB_WPOS)) {
77
if (fs_attr == FRAG_ATTRIB_COL0)
78
attr_index |= (ATTRIBUTE_SWIZZLE_INPUTATTR_FACING << ATTRIBUTE_SWIZZLE_SHIFT);
79
else if (fs_attr == FRAG_ATTRIB_COL1 && bfc == 2) {
81
attr_index |= (ATTRIBUTE_SWIZZLE_INPUTATTR_FACING << ATTRIBUTE_SWIZZLE_SHIFT);
99
if (vue_map->slot_to_vert_result[slot] == VERT_RESULT_COL0 &&
100
vue_map->slot_to_vert_result[slot+1] == VERT_RESULT_BFC0)
101
attr_override |= (ATTRIBUTE_SWIZZLE_INPUTATTR_FACING << ATTRIBUTE_SWIZZLE_SHIFT);
102
else if (vue_map->slot_to_vert_result[slot] == VERT_RESULT_COL1 &&
103
vue_map->slot_to_vert_result[slot+1] == VERT_RESULT_BFC1)
104
attr_override |= (ATTRIBUTE_SWIZZLE_INPUTATTR_FACING << ATTRIBUTE_SWIZZLE_SHIFT);
107
return attr_override;
93
113
struct intel_context *intel = &brw->intel;
94
114
struct gl_context *ctx = &intel->ctx;
115
struct brw_vue_map vue_map;
116
uint32_t urb_entry_read_length;
95
117
/* CACHE_NEW_VS_PROG */
96
uint32_t num_inputs = brw_count_bits(brw->vs.prog_data->outputs_written);
118
GLbitfield64 vs_outputs_written = brw->vs.prog_data->outputs_written;
97
119
/* BRW_NEW_FRAGMENT_PROGRAM */
98
uint32_t num_outputs = brw_count_bits(brw->fragment_program->Base.InputsRead);
120
uint32_t num_outputs = _mesa_bitcount_64(brw->fragment_program->Base.InputsRead);
122
bool shade_model_flat = ctx->Light.ShadeModel == GL_FLAT;
99
123
uint32_t dw1, dw2, dw3, dw4, dw16, dw17;
101
125
/* _NEW_BUFFER */
102
GLboolean render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
126
bool render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
103
127
int attr = 0, input_index = 0;
105
int two_side_color = (ctx->Light.Enabled && ctx->Light.Model.TwoSide);
128
int urb_entry_read_offset = 1;
106
129
float point_size;
107
130
uint16_t attr_overrides[FRAG_ATTRIB_MAX];
131
bool userclip_active;
109
133
/* _NEW_TRANSFORM */
110
if (ctx->Transform.ClipPlanesEnabled)
134
userclip_active = (ctx->Transform.ClipPlanesEnabled != 0);
136
brw_compute_vue_map(&vue_map, intel, userclip_active, vs_outputs_written);
137
urb_entry_read_length = (vue_map.num_slots + 1)/2 - urb_entry_read_offset;
138
if (urb_entry_read_length == 0) {
139
/* Setting the URB entry read length to 0 causes undefined behavior, so
140
* if we have no URB data to read, set it to 1.
142
urb_entry_read_length = 1;
116
146
GEN6_SF_SWIZZLE_ENABLE |
117
147
num_outputs << GEN6_SF_NUM_OUTPUTS_SHIFT |
118
(num_inputs + 1) / 2 << GEN6_SF_URB_ENTRY_READ_LENGTH_SHIFT |
119
urb_start << GEN6_SF_URB_ENTRY_READ_OFFSET_SHIFT;
120
dw2 = GEN6_SF_VIEWPORT_TRANSFORM_ENABLE |
121
GEN6_SF_STATISTICS_ENABLE;
148
urb_entry_read_length << GEN6_SF_URB_ENTRY_READ_LENGTH_SHIFT |
149
urb_entry_read_offset << GEN6_SF_URB_ENTRY_READ_OFFSET_SHIFT;
151
dw2 = GEN6_SF_STATISTICS_ENABLE;
153
/* Enable viewport transform only if no HiZ operation is progress
155
* From page 11 of the SandyBridge PRM, Volume 2, Part 1, Section 1.3, "3D
156
* Primitives Overview":
157
* RECTLIST: Viewport Mapping must be DISABLED (as is typical with the
158
* use of screen- space coordinates).
161
dw2 |= GEN6_SF_VIEWPORT_TRANSFORM_ENABLE;