From: Marek Olšák <marek.ol...@amd.com> They are done with instancing. --- src/gallium/auxiliary/util/u_blitter.c | 52 +++++++++++++-------------- src/gallium/auxiliary/util/u_blitter.h | 5 +-- src/gallium/drivers/r300/r300_context.h | 2 +- src/gallium/drivers/r300/r300_render.c | 8 +++-- src/gallium/drivers/radeon/r600_pipe_common.c | 13 +++++-- src/gallium/drivers/radeon/r600_pipe_common.h | 3 +- 6 files changed, 47 insertions(+), 36 deletions(-)
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 37a92d2..de2a27a 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -1246,39 +1246,40 @@ static void blitter_draw(struct blitter_context_priv *ctx, return; u_upload_unmap(pipe->stream_uploader); pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb); util_draw_arrays_instanced(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4, 0, num_instances); pipe_resource_reference(&vb.buffer.resource, NULL); } void util_blitter_draw_rectangle(struct blitter_context *blitter, - int x1, int y1, int x2, int y2, float depth, + int x1, int y1, int x2, int y2, + float depth, unsigned num_instances, enum blitter_attrib_type type, const union blitter_attrib *attrib) { struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; switch (type) { case UTIL_BLITTER_ATTRIB_COLOR: blitter_set_clear_color(ctx, (uint32_t*)attrib->color); break; case UTIL_BLITTER_ATTRIB_TEXCOORD: set_texcoords_in_vertices(attrib, &ctx->vertices[0][1][0], 8); break; default:; } - blitter_draw(ctx, x1, y1, x2, y2, depth, 1); + blitter_draw(ctx, x1, y1, x2, y2, depth, num_instances); } static void *get_clear_blend_state(struct blitter_context_priv *ctx, unsigned clear_buffers) { struct pipe_context *pipe = ctx->base.pipe; int index; clear_buffers &= PIPE_CLEAR_COLOR; @@ -1359,32 +1360,31 @@ static void util_blitter_clear_custom(struct blitter_context *blitter, util_blitter_common_clear_setup(blitter, clear_buffers, custom_blend, custom_dsa); sr.ref_value[0] = stencil & 0xff; pipe->set_stencil_ref(pipe, &sr); pipe->bind_vertex_elements_state(pipe, ctx->velem_state); bind_fs_write_all_cbufs(ctx); + union blitter_attrib attrib; + memcpy(attrib.color, color->ui, sizeof(color->ui)); + if (num_layers > 1 && ctx->has_layered) { blitter_set_common_draw_rect_state(ctx, FALSE, TRUE); - blitter_set_clear_color(ctx, color->ui); - blitter_draw(ctx, 0, 0, width, height, depth, num_layers); - } - else { - union blitter_attrib attrib; - - memcpy(attrib.color, color->ui, sizeof(color->ui)); + blitter->draw_rectangle(blitter, 0, 0, width, height, (float) depth, + num_layers, UTIL_BLITTER_ATTRIB_COLOR, &attrib); + } else { blitter_set_common_draw_rect_state(ctx, FALSE, FALSE); blitter->draw_rectangle(blitter, 0, 0, width, height, (float) depth, - UTIL_BLITTER_ATTRIB_COLOR, &attrib); + 1, UTIL_BLITTER_ATTRIB_COLOR, &attrib); } util_blitter_restore_vertex_states(blitter); util_blitter_restore_fragment_states(blitter); util_blitter_restore_render_cond(blitter); util_blitter_unset_running_flag(blitter); } void util_blitter_clear(struct blitter_context *blitter, unsigned width, unsigned height, unsigned num_layers, @@ -1618,21 +1618,21 @@ static void do_blits(struct blitter_context_priv *ctx, fb_state.zsbuf = dst; } else { fb_state.cbufs[0] = dst; } pipe->set_framebuffer_state(pipe, &fb_state); /* Draw. */ pipe->set_sample_mask(pipe, ~0); ctx->base.draw_rectangle(&ctx->base, dstbox->x, dstbox->y, dstbox->x + dstbox->width, - dstbox->y + dstbox->height, 0, + dstbox->y + dstbox->height, 0, 1, UTIL_BLITTER_ATTRIB_TEXCOORD, &coord); } else { /* Draw the quad with the generic codepath. */ int dst_z; for (dst_z = 0; dst_z < dstbox->depth; dst_z++) { struct pipe_surface *old; float dst2src_scale = srcbox->depth / (float)dstbox->depth; /* Scale Z properly if the blit is scaled. * @@ -2075,33 +2075,32 @@ void util_blitter_clear_render_target(struct blitter_context *blitter, /* set a framebuffer state */ fb_state.width = dstsurf->width; fb_state.height = dstsurf->height; fb_state.nr_cbufs = 1; fb_state.cbufs[0] = dstsurf; fb_state.zsbuf = 0; pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_sample_mask(pipe, ~0); + union blitter_attrib attrib; + memcpy(attrib.color, color->ui, sizeof(color->ui)); + num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1; if (num_layers > 1 && ctx->has_layered) { blitter_set_common_draw_rect_state(ctx, FALSE, TRUE); - blitter_set_clear_color(ctx, color->ui); - blitter_draw(ctx, dstx, dsty, dstx+width, dsty+height, 0, num_layers); - } - else { - union blitter_attrib attrib; - - memcpy(attrib.color, color->ui, sizeof(color->ui)); + blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0, + num_layers, UTIL_BLITTER_ATTRIB_COLOR, &attrib); + } else { blitter_set_common_draw_rect_state(ctx, FALSE, FALSE); blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0, - UTIL_BLITTER_ATTRIB_COLOR, &attrib); + 1, UTIL_BLITTER_ATTRIB_COLOR, &attrib); } util_blitter_restore_vertex_states(blitter); util_blitter_restore_fragment_states(blitter); util_blitter_restore_fb_state(blitter); util_blitter_restore_render_cond(blitter); util_blitter_unset_running_flag(blitter); } /* Clear a region of a depth stencil surface. */ @@ -2157,26 +2156,27 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter, fb_state.height = dstsurf->height; fb_state.nr_cbufs = 0; fb_state.cbufs[0] = 0; fb_state.zsbuf = dstsurf; pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_sample_mask(pipe, ~0); num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1; if (num_layers > 1 && ctx->has_layered) { blitter_set_common_draw_rect_state(ctx, FALSE, TRUE); - blitter_draw(ctx, dstx, dsty, dstx+width, dsty+height, (float) depth, num_layers); - } - else { + blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, + depth, num_layers, + UTIL_BLITTER_ATTRIB_NONE, NULL); + } else { blitter_set_common_draw_rect_state(ctx, FALSE, FALSE); blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, - (float) depth, + depth, 1, UTIL_BLITTER_ATTRIB_NONE, NULL); } util_blitter_restore_vertex_states(blitter); util_blitter_restore_fragment_states(blitter); util_blitter_restore_fb_state(blitter); util_blitter_restore_render_cond(blitter); util_blitter_unset_running_flag(blitter); } @@ -2222,21 +2222,21 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter, } else { fb_state.cbufs[0] = NULL; fb_state.nr_cbufs = 0; } fb_state.zsbuf = zsurf; pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_sample_mask(pipe, sample_mask); blitter_set_common_draw_rect_state(ctx, FALSE, FALSE); blitter->draw_rectangle(blitter, 0, 0, zsurf->width, zsurf->height, depth, - UTIL_BLITTER_ATTRIB_NONE, NULL); + 1, UTIL_BLITTER_ATTRIB_NONE, NULL); util_blitter_restore_vertex_states(blitter); util_blitter_restore_fragment_states(blitter); util_blitter_restore_fb_state(blitter); util_blitter_restore_render_cond(blitter); util_blitter_unset_running_flag(blitter); } void util_blitter_copy_buffer(struct blitter_context *blitter, struct pipe_resource *dst, @@ -2421,21 +2421,21 @@ void util_blitter_custom_resolve_color(struct blitter_context *blitter, fb_state.width = src->width0; fb_state.height = src->height0; fb_state.nr_cbufs = 2; fb_state.cbufs[0] = srcsurf; fb_state.cbufs[1] = dstsurf; fb_state.zsbuf = NULL; pipe->set_framebuffer_state(pipe, &fb_state); blitter_set_common_draw_rect_state(ctx, FALSE, FALSE); blitter->draw_rectangle(blitter, 0, 0, src->width0, src->height0, - 0, 0, NULL); + 0, 1, 0, NULL); util_blitter_restore_fb_state(blitter); util_blitter_restore_vertex_states(blitter); util_blitter_restore_fragment_states(blitter); util_blitter_restore_render_cond(blitter); util_blitter_unset_running_flag(blitter); pipe_surface_reference(&srcsurf, NULL); pipe_surface_reference(&dstsurf, NULL); } @@ -2470,18 +2470,18 @@ void util_blitter_custom_color(struct blitter_context *blitter, fb_state.width = dstsurf->width; fb_state.height = dstsurf->height; fb_state.nr_cbufs = 1; fb_state.cbufs[0] = dstsurf; fb_state.zsbuf = 0; pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_sample_mask(pipe, ~0); blitter_set_common_draw_rect_state(ctx, FALSE, FALSE); blitter->draw_rectangle(blitter, 0, 0, dstsurf->width, dstsurf->height, - 0, 0, NULL); + 0, 1, 0, NULL); util_blitter_restore_vertex_states(blitter); util_blitter_restore_fragment_states(blitter); util_blitter_restore_fb_state(blitter); util_blitter_restore_render_cond(blitter); util_blitter_unset_running_flag(blitter); } diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h index 07429f6..304d27e 100644 --- a/src/gallium/auxiliary/util/u_blitter.h +++ b/src/gallium/auxiliary/util/u_blitter.h @@ -74,21 +74,21 @@ struct blitter_context * to the GENERIC0 varying slot of a fragment shader. * * \param attrib See type. * * \note A driver may optionally override this callback to implement * a specialized hardware path for drawing a rectangle, e.g. using * a rectangular point sprite. */ void (*draw_rectangle)(struct blitter_context *blitter, int x1, int y1, int x2, int y2, - float depth, + float depth, unsigned num_instances, enum blitter_attrib_type type, const union blitter_attrib *attrib); /* Whether the blitter is running. */ boolean running; /* Private members, really. */ struct pipe_context *pipe; /**< pipe context */ void *saved_blend_state; /**< blend state */ @@ -147,21 +147,22 @@ struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter) /** * Override PIPE_CAP_TEXTURE_MULTISAMPLE as reported by the driver. */ void util_blitter_set_texture_multisample(struct blitter_context *blitter, boolean supported); /* The default function to draw a rectangle. This can only be used * inside of the draw_rectangle callback if the driver overrides it. */ void util_blitter_draw_rectangle(struct blitter_context *blitter, - int x1, int y1, int x2, int y2, float depth, + int x1, int y1, int x2, int y2, + float depth, unsigned num_instances, enum blitter_attrib_type type, const union blitter_attrib *attrib); /* * These states must be saved before any of the following functions are called: * - vertex buffers * - vertex elements * - vertex shader * - geometry shader (if supported) diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index a99d50f..84b8748 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -737,21 +737,21 @@ void r300_translate_index_buffer(struct r300_context *r300, unsigned *index_size, unsigned index_offset, unsigned *start, unsigned count); /* r300_render_stencilref.c */ void r300_plug_in_stencil_ref_fallback(struct r300_context *r300); /* r300_render.c */ void r500_emit_index_bias(struct r300_context *r300, int index_bias); void r300_blitter_draw_rectangle(struct blitter_context *blitter, int x1, int y1, int x2, int y2, - float depth, + float depth, unsigned num_instances, enum blitter_attrib_type type, const union blitter_attrib *attrib); /* r300_state.c */ enum r300_fb_state_change { R300_CHANGED_FB_STATE = 0, R300_CHANGED_HYPERZ_FLAG, R300_CHANGED_MULTIWRITE, R300_CHANGED_CMASK_ENABLE, }; diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index e1fabe4..1f896da 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -1107,39 +1107,41 @@ struct draw_stage* r300_draw_stage(struct r300_context* r300) * End of SW TCL functions * ***************************************************************************/ /* This functions is used to draw a rectangle for the blitter module. * * If we rendered a quad, the pixels on the main diagonal * would be computed and stored twice, which makes the clear/copy codepaths * somewhat inefficient. Instead we use a rectangular point sprite. */ void r300_blitter_draw_rectangle(struct blitter_context *blitter, int x1, int y1, int x2, int y2, - float depth, + float depth, unsigned num_instances, enum blitter_attrib_type type, const union blitter_attrib *attrib) { struct r300_context *r300 = r300_context(util_blitter_get_pipe(blitter)); unsigned last_sprite_coord_enable = r300->sprite_coord_enable; unsigned width = x2 - x1; unsigned height = y2 - y1; unsigned vertex_size = type == UTIL_BLITTER_ATTRIB_COLOR || !r300->draw ? 8 : 4; unsigned dwords = 13 + vertex_size + (type == UTIL_BLITTER_ATTRIB_TEXCOORD ? 7 : 0); static const union blitter_attrib zeros; CS_LOCALS(r300); /* XXX workaround for a lockup in MSAA resolve on SWTCL chipsets, this * function most probably doesn't handle type=NONE correctly */ - if (!r300->screen->caps.has_tcl && type == UTIL_BLITTER_ATTRIB_NONE) { - util_blitter_draw_rectangle(blitter, x1, y1, x2, y2, depth, type, attrib); + if ((!r300->screen->caps.has_tcl && type == UTIL_BLITTER_ATTRIB_NONE) || + num_instances > 1) { + util_blitter_draw_rectangle(blitter, x1, y1, x2, y2, depth, + num_instances, type, attrib); return; } if (r300->skip_rendering) return; if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) r300->sprite_coord_enable = 1; r300_update_derived_state(r300); diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index 9619031..90127dc 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -198,21 +198,22 @@ void r600_gfx_wait_fence(struct r600_common_context *ctx, radeon_emit(cs, PKT3(PKT3_WAIT_REG_MEM, 5, 0)); radeon_emit(cs, WAIT_REG_MEM_EQUAL | WAIT_REG_MEM_MEM_SPACE(1)); radeon_emit(cs, va); radeon_emit(cs, va >> 32); radeon_emit(cs, ref); /* reference value */ radeon_emit(cs, mask); /* mask */ radeon_emit(cs, 4); /* poll interval */ } void r600_draw_rectangle(struct blitter_context *blitter, - int x1, int y1, int x2, int y2, float depth, + int x1, int y1, int x2, int y2, + float depth, unsigned num_instances, enum blitter_attrib_type type, const union blitter_attrib *attrib) { struct r600_common_context *rctx = (struct r600_common_context*)util_blitter_get_pipe(blitter); struct pipe_viewport_state viewport; struct pipe_resource *buf = NULL; unsigned offset = 0; float *vb; @@ -267,22 +268,28 @@ void r600_draw_rectangle(struct blitter_context *blitter, vb[5] = attrib->texcoord.y1; vb[12] = attrib->texcoord.x1; vb[13] = attrib->texcoord.y2; vb[20] = attrib->texcoord.x2; vb[21] = attrib->texcoord.y1; break; default:; /* Nothing to do. */ } /* draw */ - util_draw_vertex_buffer(&rctx->b, NULL, buf, blitter->vb_slot, offset, - R600_PRIM_RECTANGLE_LIST, 3, 2); + struct pipe_vertex_buffer vbuffer = {}; + vbuffer.buffer.resource = buf; + vbuffer.stride = 2 * 4 * sizeof(float); /* vertex size */ + vbuffer.buffer_offset = offset; + + rctx->b.set_vertex_buffers(&rctx->b, blitter->vb_slot, 1, &vbuffer); + util_draw_arrays_instanced(&rctx->b, R600_PRIM_RECTANGLE_LIST, 0, 3, + 0, num_instances); pipe_resource_reference(&buf, NULL); } static void r600_dma_emit_wait_idle(struct r600_common_context *rctx) { struct radeon_winsys_cs *cs = rctx->dma.cs; /* NOP waits for idle on Evergreen and later. */ if (rctx->chip_class >= CIK) radeon_emit(cs, 0x00000000); /* NOP */ diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index d9cd659..8be11ef 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -746,21 +746,22 @@ void r600_replace_buffer_storage(struct pipe_context *ctx, /* r600_common_pipe.c */ void r600_gfx_write_event_eop(struct r600_common_context *ctx, unsigned event, unsigned event_flags, unsigned data_sel, struct r600_resource *buf, uint64_t va, uint32_t new_fence, unsigned query_type); unsigned r600_gfx_write_fence_dwords(struct r600_common_screen *screen); void r600_gfx_wait_fence(struct r600_common_context *ctx, uint64_t va, uint32_t ref, uint32_t mask); void r600_draw_rectangle(struct blitter_context *blitter, - int x1, int y1, int x2, int y2, float depth, + int x1, int y1, int x2, int y2, + float depth, unsigned num_instances, enum blitter_attrib_type type, const union blitter_attrib *attrib); bool r600_common_screen_init(struct r600_common_screen *rscreen, struct radeon_winsys *ws); void r600_destroy_common_screen(struct r600_common_screen *rscreen); void r600_preflush_suspend_features(struct r600_common_context *ctx); void r600_postflush_resume_features(struct r600_common_context *ctx); bool r600_common_context_init(struct r600_common_context *rctx, struct r600_common_screen *rscreen, unsigned context_flags); -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev