summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2015-08-25 16:59:12 -0700
committerKenneth Graunke <[email protected]>2015-10-10 11:40:19 -0700
commit031d3501322aee0a1474c7f2a9b79f9fa9947430 (patch)
tree9990ca3bd85cef0b1075f108c884fc0e9a94fa12 /src/mesa/drivers/dri
parenta4e988f4814d80b27102c48020c4338a6d86c6da (diff)
i965/vs: Unify URB entry size/read length calculations between backends.
Both the vec4 and scalar VS backends had virtually identical URB entry size and read length calculations. We can move those up a level to backend-agnostic code and reuse it for both. Unfortunately, the backends need to know nr_attributes to compute first_non_payload_grf, so I had to store that in prog_data. We could use urb_read_length, but that's nr_attributes rounded up to a multiple of two, so doing so would waste a register in some cases. There's more code to be removed in the vec4 backend, but that will come in a follow-on patch. Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Matt Turner <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri')
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp15
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.cpp19
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs.c32
4 files changed, 38 insertions, 30 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index aa1284db3ce..9ad6b4d90cf 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -699,6 +699,8 @@ struct brw_vs_prog_data {
GLbitfield64 inputs_read;
+ unsigned nr_attributes;
+
bool uses_vertexid;
bool uses_instanceid;
};
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index ba62fdd4b86..65f2e68e621 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -1508,21 +1508,12 @@ void
fs_visitor::assign_vs_urb_setup()
{
brw_vs_prog_data *vs_prog_data = (brw_vs_prog_data *) prog_data;
- int grf, count, slot, channel, attr;
+ int grf, slot, channel, attr;
assert(stage == MESA_SHADER_VERTEX);
- count = _mesa_bitcount_64(vs_prog_data->inputs_read);
- if (vs_prog_data->uses_vertexid || vs_prog_data->uses_instanceid)
- count++;
/* Each attribute is 4 regs. */
- this->first_non_payload_grf += count * 4;
-
- unsigned vue_entries =
- MAX2(count, vs_prog_data->base.vue_map.num_slots);
-
- vs_prog_data->base.urb_entry_size = ALIGN(vue_entries, 4) / 4;
- vs_prog_data->base.urb_read_length = (count + 1) / 2;
+ this->first_non_payload_grf += 4 * vs_prog_data->nr_attributes;
assert(vs_prog_data->base.urb_read_length <= 15);
@@ -1532,7 +1523,7 @@ fs_visitor::assign_vs_urb_setup()
if (inst->src[i].file == ATTR) {
if (inst->src[i].reg == VERT_ATTRIB_MAX) {
- slot = count - 1;
+ slot = vs_prog_data->nr_attributes - 1;
} else {
/* Attributes come in in a contiguous block, ordered by their
* gl_vert_attrib value. That means we can compute the slot
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index e966b96a5ca..08f3e9188ed 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -1632,28 +1632,11 @@ vec4_vs_visitor::setup_attributes(int payload_reg)
*/
if (vs_prog_data->uses_vertexid || vs_prog_data->uses_instanceid) {
attribute_map[VERT_ATTRIB_MAX] = payload_reg + nr_attributes;
- nr_attributes++;
}
lower_attributes_to_hw_regs(attribute_map, false /* interleaved */);
- /* The BSpec says we always have to read at least one thing from
- * the VF, and it appears that the hardware wedges otherwise.
- */
- if (nr_attributes == 0)
- nr_attributes = 1;
-
- prog_data->urb_read_length = (nr_attributes + 1) / 2;
-
- unsigned vue_entries =
- MAX2(nr_attributes, prog_data->vue_map.num_slots);
-
- if (devinfo->gen == 6)
- prog_data->urb_entry_size = ALIGN(vue_entries, 8) / 8;
- else
- prog_data->urb_entry_size = ALIGN(vue_entries, 4) / 4;
-
- return payload_reg + nr_attributes;
+ return payload_reg + vs_prog_data->nr_attributes;
}
int
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index 38de98fab86..17d3bc49580 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -159,6 +159,38 @@ brw_codegen_vs_prog(struct brw_context *brw,
&prog_data.base.vue_map, outputs_written,
prog ? prog->SeparateShader : false);
+ unsigned nr_attributes = _mesa_bitcount_64(prog_data.inputs_read);
+
+ /* gl_VertexID and gl_InstanceID are system values, but arrive via an
+ * incoming vertex attribute. So, add an extra slot.
+ */
+ if (vp->program.Base.SystemValuesRead &
+ (BITFIELD64_BIT(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) |
+ BITFIELD64_BIT(SYSTEM_VALUE_INSTANCE_ID))) {
+ nr_attributes++;
+ }
+
+ /* The BSpec says we always have to read at least one thing from the VF,
+ * and it appears that the hardware wedges otherwise.
+ */
+ if (nr_attributes == 0 && !brw->intelScreen->compiler->scalar_vs)
+ nr_attributes = 1;
+
+ prog_data.nr_attributes = nr_attributes;
+ prog_data.base.urb_read_length = DIV_ROUND_UP(nr_attributes, 2);
+
+ /* Since vertex shaders reuse the same VUE entry for inputs and outputs
+ * (overwriting the original contents), we need to make sure the size is
+ * the larger of the two.
+ */
+ const unsigned vue_entries =
+ MAX2(nr_attributes, prog_data.base.vue_map.num_slots);
+
+ if (brw->gen == 6)
+ prog_data.base.urb_entry_size = DIV_ROUND_UP(vue_entries, 8);
+ else
+ prog_data.base.urb_entry_size = DIV_ROUND_UP(vue_entries, 4);
+
if (0) {
_mesa_fprint_program_opt(stderr, &vp->program.Base, PROG_PRINT_DEBUG,
true);