diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 33adee8d77a..8d217a4053e 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -1416,3 +1416,23 @@ cso_draw_arrays(struct cso_context *cso, uint mode, uint start, uint count) cso_draw_vbo(cso, &info); } + +void +cso_draw_arrays_instanced(struct cso_context *cso, uint mode, + uint start, uint count, + uint start_instance, uint instance_count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + + info.mode = mode; + info.start = start; + info.count = count; + info.min_index = start; + info.max_index = start + count - 1; + info.start_instance = start_instance; + info.instance_count = instance_count; + + cso_draw_vbo(cso, &info); +} diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 82c8e18def0..4b433b1c7a1 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -228,6 +228,11 @@ void cso_draw_vbo(struct cso_context *cso, const struct pipe_draw_info *info); +void +cso_draw_arrays_instanced(struct cso_context *cso, uint mode, + uint start, uint count, + uint start_instance, uint instance_count); + /* helper drawing function */ void cso_draw_arrays(struct cso_context *cso, uint mode, uint start, uint count); diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 8da664afbf2..274cc473a7c 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -51,6 +51,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/u_format.h" +#include "util/u_framebuffer.h" #include "util/u_inlines.h" #include "util/u_simple_shaders.h" #include "util/u_draw_quad.h" @@ -129,6 +130,26 @@ set_vertex_shader(struct st_context *st) } +static void +set_vertex_shader_layered(struct st_context *st) +{ + struct pipe_context *pipe = st->pipe; + + if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) || + !pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER)) { + assert(!"Got layered clear, but the VS layer output is unsupported"); + set_vertex_shader(st); + return; + } + + if (!st->clear.vs_layered) { + st->clear.vs_layered = util_make_layered_clear_vertex_shader(pipe); + } + + cso_set_vertex_shader_handle(st->cso_context, st->clear.vs_layered); +} + + /** * Draw a screen-aligned quadrilateral. * Coords are clip coords with y=0=bottom. @@ -136,15 +157,19 @@ set_vertex_shader(struct st_context *st) static void draw_quad(struct st_context *st, float x0, float y0, float x1, float y1, GLfloat z, + unsigned num_instances, const union pipe_color_union *color) { - struct pipe_context *pipe = st->pipe; - struct pipe_resource *vbuf = NULL; - GLuint i, offset; + struct cso_context *cso = st->cso_context; + struct pipe_vertex_buffer vb = {0}; + GLuint i; float (*vertices)[2][4]; /**< vertex pos + color */ + vb.stride = 8 * sizeof(float); + if (u_upload_alloc(st->uploader, 0, 4 * sizeof(vertices[0]), - &offset, &vbuf, (void **) &vertices) != PIPE_OK) { + &vb.buffer_offset, &vb.buffer, + (void **) &vertices) != PIPE_OK) { return; } @@ -174,16 +199,10 @@ draw_quad(struct st_context *st, u_upload_unmap(st->uploader); /* draw */ - util_draw_vertex_buffer(pipe, - st->cso_context, - vbuf, - cso_get_aux_vertex_buffer_slot(st->cso_context), - offset, - PIPE_PRIM_TRIANGLE_FAN, - 4, /* verts */ - 2); /* attribs/vert */ - - pipe_resource_reference(&vbuf, NULL); + cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1, &vb); + cso_draw_arrays_instanced(cso, PIPE_PRIM_TRIANGLE_FAN, 0, 4, + 0, num_instances); + pipe_resource_reference(&vb.buffer, NULL); } @@ -206,6 +225,8 @@ clear_with_quad(struct gl_context *ctx, const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f; const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f; union pipe_color_union clearColor; + unsigned num_layers = + util_framebuffer_get_num_layers(&st->state.framebuffer); /* printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__, @@ -305,9 +326,13 @@ clear_with_quad(struct gl_context *ctx, } set_fragment_shader(st); - set_vertex_shader(st); cso_set_geometry_shader_handle(st->cso_context, NULL); + if (num_layers > 1) + set_vertex_shader_layered(st); + else + set_vertex_shader(st); + if (ctx->DrawBuffer->_ColorDrawBuffers[0]) { struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; GLboolean is_integer = _mesa_is_enum_format_integer(rb->InternalFormat); @@ -319,7 +344,8 @@ clear_with_quad(struct gl_context *ctx, } /* draw quad matching scissor rect */ - draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, &clearColor); + draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, num_layers, + &clearColor); /* Restore pipe state */ cso_restore_blend(st->cso_context); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index ab89b49473c..cd0a5ae98f0 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -178,6 +178,7 @@ struct st_context struct pipe_viewport_state viewport; void *vs; void *fs; + void *vs_layered; } clear; /** used for anything using util_draw_vertex_buffer */