Commit 399215eb authored by Ilia Mirkin's avatar Ilia Mirkin
Browse files

nvc0: add support for handling indirect draws with attrib conversion



The hardware does not natively support FIXED and DOUBLE formats. If
those are used in an indirect draw, they have to be converted. Our
conversion tries to be clever about only converting the data that's
needed. However for indirect, that won't work.

Given that DOUBLE or FIXED are highly unlikely to ever be used with
indirect draws, read the indirect buffer on the CPU and issue draws
directly.

Fixes the failing dEQP-GLES31.functional.draw_indirect.random.* tests.
Signed-off-by: Ilia Mirkin's avatarIlia Mirkin <imirkin@alum.mit.edu>
Cc: 19.0 <mesa-stable@lists.freedesktop.org>
parent 0f7a20e9
......@@ -434,6 +434,7 @@ nvc0_video_buffer_create(struct pipe_context *pipe,
/* nvc0_push.c */
void nvc0_push_vbo(struct nvc0_context *, const struct pipe_draw_info *);
void nvc0_push_vbo_indirect(struct nvc0_context *, const struct pipe_draw_info *);
/* nve4_compute.c */
void nve4_launch_grid(struct pipe_context *, const struct pipe_grid_info *);
......
......@@ -1040,7 +1040,10 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
}
if (nvc0->state.vbo_mode) {
nvc0_push_vbo(nvc0, info);
if (info->indirect)
nvc0_push_vbo_indirect(nvc0, info);
else
nvc0_push_vbo(nvc0, info);
goto cleanup;
}
......
......@@ -466,6 +466,83 @@ nvc0_prim_gl(unsigned prim)
}
}
typedef struct {
uint32_t count;
uint32_t primCount;
uint32_t first;
uint32_t baseInstance;
} DrawArraysIndirectCommand;
typedef struct {
uint32_t count;
uint32_t primCount;
uint32_t firstIndex;
int32_t baseVertex;
uint32_t baseInstance;
} DrawElementsIndirectCommand;
void
nvc0_push_vbo_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
{
/* The strategy here is to just read the commands from the indirect buffer
* and do the draws. This is suboptimal, but will only happen in the case
* that conversion is required for FIXED or DOUBLE inputs.
*/
struct nvc0_screen *screen = nvc0->screen;
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nv04_resource *buf = nv04_resource(info->indirect->buffer);
struct nv04_resource *buf_count = nv04_resource(info->indirect->indirect_draw_count);
unsigned i;
unsigned draw_count = info->indirect->draw_count;
if (buf_count) {
uint32_t *count = nouveau_resource_map_offset(
&nvc0->base, buf_count, info->indirect->indirect_draw_count_offset,
NOUVEAU_BO_RD);
draw_count = *count;
}
uint8_t *buf_data = nouveau_resource_map_offset(
&nvc0->base, buf, info->indirect->offset, NOUVEAU_BO_RD);
struct pipe_draw_info single = *info;
single.indirect = NULL;
for (i = 0; i < draw_count; i++, buf_data += info->indirect->stride) {
if (info->index_size) {
DrawElementsIndirectCommand *cmd = (void *)buf_data;
single.start = info->start + cmd->firstIndex;
single.count = cmd->count;
single.start_instance = cmd->baseInstance;
single.instance_count = cmd->primCount;
single.index_bias = cmd->baseVertex;
} else {
DrawArraysIndirectCommand *cmd = (void *)buf_data;
single.start = cmd->first;
single.count = cmd->count;
single.start_instance = cmd->baseInstance;
single.instance_count = cmd->primCount;
}
if (nvc0->vertprog->vp.need_draw_parameters) {
PUSH_SPACE(push, 9);
BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
PUSH_DATA (push, NVC0_CB_AUX_SIZE);
PUSH_DATAh(push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(0));
PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(0));
BEGIN_1IC0(push, NVC0_3D(CB_POS), 1 + 3);
PUSH_DATA (push, NVC0_CB_AUX_DRAW_INFO);
PUSH_DATA (push, single.index_bias);
PUSH_DATA (push, single.start_instance);
PUSH_DATA (push, single.drawid + i);
}
nvc0_push_vbo(nvc0, &single);
}
nouveau_resource_unmap(buf);
if (buf_count)
nouveau_resource_unmap(buf_count);
}
void
nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment