--- docs/GL3.txt | 4 +- src/gallium/drivers/nvc0/nvc0_3d.xml.h | 4 + src/gallium/drivers/nvc0/nvc0_graph_macros.h | 121 ++++++++++++++++++++++++++ src/gallium/drivers/nvc0/nvc0_screen.c | 6 ++ src/gallium/drivers/nvc0/nvc0_vbo.c | 56 +++++++++++-- 5 files changed, 183 insertions(+), 8 deletions(-)
diff --git a/docs/GL3.txt b/docs/GL3.txt index 88621e3..b60dbb6 100644 --- a/docs/GL3.txt +++ b/docs/GL3.txt @@ -89,7 +89,7 @@ GL 4.0: GLSL 4.0 not started GL_ARB_texture_query_lod not started GL_ARB_draw_buffers_blend DONE (i965, r600, softpipe) -GL_ARB_draw_indirect not started +GL_ARB_draw_indirect DONE (nvc0, softpipe) GL_ARB_gpu_shader5 not started GL_ARB_gpu_shader_fp64 not started GL_ARB_sample_shading not started @@ -143,7 +143,7 @@ ARB_fragment_layer_viewport not started ARB_framebuffer_no_attachments not started ARB_internalformat_query2 not started ARB_invalidate_subdata not started -ARB_multi_draw_indirect not started +ARB_multi_draw_indirect DONE (nvc0, softpipe) ARB_program_interface_query not started ARB_robust_buffer_access_behavior not started ARB_shader_image_size not started diff --git a/src/gallium/drivers/nvc0/nvc0_3d.xml.h b/src/gallium/drivers/nvc0/nvc0_3d.xml.h index 1cf1f96..d90c1b6 100644 --- a/src/gallium/drivers/nvc0/nvc0_3d.xml.h +++ b/src/gallium/drivers/nvc0/nvc0_3d.xml.h @@ -1340,5 +1340,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_MACRO_TEP_SELECT 0x00003830 +#define NVC0_3D_MACRO_DRAW_ARRAYS_INDIRECT 0x00003838 + +#define NVC0_3D_MACRO_DRAW_ELEMENTS_INDIRECT 0x00003840 + #endif /* NVC0_3D_XML */ diff --git a/src/gallium/drivers/nvc0/nvc0_graph_macros.h b/src/gallium/drivers/nvc0/nvc0_graph_macros.h index f009980..e12ea6c 100644 --- a/src/gallium/drivers/nvc0/nvc0_graph_macros.h +++ b/src/gallium/drivers/nvc0/nvc0_graph_macros.h @@ -233,4 +233,125 @@ static const uint32_t nvc0_9097_tep_select[] = /* 0x10 */ 0x00003041, /* 0x10: send $r6 */ }; +/* NVC0_3D_MACRO_DRAW_ELEMENTS_INDIRECT + * + * NOTE: Saves and restores VB_ELEMENT,INSTANCE_BASE. + * + * arg = mode + * parm[0] = count + * parm[1] = instance_count + * parm[2] = start + * parm[3] = index_bias + * parm[4] = start_instance + */ +static const uint32_t nvc0_9097_draw_elts_indirect[] = +{ + /* 0x00: parm $r3 (count) */ + /* 0x01: parm $r2 (instance_count) */ + /* 0x02: parm $r4 maddr 0x5f7 (INDEX_BATCH_FIRST, start) */ + /* 0x04: parm $r4 send $r4 (index_bias, send start) */ + /* 0x05: braz $r2 END */ + /* 0x06: parm $r5 (start_instance) */ + /* 0x07: read $r6 0x50d (VB_ELEMENT_BASE) */ + /* 0x08: read $r7 0x50e (VB_INSTANCE_BASE) */ + /* 0x09: maddr 0x150d (VB_ELEMENT,INSTANCE_BASE) */ + /* 0x0a: send $r4 */ + /* 0x0b: send $r5 */ + /* 0x0c: mov $r4 0x1 */ + /* 0x0d: maddr 0x586 (VERTEX_BEGIN_GL) */ + /* 0x0e: send $r1 (mode) */ + /* 0x0f: maddr 0x5f8 (INDEX_BATCH_COUNT) */ + /* 0x10: send $r3 (count) */ + /* 0x11: mov $r2 (sub $r2 $r4) */ + /* 0x12: maddrsend 0x585 (VERTEX_END_GL) */ + /* 0x13: branz $r2 AGAIN */ + /* 0x14: mov $r1 (extrinsrt $r1 $r4 0 1 26) (set INSTANCE_NEXT) */ + /* 0x15: maddr 0x150d (VB_ELEMENT,INSTANCE_BASE) */ + /* 0x16: exit send $r6 */ + /* 0x17: send $r7 */ + /* 0x18: exit */ + /* 0x19: nop */ + 0x00000301, + 0x00000201, + 0x017dc451, + 0x00002431, + 0x0004d007, + 0x00000501, + 0x01434615, + 0x01438715, + 0x05434021, + 0x00002041, + 0x00002841, + 0x00004411, + 0x01618021, + 0x00000841, + 0x017e0021, + 0x00001841, + 0x00051210, + 0x01614071, + 0xfffe9017, + 0xd0410912, + 0x05434021, + 0x000030c1, + 0x00003841, + 0x00000091, + 0x00000011 +}; + +/* NVC0_3D_MACRO_DRAW_ARRAYS_INDIRECT: + * + * NOTE: Saves and restores VB_INSTANCE_BASE. + * + * arg = mode + * parm[0] = count + * parm[1] = instance_count + * parm[2] = start + * parm[3] = start_instance + */ +static const uint32_t nvc0_9097_draw_arrays_indirect[] = +{ + /* 0x00: parm $r2 (count) */ + /* 0x01: parm $r3 (instance_count) */ + /* 0x02: parm $r4 maddr 0x35d (VERTEX_BUFFER_FIRST, start) */ + /* 0x04: parm $r4 send $r4 (start_instance) */ + /* 0x05: braz $r3 END */ + /* 0x06: read $r6 0x50e (VB_INSTANCE_BASE) */ + /* 0x07: maddr 0x50e (VB_INSTANCE_BASE) */ + /* 0x08: mov $r5 0x1 */ + /* 0x09: send $r4 */ + /* 0x0a: maddr 0x586 (VERTEX_BEGIN_GL) */ + /* 0x0b: send $r1 (mode) */ + /* 0x0c: maddr 0x35e (VERTEX_BUFFER_COUNT) */ + /* 0x0d: send $r2 */ + /* 0x0e: mov $r3 (sub $r3 $r5) */ + /* 0x0f: maddrsend 0x585 (VERTEX_END_GL) */ + /* 0x10: branz $r3 AGAIN */ + /* 0x11: mov $r1 (extrinsrt $r1 $r5 0 1 26) (set INSTANCE_NEXT) */ + /* 0x12: exit maddr 0x50e (VB_INSTANCE_BASE to restore) */ + /* 0x13: send $r6 */ + /* 0x14: exit nop */ + /* 0x15: nop */ + 0x00000201, + 0x00000301, + 0x00d74451, + 0x00002431, + 0x0003d807, + 0x01438615, + 0x01438021, + 0x00004511, + 0x00002041, + 0x01618021, + 0x00000841, + 0x00d78021, + 0x00001041, + 0x00055b10, + 0x01614071, + 0xfffe9817, + 0xd0414912, + 0x014380a1, + 0x00003041, + 0x00000091, + 0x00000011 +}; + #endif diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index acc28d1..c0b6b9c 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -176,6 +176,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: case PIPE_CAP_TEXTURE_MULTISAMPLE: return 0; + case PIPE_CAP_DRAW_INDIRECT: + return 1; default: NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); return 0; @@ -314,6 +316,8 @@ nvc0_graph_set_macro(struct nvc0_screen *screen, uint32_t m, unsigned pos, size /= 4; + assert((pos + size) <= 0x800); + BEGIN_NVC0(push, SUBC_3D(NVC0_GRAPH_MACRO_ID), 2); PUSH_DATA (push, (m - 0x3800) / 8); PUSH_DATA (push, pos); @@ -748,6 +752,8 @@ nvc0_screen_create(struct nouveau_device *dev) MK_MACRO(NVC0_3D_MACRO_GP_SELECT, nvc0_9097_gp_select); MK_MACRO(NVC0_3D_MACRO_POLYGON_MODE_FRONT, nvc0_9097_poly_mode_front); MK_MACRO(NVC0_3D_MACRO_POLYGON_MODE_BACK, nvc0_9097_poly_mode_back); + MK_MACRO(NVC0_3D_MACRO_DRAW_ARRAYS_INDIRECT, nvc0_9097_draw_arrays_indirect); + MK_MACRO(NVC0_3D_MACRO_DRAW_ELEMENTS_INDIRECT, nvc0_9097_draw_elts_indirect); BEGIN_NVC0(push, NVC0_3D(RASTERIZE_ENABLE), 1); PUSH_DATA (push, 1); diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c index 61a6341..6750aea 100644 --- a/src/gallium/drivers/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nvc0/nvc0_vbo.c @@ -565,6 +565,8 @@ nvc0_draw_arrays(struct nvc0_context *nvc0, unsigned prim; if (nvc0->state.index_bias) { + /* index_bias is implied 0 if !info->indexed (really ?) */ + /* TODO: can we deactivate it for the VERTEX_BUFFER_FIRST command ? */ PUSH_SPACE(push, 1); IMMED_NVC0(push, NVC0_3D(VB_ELEMENT_BASE), 0); nvc0->state.index_bias = 0; @@ -781,6 +783,42 @@ nvc0_draw_stream_output(struct nvc0_context *nvc0, } } +static void +nvc0_draw_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info) +{ + struct nouveau_pushbuf *push = nvc0->base.pushbuf; + struct nv04_resource *buf = nv04_resource(info->indirect); + unsigned size; + const uint32_t offset = buf->offset + info->indirect_offset; + + if (buf->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) { + buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; + /* must make FIFO wait for engines idle before continuing to process */ + IMMED_NVC0(push, SUBC_3D(NV10_SUBCHAN_REF_CNT), 0); + } + + PUSH_SPACE(push, 8); + if (info->indexed) { + assert(nvc0->idxbuf.buffer); + assert(nouveau_resource_mapped_by_gpu(nvc0->idxbuf.buffer)); + size = 5 * 4; + BEGIN_1IC0(push, NVC0_3D(MACRO_DRAW_ELEMENTS_INDIRECT), 1 + size / 4); + } else { + if (nvc0->state.index_bias) { + /* index_bias is implied 0 if !info->indexed (really ?) */ + IMMED_NVC0(push, NVC0_3D(VB_ELEMENT_BASE), 0); + nvc0->state.index_bias = 0; + } + size = 4 * 4; + BEGIN_1IC0(push, NVC0_3D(MACRO_DRAW_ARRAYS_INDIRECT), 1 + size / 4); + } + PUSH_DATA(push, nvc0_prim_gl(info->mode)); +#define NVC0_IB_ENTRY_1_NO_PREFETCH (1 << (31 - 8)) + nouveau_pushbuf_space(push, 0, 0, 1); + nouveau_pushbuf_data(push, + buf->bo, offset, NVC0_IB_ENTRY_1_NO_PREFETCH | size); +} + void nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { @@ -863,16 +901,22 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) shorten = FALSE; } - nvc0_draw_elements(nvc0, shorten, - info->mode, info->start, info->count, - info->instance_count, info->index_bias); + if (unlikely(info->indirect)) + nvc0_draw_indirect(nvc0, info); + else + nvc0_draw_elements(nvc0, shorten, + info->mode, info->start, info->count, + info->instance_count, info->index_bias); } else if (unlikely(info->count_from_stream_output)) { nvc0_draw_stream_output(nvc0, info); } else { - nvc0_draw_arrays(nvc0, - info->mode, info->start, info->count, - info->instance_count); + if (unlikely(info->indirect)) + nvc0_draw_indirect(nvc0, info); + else + nvc0_draw_arrays(nvc0, + info->mode, info->start, info->count, + info->instance_count); } push->kick_notify = nvc0_default_kick_notify; -- 1.7.3.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev