On Mon, Jan 18, 2016 at 11:22 PM, Nicolai Hähnle <nhaeh...@gmail.com> wrote: > From: Nicolai Hähnle <nicolai.haeh...@amd.com> > > Use instancing to generate two triangles for each destination layer and use > a geometry shader to route the layer index.
A better way is to disable the geometry shader and write the layer index in the vertex shader. Some drivers (such as svga) might not support it though. > --- > src/mesa/state_tracker/st_cb_texture.c | 145 > +++++++++++++++++++++++++++------ > src/mesa/state_tracker/st_context.h | 2 + > 2 files changed, 122 insertions(+), 25 deletions(-) > > diff --git a/src/mesa/state_tracker/st_cb_texture.c > b/src/mesa/state_tracker/st_cb_texture.c > index c3aadb5..7804786 100644 > --- a/src/mesa/state_tracker/st_cb_texture.c > +++ b/src/mesa/state_tracker/st_cb_texture.c > @@ -698,17 +698,9 @@ st_init_pbo_upload(struct st_context *st) > > st->pbo_upload.rgba_only = > screen->get_param(screen, PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY); > - > - /* Create the vertex shader */ > - { > - unsigned semantic_names[] = { TGSI_SEMANTIC_POSITION }; > - unsigned semantic_indexes[] = { 0 }; > - > - st->pbo_upload.vs = util_make_vertex_passthrough_shader(pipe, 1, > - semantic_names, > - > semantic_indexes, > - FALSE); > - } > + st->pbo_upload.upload_layers = > + screen->get_param(screen, PIPE_CAP_TGSI_INSTANCEID) && > + screen->get_param(screen, PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES) >= 3; > > /* Blend state */ > memset(&st->pbo_upload.blend, 0, sizeof(struct pipe_blend_state)); > @@ -1113,7 +1105,82 @@ reinterpret_formats(enum pipe_format *src_format, enum > pipe_format *dst_format) > } > > static void * > -create_pbo_upload_shader(struct pipe_context *pipe) > +create_pbo_upload_vs(struct st_context *st) > +{ > + struct ureg_program *ureg; > + struct ureg_src in_pos; > + struct ureg_src in_instanceid; > + struct ureg_dst out_pos; > + > + ureg = ureg_create(TGSI_PROCESSOR_VERTEX); > + > + in_pos = ureg_DECL_vs_input(ureg, TGSI_SEMANTIC_POSITION); > + > + if (st->pbo_upload.upload_layers) > + in_instanceid = ureg_DECL_system_value(ureg, TGSI_SEMANTIC_INSTANCEID, > 0); > + > + out_pos = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); > + > + /* out_pos = in_pos */ > + ureg_MOV(ureg, out_pos, in_pos); > + > + if (st->pbo_upload.upload_layers) { > + /* out_pos.z = i2f(gl_InstanceID) */ > + ureg_I2F(ureg, ureg_writemask(out_pos, TGSI_WRITEMASK_Z), > + ureg_scalar(in_instanceid, TGSI_SWIZZLE_X)); > + } > + > + ureg_END(ureg); > + > + return ureg_create_shader_and_destroy(ureg, st->pipe); > +} > + > +static void * > +create_pbo_upload_gs(struct st_context *st) > +{ > + static const int zero = 0; > + struct ureg_program *ureg; > + struct ureg_dst out_pos; > + struct ureg_dst out_layer; > + struct ureg_src in_pos; > + struct ureg_src imm; > + unsigned i; > + > + ureg = ureg_create(TGSI_PROCESSOR_GEOMETRY); > + if (!ureg) > + return NULL; > + > + ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM, PIPE_PRIM_TRIANGLES); > + ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM, > PIPE_PRIM_TRIANGLE_STRIP); > + ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES, 3); > + > + out_pos = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); > + out_layer = ureg_DECL_output(ureg, TGSI_SEMANTIC_LAYER, 0); > + > + in_pos = ureg_DECL_input(ureg, TGSI_SEMANTIC_POSITION, 0, 0, 1); > + > + imm = ureg_DECL_immediate_int(ureg, &zero, 1); > + > + for (i = 0; i < 3; ++i) { > + struct ureg_src in_pos_vertex = ureg_src_dimension(in_pos, i); > + > + /* out_pos = in_pos[i] */ > + ureg_MOV(ureg, out_pos, in_pos_vertex); > + > + /* out_layer.x = f2i(in_pos[i].z) */ > + ureg_F2I(ureg, ureg_writemask(out_layer, TGSI_WRITEMASK_X), > + ureg_scalar(in_pos_vertex, TGSI_SWIZZLE_Z)); > + > + ureg_EMIT(ureg, ureg_scalar(imm, TGSI_SWIZZLE_X)); > + } > + > + ureg_END(ureg); > + > + return ureg_create_shader_and_destroy(ureg, st->pipe); > +} > + > +static void * > +create_pbo_upload_fs(struct st_context *st) > { > struct ureg_program *ureg; > struct ureg_dst out; > @@ -1122,7 +1189,10 @@ create_pbo_upload_shader(struct pipe_context *pipe) > struct ureg_src const0; > struct ureg_dst temp0; > > - ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); > + ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); > + if (!ureg) > + return NULL; > + > out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); > sampler = ureg_DECL_sampler(ureg, 0); > pos = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_POSITION, 0, > @@ -1130,15 +1200,15 @@ create_pbo_upload_shader(struct pipe_context *pipe) > const0 = ureg_DECL_constant(ureg, 0); > temp0 = ureg_DECL_temporary(ureg); > > - /* Note: const0 = [ -xoffset, -yoffset, stride, 0 ] */ > + /* Note: const0 = [ -xoffset, -yoffset, stride, stride * image_height ] */ > > ureg_MOV(ureg, temp0, pos); > > - /* temp0.xy = f2i(temp0.xy) */ > - ureg_F2I(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_XY), > + /* temp0.xyz = f2i(temp0.xyz) */ > + ureg_F2I(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_XYZ), > ureg_swizzle(ureg_src(temp0), > TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, > - TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Y)); > + TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z)); I think this relies on unclamped POSITION.z, right? I wonder if POSITION.z is always unclamped if depth clipping is disabled. Marek _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev