[Mesa-dev] [PATCH 02/23] tgsi: add Stream{X, Y, Z, W} fields to tgsi_declaration_semantic
Nicolai Hähnle
nicolai.haehnle at amd.com
Wed Nov 30 19:19:11 UTC 2016
On 30.11.2016 19:06, Roland Scheidegger wrote:
> Am 30.11.2016 um 14:35 schrieb Nicolai Hähnle:
>> From: Nicolai Hähnle <nicolai.haehnle at 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...
There are two variants of that question, I guess.
The answer to the first variant is: Yes, this is currently true.
lower_packed_varyings will happily pack outputs from different vertex
streams into the same vec4. This affects quite a lot of programs, e.g.
you see it in piglit arb_gpu_shader5-xfb-streams.
The second question is: Do we want it to be true? I agree that it would
be convenient to be able to use a single Stream member. Also, isolating
the stream0 components from the rest would lead to slightly more
efficient shaders for us in some cases.
I opted against it so far because I didn't want to think through the
implications of changing lower_packed_varyings. The main question I have
is: if you account for the size of the GS output in # of components,
then it could happen that the number of output vec4s ends up being
larger than (max # of output components) / 4. Will that be a problem
somewhere?
Nicolai
>
> 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;
>> };
>>
>>
>
More information about the mesa-dev
mailing list