mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
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 <imirkin@alum.mit.edu> Cc: 19.0 <mesa-stable@lists.freedesktop.org>
This commit is contained in:
parent
0f7a20e91e
commit
399215eb7a
3 changed files with 82 additions and 1 deletions
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue