Am 30.11.2016 um 14:35 schrieb Nicolai Hähnle: > From: Nicolai Hähnle <nicolai.haeh...@amd.com> > > This is for geometry shader outputs. Without it, drivers have no way of > knowing which stream each output is intended for, and have to > conservatively write all outputs to all streams. > > Separate stream numbers for each component are required due to output > packing. Are you sure this is true? This is an area I don't know much about, but https://www.opengl.org/wiki/Layout_Qualifier_(GLSL) tells me "Stream assignments for a geometry shader are required to be the same for all members of a block, but offsets are not."
Therefore I don't think output packing should ever happen across multiple streams. I think it would be MUCH nicer if the semantic needed just one stream member... Roland > --- > src/compiler/glsl/ir_print_visitor.cpp | 4 +-- > src/gallium/auxiliary/tgsi/tgsi_build.c | 18 +++++++++-- > src/gallium/auxiliary/tgsi/tgsi_dump.c | 13 ++++++++ > src/gallium/auxiliary/tgsi/tgsi_text.c | 48 > ++++++++++++++++++++++++++++++ > src/gallium/include/pipe/p_shader_tokens.h | 5 +++- > 5 files changed, 83 insertions(+), 5 deletions(-) > > diff --git a/src/compiler/glsl/ir_print_visitor.cpp > b/src/compiler/glsl/ir_print_visitor.cpp > index 2b77c14..d401426 100644 > --- a/src/compiler/glsl/ir_print_visitor.cpp > +++ b/src/compiler/glsl/ir_print_visitor.cpp > @@ -173,26 +173,26 @@ void ir_print_visitor::visit(ir_variable *ir) > if (ir->data.location != -1) > snprintf(loc, sizeof(loc), "location=%i ", ir->data.location); > > char component[32] = {0}; > if (ir->data.explicit_component) > snprintf(component, sizeof(component), "component=%i ", > ir->data.location_frac); > > char stream[32] = {0}; > if (ir->data.stream & (1u << 31)) { > if (ir->data.stream & ~(1u << 31)) { > - snprintf(stream, sizeof(stream), "stream(%u,%u,%u,%u)", > + snprintf(stream, sizeof(stream), "stream(%u,%u,%u,%u) ", > ir->data.stream & 3, (ir->data.stream >> 2) & 3, > (ir->data.stream >> 4) & 3, (ir->data.stream >> 6) & 3); > } > } else if (ir->data.stream) { > - snprintf(stream, sizeof(stream), "stream%u", ir->data.stream); > + snprintf(stream, sizeof(stream), "stream%u ", ir->data.stream); > } > > const char *const cent = (ir->data.centroid) ? "centroid " : ""; > const char *const samp = (ir->data.sample) ? "sample " : ""; > const char *const patc = (ir->data.patch) ? "patch " : ""; > const char *const inv = (ir->data.invariant) ? "invariant " : ""; > const char *const prec = (ir->data.precise) ? "precise " : ""; > const char *const mode[] = { "", "uniform ", "shader_storage ", > "shader_shared ", "shader_in ", "shader_out > ", > "in ", "out ", "inout ", > diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c > b/src/gallium/auxiliary/tgsi/tgsi_build.c > index d525c8f..773f892 100644 > --- a/src/gallium/auxiliary/tgsi/tgsi_build.c > +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c > @@ -232,40 +232,50 @@ tgsi_build_declaration_interp(unsigned interpolate, > return di; > } > > static struct tgsi_declaration_semantic > tgsi_default_declaration_semantic( void ) > { > struct tgsi_declaration_semantic ds; > > ds.Name = TGSI_SEMANTIC_POSITION; > ds.Index = 0; > - ds.Padding = 0; > + ds.StreamX = 0; > + ds.StreamY = 0; > + ds.StreamZ = 0; > + ds.StreamW = 0; > > return ds; > } > > static struct tgsi_declaration_semantic > tgsi_build_declaration_semantic( > unsigned semantic_name, > unsigned semantic_index, > + unsigned streamx, > + unsigned streamy, > + unsigned streamz, > + unsigned streamw, > struct tgsi_declaration *declaration, > struct tgsi_header *header ) > { > struct tgsi_declaration_semantic ds; > > assert( semantic_name <= TGSI_SEMANTIC_COUNT ); > assert( semantic_index <= 0xFFFF ); > > ds.Name = semantic_name; > ds.Index = semantic_index; > - ds.Padding = 0; > + ds.StreamX = streamx; > + ds.StreamY = streamy; > + ds.StreamZ = streamz; > + ds.StreamW = streamw; > > declaration_grow( declaration, header ); > > return ds; > } > > static struct tgsi_declaration_image > tgsi_default_declaration_image(void) > { > struct tgsi_declaration_image di; > @@ -454,20 +464,24 @@ tgsi_build_full_declaration( > struct tgsi_declaration_semantic *ds; > > if( maxsize <= size ) > return 0; > ds = (struct tgsi_declaration_semantic *) &tokens[size]; > size++; > > *ds = tgsi_build_declaration_semantic( > full_decl->Semantic.Name, > full_decl->Semantic.Index, > + full_decl->Semantic.StreamX, > + full_decl->Semantic.StreamY, > + full_decl->Semantic.StreamZ, > + full_decl->Semantic.StreamW, > declaration, > header ); > } > > if (full_decl->Declaration.File == TGSI_FILE_IMAGE) { > struct tgsi_declaration_image *di; > > if (maxsize <= size) { > return 0; > } > diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c > b/src/gallium/auxiliary/tgsi/tgsi_dump.c > index 614bcb2..f74aad1 100644 > --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c > +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c > @@ -353,20 +353,33 @@ iter_declaration( > if (decl->Declaration.Semantic) { > TXT( ", " ); > ENM( decl->Semantic.Name, tgsi_semantic_names ); > if (decl->Semantic.Index != 0 || > decl->Semantic.Name == TGSI_SEMANTIC_TEXCOORD || > decl->Semantic.Name == TGSI_SEMANTIC_GENERIC) { > CHR( '[' ); > UID( decl->Semantic.Index ); > CHR( ']' ); > } > + > + if (decl->Semantic.StreamX != 0 || decl->Semantic.StreamY != 0 || > + decl->Semantic.StreamZ != 0 || decl->Semantic.StreamW != 0) { > + TXT(", STREAM("); > + UID(decl->Semantic.StreamX); > + TXT(", "); > + UID(decl->Semantic.StreamY); > + TXT(", "); > + UID(decl->Semantic.StreamZ); > + TXT(", "); > + UID(decl->Semantic.StreamW); > + CHR(')'); > + } > } > > if (decl->Declaration.File == TGSI_FILE_IMAGE) { > TXT(", "); > ENM(decl->Image.Resource, tgsi_texture_names); > TXT(", "); > TXT(util_format_name(decl->Image.Format)); > if (decl->Image.Writable) > TXT(", WR"); > if (decl->Image.Raw) > diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c > b/src/gallium/auxiliary/tgsi/tgsi_text.c > index be80842..1b4f594 100644 > --- a/src/gallium/auxiliary/tgsi/tgsi_text.c > +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c > @@ -1539,20 +1539,68 @@ static boolean parse_declaration( struct > translate_ctx *ctx ) > ctx->cur = cur; > break; > } > } > } > } > } > > cur = ctx->cur; > eat_opt_white( &cur ); > + if (*cur == ',' && > + file == TGSI_FILE_OUTPUT && ctx->processor == PIPE_SHADER_GEOMETRY) { > + cur++; > + eat_opt_white(&cur); > + if (str_match_nocase_whole(&cur, "STREAM")) { > + uint stream[4]; > + > + eat_opt_white(&cur); > + if (*cur != '(') { > + report_error(ctx, "Expected '('"); > + return FALSE; > + } > + cur++; > + > + for (int i = 0; i < 4; ++i) { > + eat_opt_white(&cur); > + if (!parse_uint(&cur, &stream[i])) { > + report_error(ctx, "Expected literal integer"); > + return FALSE; > + } > + > + eat_opt_white(&cur); > + if (i < 3) { > + if (*cur != ',') { > + report_error(ctx, "Expected ','"); > + return FALSE; > + } > + cur++; > + } > + } > + > + if (*cur != ')') { > + report_error(ctx, "Expected ')'"); > + return FALSE; > + } > + cur++; > + > + decl.Semantic.StreamX = stream[0]; > + decl.Semantic.StreamY = stream[1]; > + decl.Semantic.StreamZ = stream[2]; > + decl.Semantic.StreamW = stream[3]; > + > + ctx->cur = cur; > + } > + } > + > + cur = ctx->cur; > + eat_opt_white( &cur ); > if (*cur == ',' && !is_vs_input) { > uint i; > > cur++; > eat_opt_white( &cur ); > for (i = 0; i < TGSI_INTERPOLATE_COUNT; i++) { > if (str_match_nocase_whole( &cur, tgsi_interpolate_names[i] )) { > decl.Declaration.Interpolate = 1; > decl.Interp.Interpolate = i; > > diff --git a/src/gallium/include/pipe/p_shader_tokens.h > b/src/gallium/include/pipe/p_shader_tokens.h > index 4a259db..ee59df0 100644 > --- a/src/gallium/include/pipe/p_shader_tokens.h > +++ b/src/gallium/include/pipe/p_shader_tokens.h > @@ -200,21 +200,24 @@ enum tgsi_semantic { > TGSI_SEMANTIC_BASEINSTANCE, > TGSI_SEMANTIC_DRAWID, > TGSI_SEMANTIC_WORK_DIM, /**< opencl get_work_dim value */ > TGSI_SEMANTIC_COUNT, /**< number of semantic values */ > }; > > struct tgsi_declaration_semantic > { > unsigned Name : 8; /**< one of TGSI_SEMANTIC_x */ > unsigned Index : 16; /**< UINT */ > - unsigned Padding : 8; > + unsigned StreamX : 2; /**< vertex stream (for GS output) */ > + unsigned StreamY : 2; > + unsigned StreamZ : 2; > + unsigned StreamW : 2; > }; > > struct tgsi_declaration_image { > unsigned Resource : 8; /**< one of TGSI_TEXTURE_ */ > unsigned Raw : 1; > unsigned Writable : 1; > unsigned Format : 10; /**< one of PIPE_FORMAT_ */ > unsigned Padding : 12; > }; > > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev