mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-01 01:38:06 +02:00
nvc0: add support for indirect drawing
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
parent
bbc4a7bd31
commit
a284a0afa2
10 changed files with 223 additions and 32 deletions
|
|
@ -98,7 +98,7 @@ GL 4.0:
|
|||
|
||||
GLSL 4.0 not started
|
||||
GL_ARB_draw_buffers_blend DONE (i965, nv50, nvc0, r600, radeonsi, softpipe)
|
||||
GL_ARB_draw_indirect DONE (i965)
|
||||
GL_ARB_draw_indirect DONE (i965, nvc0)
|
||||
GL_ARB_gpu_shader5 started
|
||||
- 'precise' qualifier DONE
|
||||
- Dynamically uniform sampler array indices started (Chris)
|
||||
|
|
@ -165,7 +165,7 @@ GL 4.3:
|
|||
GL_ARB_framebuffer_no_attachments not started
|
||||
GL_ARB_internalformat_query2 not started
|
||||
GL_ARB_invalidate_subdata DONE (all drivers)
|
||||
GL_ARB_multi_draw_indirect DONE (i965)
|
||||
GL_ARB_multi_draw_indirect DONE (i965, nvc0)
|
||||
GL_ARB_program_interface_query not started
|
||||
GL_ARB_robust_buffer_access_behavior not started
|
||||
GL_ARB_shader_image_size not started
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ Note: some of the new features are only available with certain drivers.
|
|||
<li>GL_ARB_seamless_cubemap_per_texture on i965, llvmpipe, nvc0, r600, radeonsi, softpipe</li>
|
||||
<li>GL_ARB_fragment_layer_viewport on nv50, nvc0, llvmpipe, r600</li>
|
||||
<li>GL_AMD_vertex_shader_viewport_index on i965/gen7+, r600</li>
|
||||
<li>GL_ARB_(multi_)draw_indirect on nvc0</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -194,12 +194,14 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
|
|||
screen->lowmem_bindings = PIPE_BIND_GLOBAL; /* gallium limit */
|
||||
screen->vidmem_bindings =
|
||||
PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL |
|
||||
PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_CURSOR |
|
||||
PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT |
|
||||
PIPE_BIND_CURSOR |
|
||||
PIPE_BIND_SAMPLER_VIEW |
|
||||
PIPE_BIND_SHADER_RESOURCE | PIPE_BIND_COMPUTE_RESOURCE |
|
||||
PIPE_BIND_GLOBAL;
|
||||
screen->sysmem_bindings =
|
||||
PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_STREAM_OUTPUT;
|
||||
PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_STREAM_OUTPUT |
|
||||
PIPE_BIND_COMMAND_ARGS_BUFFER;
|
||||
|
||||
memset(&mm_config, 0, sizeof(mm_config));
|
||||
|
||||
|
|
|
|||
|
|
@ -479,7 +479,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define NV50_3D_WATCHDOG_TIMER 0x00000de4
|
||||
|
||||
#define NV50_3D_UNK0DE8 0x00000de8
|
||||
#define NV50_3D_PRIM_RESTART_WITH_DRAW_ARRAYS 0x00000de8
|
||||
|
||||
#define NV50_3D_UNK0DEC 0x00000dec
|
||||
|
||||
|
|
|
|||
|
|
@ -437,6 +437,8 @@ nv50_screen_init_hwctx(struct nv50_screen *screen)
|
|||
PUSH_DATA (push, NV50_3D_MULTISAMPLE_MODE_MS1);
|
||||
BEGIN_NV04(push, NV50_3D(MULTISAMPLE_CTRL), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(PRIM_RESTART_WITH_DRAW_ARRAYS), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NV04(push, NV50_3D(LINE_LAST_PIXEL), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(BLEND_SEPARATE_ALPHA), 1);
|
||||
|
|
|
|||
|
|
@ -223,3 +223,78 @@ locn_0a_ts:
|
|||
locn_0f_ts:
|
||||
exit maddr 0xbb
|
||||
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
|
||||
*/
|
||||
.section #mme9097_draw_elts_indirect
|
||||
parm $r3 /* count */
|
||||
parm $r2 /* instance_count */
|
||||
parm $r4 maddr 0x5f7 /* INDEX_BATCH_FIRST, start */
|
||||
parm $r4 send $r4 /* index_bias, send start */
|
||||
braz $r2 #dei_end
|
||||
parm $r5 /* start_instance */
|
||||
read $r6 0x50d /* VB_ELEMENT_BASE */
|
||||
read $r7 0x50e /* VB_INSTANCE_BASE */
|
||||
maddr 0x150d /* VB_ELEMENT,INSTANCE_BASE */
|
||||
send $r4
|
||||
send $r5
|
||||
mov $r4 0x1
|
||||
dei_again:
|
||||
maddr 0x586 /* VERTEX_BEGIN_GL */
|
||||
send $r1 /* mode */
|
||||
maddr 0x5f8 /* INDEX_BATCH_COUNT */
|
||||
send $r3 /* count */
|
||||
mov $r2 (sub $r2 $r4)
|
||||
maddrsend 0x585 /* VERTEX_END_GL */
|
||||
branz $r2 #dei_again
|
||||
mov $r1 (extrinsrt $r1 $r4 0 1 26) /* set INSTANCE_NEXT */
|
||||
maddr 0x150d /* VB_ELEMENT,INSTANCE_BASE */
|
||||
exit send $r6
|
||||
send $r7
|
||||
dei_end:
|
||||
exit
|
||||
nop
|
||||
|
||||
/* 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
|
||||
*/
|
||||
.section #mme9097_draw_arrays_indirect
|
||||
parm $r2 /* count */
|
||||
parm $r3 /* instance_count */
|
||||
parm $r4 maddr 0x35d /* VERTEX_BUFFER_FIRST, start */
|
||||
parm $r4 send $r4 /* start_instance */
|
||||
braz $r3 #dai_end
|
||||
read $r6 0x50e /* VB_INSTANCE_BASE */
|
||||
maddr 0x50e /* VB_INSTANCE_BASE */
|
||||
mov $r5 0x1
|
||||
send $r4
|
||||
dai_again:
|
||||
maddr 0x586 /* VERTEX_BEGIN_GL */
|
||||
send $r1 /* mode */
|
||||
maddr 0x35e /* VERTEX_BUFFER_COUNT */
|
||||
send $r2
|
||||
mov $r3 (sub $r3 $r5)
|
||||
maddrsend 0x585 /* VERTEX_END_GL */
|
||||
branz $r3 #dai_again
|
||||
mov $r1 (extrinsrt $r1 $r5 0 1 26) /* set INSTANCE_NEXT */
|
||||
exit maddr 0x50e /* VB_INSTANCE_BASE to restore */
|
||||
send $r6
|
||||
dai_end:
|
||||
exit
|
||||
nop
|
||||
|
|
|
|||
|
|
@ -123,3 +123,59 @@ uint32_t mme9097_tep_select[] = {
|
|||
0x002ec0a1,
|
||||
0x00003041,
|
||||
};
|
||||
|
||||
uint32_t mme9097_draw_elts_indirect[] = {
|
||||
0x00000301,
|
||||
0x00000201,
|
||||
0x017dc451,
|
||||
/* 0x000c: dei_again */
|
||||
0x00002431,
|
||||
0x0004d007,
|
||||
/* 0x0017: dei_end */
|
||||
0x00000501,
|
||||
0x01434615,
|
||||
0x01438715,
|
||||
0x05434021,
|
||||
0x00002041,
|
||||
0x00002841,
|
||||
0x00004411,
|
||||
0x01618021,
|
||||
0x00000841,
|
||||
0x017e0021,
|
||||
0x00001841,
|
||||
0x00051210,
|
||||
0x01614071,
|
||||
0xfffe9017,
|
||||
0xd0410912,
|
||||
0x05434021,
|
||||
0x000030c1,
|
||||
0x00003841,
|
||||
0x00000091,
|
||||
0x00000011,
|
||||
};
|
||||
|
||||
uint32_t mme9097_draw_arrays_indirect[] = {
|
||||
0x00000201,
|
||||
0x00000301,
|
||||
/* 0x0009: dai_again */
|
||||
0x00d74451,
|
||||
0x00002431,
|
||||
/* 0x0013: dai_end */
|
||||
0x0003d807,
|
||||
0x01438615,
|
||||
0x01438021,
|
||||
0x00004511,
|
||||
0x00002041,
|
||||
0x01618021,
|
||||
0x00000841,
|
||||
0x00d78021,
|
||||
0x00001041,
|
||||
0x00055b10,
|
||||
0x01614071,
|
||||
0xfffe9817,
|
||||
0xd0414912,
|
||||
0x014380a1,
|
||||
0x00003041,
|
||||
0x00000091,
|
||||
0x00000011,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -338,6 +338,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define NVC0_3D_WATCHDOG_TIMER 0x00000de4
|
||||
|
||||
#define NVC0_3D_PRIM_RESTART_WITH_DRAW_ARRAYS 0x00000de8
|
||||
|
||||
#define NVC0_3D_WINDOW_OFFSET_X 0x00000df8
|
||||
|
||||
#define NVC0_3D_WINDOW_OFFSET_Y 0x00000dfc
|
||||
|
|
@ -1347,5 +1349,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 */
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||
case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
|
||||
case PIPE_CAP_START_INSTANCE:
|
||||
case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
|
||||
case PIPE_CAP_DRAW_INDIRECT:
|
||||
case PIPE_CAP_USER_CONSTANT_BUFFERS:
|
||||
case PIPE_CAP_USER_INDEX_BUFFERS:
|
||||
case PIPE_CAP_USER_VERTEX_BUFFERS:
|
||||
|
|
@ -183,7 +184,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||
case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
|
||||
case PIPE_CAP_FAKE_SW_MSAA:
|
||||
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
|
||||
case PIPE_CAP_DRAW_INDIRECT:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -405,6 +405,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);
|
||||
|
|
@ -433,8 +435,6 @@ nvc0_magic_3d_init(struct nouveau_pushbuf *push, uint16_t obj_class)
|
|||
PUSH_DATA (push, (3 << 16) | 3);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x1794), 1);
|
||||
PUSH_DATA (push, (2 << 16) | 2);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x0de8), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
|
||||
if (obj_class < GM107_3D_CLASS) {
|
||||
BEGIN_NVC0(push, SUBC_3D(0x12ac), 1);
|
||||
|
|
@ -609,7 +609,8 @@ nvc0_screen_create(struct nouveau_device *dev)
|
|||
push->rsvd_kick = 5;
|
||||
|
||||
screen->base.vidmem_bindings |= PIPE_BIND_CONSTANT_BUFFER |
|
||||
PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER;
|
||||
PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER |
|
||||
PIPE_BIND_COMMAND_ARGS_BUFFER;
|
||||
screen->base.sysmem_bindings |=
|
||||
PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER;
|
||||
|
||||
|
|
@ -768,6 +769,8 @@ nvc0_screen_create(struct nouveau_device *dev)
|
|||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(LINE_LAST_PIXEL), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(PRIM_RESTART_WITH_DRAW_ARRAYS), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(BLEND_SEPARATE_ALPHA), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE_COMMON), 1);
|
||||
|
|
@ -954,6 +957,8 @@ nvc0_screen_create(struct nouveau_device *dev)
|
|||
MK_MACRO(NVC0_3D_MACRO_GP_SELECT, mme9097_gp_select);
|
||||
MK_MACRO(NVC0_3D_MACRO_POLYGON_MODE_FRONT, mme9097_poly_mode_front);
|
||||
MK_MACRO(NVC0_3D_MACRO_POLYGON_MODE_BACK, mme9097_poly_mode_back);
|
||||
MK_MACRO(NVC0_3D_MACRO_DRAW_ARRAYS_INDIRECT, mme9097_draw_arrays_indirect);
|
||||
MK_MACRO(NVC0_3D_MACRO_DRAW_ELEMENTS_INDIRECT, mme9097_draw_elts_indirect);
|
||||
|
||||
BEGIN_NVC0(push, NVC0_3D(RASTERIZE_ENABLE), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
|
|
|
|||
|
|
@ -573,6 +573,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;
|
||||
|
|
@ -794,6 +796,61 @@ 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;
|
||||
|
||||
/* must make FIFO wait for engines idle before continuing to process */
|
||||
if (buf->fence_wr && !nouveau_fence_signalled(buf->fence_wr))
|
||||
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);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
nvc0_update_prim_restart(struct nvc0_context *nvc0, boolean en, uint32_t index)
|
||||
{
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
|
||||
if (en != nvc0->state.prim_restart) {
|
||||
if (en) {
|
||||
BEGIN_NVC0(push, NVC0_3D(PRIM_RESTART_ENABLE), 2);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATA (push, index);
|
||||
} else {
|
||||
IMMED_NVC0(push, NVC0_3D(PRIM_RESTART_ENABLE), 0);
|
||||
}
|
||||
nvc0->state.prim_restart = en;
|
||||
} else
|
||||
if (en) {
|
||||
BEGIN_NVC0(push, NVC0_3D(PRIM_RESTART_INDEX), 1);
|
||||
PUSH_DATA (push, index);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
||||
{
|
||||
|
|
@ -885,42 +942,29 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
|||
nvc0->idxbuf.buffer->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT)
|
||||
nvc0->base.vbo_dirty = TRUE;
|
||||
|
||||
nvc0_update_prim_restart(nvc0, info->primitive_restart, info->restart_index);
|
||||
|
||||
if (nvc0->base.vbo_dirty) {
|
||||
if (nvc0->screen->eng3d->oclass < GM107_3D_CLASS)
|
||||
IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_FLUSH), 0);
|
||||
nvc0->base.vbo_dirty = FALSE;
|
||||
}
|
||||
|
||||
if (unlikely(info->indirect)) {
|
||||
nvc0_draw_indirect(nvc0, info);
|
||||
} else
|
||||
if (unlikely(info->count_from_stream_output)) {
|
||||
nvc0_draw_stream_output(nvc0, info);
|
||||
} else
|
||||
if (info->indexed) {
|
||||
boolean shorten = info->max_index <= 65535;
|
||||
|
||||
if (info->primitive_restart != nvc0->state.prim_restart) {
|
||||
if (info->primitive_restart) {
|
||||
BEGIN_NVC0(push, NVC0_3D(PRIM_RESTART_ENABLE), 2);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATA (push, info->restart_index);
|
||||
|
||||
if (info->restart_index > 65535)
|
||||
shorten = FALSE;
|
||||
} else {
|
||||
IMMED_NVC0(push, NVC0_3D(PRIM_RESTART_ENABLE), 0);
|
||||
}
|
||||
nvc0->state.prim_restart = info->primitive_restart;
|
||||
} else
|
||||
if (info->primitive_restart) {
|
||||
BEGIN_NVC0(push, NVC0_3D(PRIM_RESTART_INDEX), 1);
|
||||
PUSH_DATA (push, info->restart_index);
|
||||
|
||||
if (info->restart_index > 65535)
|
||||
shorten = FALSE;
|
||||
}
|
||||
if (info->primitive_restart && info->restart_index > 65535)
|
||||
shorten = FALSE;
|
||||
|
||||
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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue