summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/i965/brw_compiler.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h9
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.c12
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_upload.c45
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp2
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_nir.cpp10
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp10
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.cpp13
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_nir.cpp8
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp5
-rw-r--r--src/mesa/drivers/dri/i965/gen8_draw_upload.c34
-rw-r--r--src/mesa/drivers/dri/i965/intel_extensions.c1
12 files changed, 145 insertions, 5 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_compiler.h b/src/mesa/drivers/dri/i965/brw_compiler.h
index 9b3bb9f..224ddb1 100644
--- a/src/mesa/drivers/dri/i965/brw_compiler.h
+++ b/src/mesa/drivers/dri/i965/brw_compiler.h
@@ -597,6 +597,7 @@ struct brw_vs_prog_data {
bool uses_instanceid;
bool uses_basevertex;
bool uses_baseinstance;
+ bool uses_drawid;
};
struct brw_tcs_prog_data
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 4cbe585..7b0340f 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -923,6 +923,15 @@ struct brw_context
*/
drm_intel_bo *draw_params_bo;
uint32_t draw_params_offset;
+
+ /**
+ * The value of gl_DrawID for the current _mesa_prim. This always comes
+ * in from it's own vertex buffer since it's not part of the indirect
+ * draw parameters.
+ */
+ int gl_drawid;
+ drm_intel_bo *draw_id_bo;
+ uint32_t draw_id_offset;
} draw;
struct {
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index e0665d3..b0a162a 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -511,6 +511,18 @@ brw_try_draw_prims(struct gl_context *ctx,
brw->draw.draw_params_offset = 0;
}
+ /* gl_DrawID always needs its own vertex buffer since it's not part of
+ * the indirect parameter buffer. If the program uses gl_DrawID we need
+ * to flag BRW_NEW_VERTICES. For the first iteration, we don't have
+ * valid brw->vs.prog_data, but we always flag BRW_NEW_VERTICES before
+ * the loop.
+ */
+ brw->draw.gl_drawid = prims[i].draw_id;
+ drm_intel_bo_unreference(brw->draw.draw_id_bo);
+ brw->draw.draw_id_bo = NULL;
+ if (i > 0 && brw->vs.prog_data->uses_drawid)
+ brw->ctx.NewDriverState |= BRW_NEW_VERTICES;
+
if (brw->gen < 6)
brw_set_prim(brw, &prims[i]);
else
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index ccf963c..f781d8b 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -599,6 +599,12 @@ brw_prepare_shader_draw_parameters(struct brw_context *brw)
&brw->draw.draw_params_bo,
&brw->draw.draw_params_offset);
}
+
+ if (brw->vs.prog_data->uses_drawid) {
+ intel_upload_data(brw, &brw->draw.gl_drawid, sizeof(brw->draw.gl_drawid), 4,
+ &brw->draw.draw_id_bo,
+ &brw->draw.draw_id_offset);
+ }
}
/**
@@ -663,6 +669,8 @@ brw_emit_vertices(struct brw_context *brw)
if (brw->vs.prog_data->uses_vertexid || brw->vs.prog_data->uses_instanceid ||
brw->vs.prog_data->uses_basevertex || brw->vs.prog_data->uses_baseinstance)
++nr_elements;
+ if (brw->vs.prog_data->uses_drawid)
+ nr_elements++;
/* If the VS doesn't read any inputs (calculating vertex position from
* a state variable for some reason, for example), emit a single pad
@@ -699,7 +707,8 @@ brw_emit_vertices(struct brw_context *brw)
const bool uses_draw_params =
brw->vs.prog_data->uses_basevertex ||
brw->vs.prog_data->uses_baseinstance;
- const unsigned nr_buffers = brw->vb.nr_buffers + uses_draw_params;
+ const unsigned nr_buffers = brw->vb.nr_buffers +
+ uses_draw_params + brw->vs.prog_data->uses_drawid;
if (nr_buffers) {
if (brw->gen >= 6) {
@@ -726,6 +735,16 @@ brw_emit_vertices(struct brw_context *brw)
0, /* stride */
0); /* step rate */
}
+
+ if (brw->vs.prog_data->uses_drawid) {
+ EMIT_VERTEX_BUFFER_STATE(brw, brw->vb.nr_buffers + 1,
+ brw->draw.draw_id_bo,
+ brw->draw.draw_id_bo->size - 1,
+ brw->draw.draw_id_offset,
+ 0, /* stride */
+ 0); /* step rate */
+ }
+
ADVANCE_BATCH();
}
@@ -839,6 +858,30 @@ brw_emit_vertices(struct brw_context *brw)
OUT_BATCH(dw1);
}
+ if (brw->vs.prog_data->uses_drawid) {
+ uint32_t dw0 = 0, dw1 = 0;
+
+ dw1 = (BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT);
+
+ if (brw->gen >= 6) {
+ dw0 |= GEN6_VE0_VALID |
+ ((brw->vb.nr_buffers + 1) << GEN6_VE0_INDEX_SHIFT) |
+ (BRW_SURFACEFORMAT_R32_UINT << BRW_VE0_FORMAT_SHIFT);
+ } else {
+ dw0 |= BRW_VE0_VALID |
+ ((brw->vb.nr_buffers + 1) << BRW_VE0_INDEX_SHIFT) |
+ (BRW_SURFACEFORMAT_R32_UINT << BRW_VE0_FORMAT_SHIFT);
+
+ dw1 |= (i * 4) << BRW_VE1_DST_OFFSET_SHIFT;
+ }
+
+ OUT_BATCH(dw0);
+ OUT_BATCH(dw1);
+ }
+
if (brw->gen >= 6 && gen6_edgeflag_input) {
uint32_t format =
brw_get_vertex_surface_type(brw, gen6_edgeflag_input->glarray);
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 8235ce7..286ee0e 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -1674,6 +1674,8 @@ fs_visitor::assign_vs_urb_setup()
if (vs_prog_data->uses_vertexid || vs_prog_data->uses_instanceid ||
vs_prog_data->uses_basevertex || vs_prog_data->uses_baseinstance)
count++;
+ if (vs_prog_data->uses_drawid)
+ count++;
/* Each attribute is 4 regs. */
this->first_non_payload_grf += 4 * vs_prog_data->nr_attributes;
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index 5b901a0..827dbee 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -229,6 +229,13 @@ emit_system_values_block(nir_block *block, void *void_visitor)
*reg = *v->emit_vs_system_value(SYSTEM_VALUE_BASE_INSTANCE);
break;
+ case nir_intrinsic_load_draw_id:
+ assert(v->stage == MESA_SHADER_VERTEX);
+ reg = &v->nir_system_values[SYSTEM_VALUE_DRAW_ID];
+ if (reg->file == BAD_FILE)
+ *reg = *v->emit_vs_system_value(SYSTEM_VALUE_DRAW_ID);
+ break;
+
case nir_intrinsic_load_invocation_id:
assert(v->stage == MESA_SHADER_GEOMETRY);
reg = &v->nir_system_values[SYSTEM_VALUE_INVOCATION_ID];
@@ -1755,7 +1762,8 @@ fs_visitor::nir_emit_vs_intrinsic(const fs_builder &bld,
case nir_intrinsic_load_vertex_id_zero_base:
case nir_intrinsic_load_base_vertex:
case nir_intrinsic_load_instance_id:
- case nir_intrinsic_load_base_instance: {
+ case nir_intrinsic_load_base_instance:
+ case nir_intrinsic_load_draw_id: {
gl_system_value sv = nir_system_value_from_intrinsic(instr->intrinsic);
fs_reg val = nir_system_values[sv];
assert(val.file != BAD_FILE);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index d6941fa..25240ad 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -59,6 +59,16 @@ fs_visitor::emit_vs_system_value(int location)
reg->reg_offset = 3;
vs_prog_data->uses_instanceid = true;
break;
+ case SYSTEM_VALUE_DRAW_ID:
+ if (nir->info.system_values_read &
+ (BITFIELD64_BIT(SYSTEM_VALUE_BASE_VERTEX) |
+ BITFIELD64_BIT(SYSTEM_VALUE_BASE_INSTANCE) |
+ BITFIELD64_BIT(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) |
+ BITFIELD64_BIT(SYSTEM_VALUE_INSTANCE_ID)))
+ reg->nr += 4;
+ reg->reg_offset = 0;
+ vs_prog_data->uses_drawid = true;
+ break;
default:
unreachable("not reached");
}
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index b2a27d8..dd22398 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -1566,7 +1566,7 @@ int
vec4_vs_visitor::setup_attributes(int payload_reg)
{
int nr_attributes;
- int attribute_map[VERT_ATTRIB_MAX + 1];
+ int attribute_map[VERT_ATTRIB_MAX + 2];
memset(attribute_map, 0, sizeof(attribute_map));
nr_attributes = 0;
@@ -1577,6 +1577,11 @@ vec4_vs_visitor::setup_attributes(int payload_reg)
}
}
+ if (vs_prog_data->uses_drawid) {
+ attribute_map[VERT_ATTRIB_MAX + 1] = payload_reg + nr_attributes;
+ nr_attributes++;
+ }
+
/* VertexID is stored by the VF as the last vertex element, but we
* don't represent it with a flag in inputs_read, so we call it
* VERT_ATTRIB_MAX.
@@ -1584,6 +1589,7 @@ vec4_vs_visitor::setup_attributes(int payload_reg)
if (vs_prog_data->uses_vertexid || vs_prog_data->uses_instanceid ||
vs_prog_data->uses_basevertex || vs_prog_data->uses_baseinstance) {
attribute_map[VERT_ATTRIB_MAX] = payload_reg + nr_attributes;
+ nr_attributes++;
}
lower_attributes_to_hw_regs(attribute_map, false /* interleaved */);
@@ -1990,6 +1996,11 @@ brw_compile_vs(const struct brw_compiler *compiler, void *log_data,
nr_attributes++;
}
+ /* gl_DrawID has its very own vec4 */
+ if (shader->info.system_values_read & BITFIELD64_BIT(SYSTEM_VALUE_DRAW_ID)) {
+ nr_attributes++;
+ }
+
/* The 3DSTATE_VS documentation lists the lower bound on "Vertex URB Entry
* Read Length" as 1 in vec4 mode, and 0 in SIMD8 mode. Empirically, in
* vec4 mode, the hardware appears to wedge unless we read something.
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
index c20da9b..a3bdbc3 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
@@ -85,6 +85,13 @@ vec4_visitor::nir_setup_system_value_intrinsic(nir_intrinsic_instr *instr)
glsl_type::int_type);
break;
+ case nir_intrinsic_load_draw_id:
+ reg = &nir_system_values[SYSTEM_VALUE_DRAW_ID];
+ if (reg->file == BAD_FILE)
+ *reg = *make_reg_for_system_value(SYSTEM_VALUE_DRAW_ID,
+ glsl_type::int_type);
+ break;
+
default:
break;
}
@@ -677,6 +684,7 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
case nir_intrinsic_load_base_vertex:
case nir_intrinsic_load_instance_id:
case nir_intrinsic_load_base_instance:
+ case nir_intrinsic_load_draw_id:
case nir_intrinsic_load_invocation_id:
case nir_intrinsic_load_tess_level_inner:
case nir_intrinsic_load_tess_level_outer: {
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp
index bd6a9a4..1d69149 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp
@@ -170,6 +170,11 @@ vec4_vs_visitor::make_reg_for_system_value(int location,
reg->writemask = WRITEMASK_W;
vs_prog_data->uses_instanceid = true;
break;
+ case SYSTEM_VALUE_DRAW_ID:
+ reg = new(mem_ctx) dst_reg(ATTR, VERT_ATTRIB_MAX + 1);
+ reg->writemask = WRITEMASK_X;
+ vs_prog_data->uses_drawid = true;
+ break;
default:
unreachable("not reached");
}
diff --git a/src/mesa/drivers/dri/i965/gen8_draw_upload.c b/src/mesa/drivers/dri/i965/gen8_draw_upload.c
index 451cf0b..ff89e5f 100644
--- a/src/mesa/drivers/dri/i965/gen8_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/gen8_draw_upload.c
@@ -118,7 +118,8 @@ gen8_emit_vertices(struct brw_context *brw)
const bool uses_draw_params =
brw->vs.prog_data->uses_basevertex ||
brw->vs.prog_data->uses_baseinstance;
- const unsigned nr_buffers = brw->vb.nr_buffers + uses_draw_params;
+ const unsigned nr_buffers = brw->vb.nr_buffers +
+ uses_draw_params + brw->vs.prog_data->uses_drawid;
if (nr_buffers) {
assert(nr_buffers <= 33);
@@ -147,6 +148,15 @@ gen8_emit_vertices(struct brw_context *brw)
brw->draw.draw_params_offset);
OUT_BATCH(brw->draw.draw_params_bo->size);
}
+
+ if (brw->vs.prog_data->uses_drawid) {
+ OUT_BATCH((brw->vb.nr_buffers + 1) << GEN6_VB0_INDEX_SHIFT |
+ GEN7_VB0_ADDRESS_MODIFYENABLE |
+ mocs_wb << 16);
+ OUT_RELOC64(brw->draw.draw_id_bo, I915_GEM_DOMAIN_VERTEX, 0,
+ brw->draw.draw_id_offset);
+ OUT_BATCH(brw->draw.draw_id_bo->size);
+ }
ADVANCE_BATCH();
}
@@ -163,7 +173,8 @@ gen8_emit_vertices(struct brw_context *brw)
((brw->vs.prog_data->uses_instanceid ||
brw->vs.prog_data->uses_vertexid) &&
uses_edge_flag));
- const unsigned nr_elements = brw->vb.nr_enabled + needs_sgvs_element;
+ const unsigned nr_elements =
+ brw->vb.nr_enabled + needs_sgvs_element + brw->vs.prog_data->uses_drawid;
/* The hardware allows one more VERTEX_ELEMENTS than VERTEX_BUFFERS,
* presumably for VertexID/InstanceID.
@@ -236,6 +247,16 @@ gen8_emit_vertices(struct brw_context *brw)
}
}
+ if (brw->vs.prog_data->uses_drawid) {
+ OUT_BATCH(GEN6_VE0_VALID |
+ ((brw->vb.nr_buffers + 1) << GEN6_VE0_INDEX_SHIFT) |
+ (BRW_SURFACEFORMAT_R32_UINT << BRW_VE0_FORMAT_SHIFT));
+ OUT_BATCH((BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT));
+ }
+
if (gen6_edgeflag_input) {
uint32_t format =
brw_get_vertex_surface_type(brw, gen6_edgeflag_input->glarray);
@@ -273,6 +294,15 @@ gen8_emit_vertices(struct brw_context *brw)
OUT_BATCH(buffer->step_rate);
ADVANCE_BATCH();
}
+
+ if (brw->vs.prog_data->uses_drawid) {
+ const unsigned element = brw->vb.nr_enabled + needs_sgvs_element;
+ BEGIN_BATCH(3);
+ OUT_BATCH(_3DSTATE_VF_INSTANCING << 16 | (3 - 2));
+ OUT_BATCH(element);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+ }
}
const struct brw_tracked_state gen8_vertices = {
diff --git a/src/mesa/drivers/dri/i965/intel_extensions.c b/src/mesa/drivers/dri/i965/intel_extensions.c
index de16ebb..e1338e9 100644
--- a/src/mesa/drivers/dri/i965/intel_extensions.c
+++ b/src/mesa/drivers/dri/i965/intel_extensions.c
@@ -203,6 +203,7 @@ intelInitExtensions(struct gl_context *ctx)
ctx->Extensions.ARB_point_sprite = true;
ctx->Extensions.ARB_seamless_cube_map = true;
ctx->Extensions.ARB_shader_bit_encoding = true;
+ ctx->Extensions.ARB_shader_draw_parameters = true;
ctx->Extensions.ARB_shader_texture_lod = true;
ctx->Extensions.ARB_shadow = true;
ctx->Extensions.ARB_sync = true;