summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri
diff options
context:
space:
mode:
authorKristian Høgsberg Kristensen <krh@bitplanet.net>2015-12-10 12:27:38 -0800
committerKristian Høgsberg Kristensen <krh@bitplanet.net>2015-12-29 10:39:25 -0800
commitcddfc2cefa93b884c40329dcb193fe4fb22143ab (patch)
tree5f7de35cd73cbdcccb772524b8b80e08612c2c0c /src/mesa/drivers/dri
parent17ebb55a14b5a9aa639845fbda9330ef9421834a (diff)
downloadexternal_mesa3d-cddfc2cefa93b884c40329dcb193fe4fb22143ab.zip
external_mesa3d-cddfc2cefa93b884c40329dcb193fe4fb22143ab.tar.gz
external_mesa3d-cddfc2cefa93b884c40329dcb193fe4fb22143ab.tar.bz2
i965: Add support for gl_DrawIDARB and enable extension
We have to break open a new vec4 for gl_DrawIDARB. We've used up all space in the vec4 we use for SGVS and gl_DrawIDARB has to come from its own separate vertex buffer anyway. This is because we point the vb for base vertex and base instance into the draw parameter BO for indirect draw calls, but the draw id is generated by mesa in a different buffer. Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com>
Diffstat (limited to 'src/mesa/drivers/dri')
-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;