summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2018-12-07 21:37:26 -0800
committerEric Anholt <[email protected]>2018-12-14 17:48:01 -0800
commit5b2cc038522de2bd4b522d6376aef34c65af02d5 (patch)
treeaf29ec55ce3a14b1fb57f7e2683ae26f5ab6398b /src/gallium
parentff80e58b38a13c97a4ee598497e3e7b886918087 (diff)
v3d: Add support for draw indirect for GLES3.1.
In trying to enable compute shaders, I found that a bunch of deqp-gles31's compute stuff wanted to interact with indirect dispatch. This was easy to do on its own.
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/v3d/v3d_screen.c1
-rw-r--r--src/gallium/drivers/v3d/v3dx_draw.c32
2 files changed, 31 insertions, 2 deletions
diff --git a/src/gallium/drivers/v3d/v3d_screen.c b/src/gallium/drivers/v3d/v3d_screen.c
index 6f6c11f1ef1..f6846080c1c 100644
--- a/src/gallium/drivers/v3d/v3d_screen.c
+++ b/src/gallium/drivers/v3d/v3d_screen.c
@@ -122,6 +122,7 @@ v3d_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
case PIPE_CAP_COMPUTE:
case PIPE_CAP_DRAW_INDIRECT:
+ case PIPE_CAP_MULTI_DRAW_INDIRECT:
case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET:
case PIPE_CAP_TGSI_CAN_READ_OUTPUTS:
diff --git a/src/gallium/drivers/v3d/v3dx_draw.c b/src/gallium/drivers/v3d/v3dx_draw.c
index d48970e1e2b..692f1fe3c04 100644
--- a/src/gallium/drivers/v3d/v3dx_draw.c
+++ b/src/gallium/drivers/v3d/v3dx_draw.c
@@ -450,6 +450,9 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
for (int s = 0; s < PIPE_SHADER_TYPES; s++)
v3d_predraw_check_stage_inputs(pctx, s);
+ if (info->indirect)
+ v3d_flush_jobs_writing_resource(v3d, info->indirect->buffer);
+
struct v3d_job *job = v3d_get_job_for_fbo(v3d);
/* If vertex texturing depends on the output of rendering, we need to
@@ -547,7 +550,23 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
}
#endif
- if (info->instance_count > 1) {
+ if (info->indirect) {
+ cl_emit(&job->bcl, INDIRECT_INDEXED_INSTANCED_PRIM_LIST, prim) {
+ prim.index_type = ffs(info->index_size) - 1;
+#if V3D_VERSION < 40
+ prim.address_of_indices_list =
+ cl_address(rsc->bo, offset);
+#endif /* V3D_VERSION < 40 */
+ prim.mode = info->mode | prim_tf_enable;
+ prim.enable_primitive_restarts = info->primitive_restart;
+
+ prim.number_of_draw_indirect_indexed_records = info->indirect->draw_count;
+
+ prim.stride_in_multiples_of_4_bytes = info->indirect->stride >> 2;
+ prim.address = cl_address(v3d_resource(info->indirect->buffer)->bo,
+ info->indirect->offset);
+ }
+ } else if (info->instance_count > 1) {
cl_emit(&job->bcl, INDEXED_INSTANCED_PRIM_LIST, prim) {
prim.index_type = ffs(info->index_size) - 1;
#if V3D_VERSION >= 40
@@ -584,7 +603,16 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
if (info->has_user_indices)
pipe_resource_reference(&prsc, NULL);
} else {
- if (info->instance_count > 1) {
+ if (info->indirect) {
+ cl_emit(&job->bcl, INDIRECT_VERTEX_ARRAY_INSTANCED_PRIMS, prim) {
+ prim.mode = info->mode | prim_tf_enable;
+ prim.number_of_draw_indirect_array_records = info->indirect->draw_count;
+
+ prim.stride_in_multiples_of_4_bytes = info->indirect->stride >> 2;
+ prim.address = cl_address(v3d_resource(info->indirect->buffer)->bo,
+ info->indirect->offset);
+ }
+ } else if (info->instance_count > 1) {
cl_emit(&job->bcl, VERTEX_ARRAY_INSTANCED_PRIMS, prim) {
prim.mode = info->mode | prim_tf_enable;
prim.index_of_first_vertex = info->start;