diff options
author | Dave Airlie <airlied@redhat.com> | 2015-12-19 17:46:41 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-12-22 08:49:33 +1000 |
commit | 97876080918a92f968bba04a9e36e9c1c5536e7f (patch) | |
tree | 7d28b5b1e85ca39ef6f8de557c3e185e5e3f423c | |
parent | e9d3c0c27aa802166b75634079e47920784f9b26 (diff) |
gallium/tgsi: update with some newer gallium pieces
This updates the tgsi code from mesa, it introduces
changes necessary to deal with tessellation and doubles.
It also drops an unused saturate feature, which we didn't
use anyways.
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_build.c | 4 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_dump.c | 64 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_dump.h | 7 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_info.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_scan.c | 185 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_scan.h | 34 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_strings.c | 43 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_strings.h | 4 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_text.c | 69 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_memory.h | 4 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_defines.h | 38 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_shader_tokens.h | 67 | ||||
-rw-r--r-- | src/vrend_shader.c | 2 |
13 files changed, 418 insertions, 105 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index 39a4296..fdb7feb 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -610,7 +610,7 @@ tgsi_default_instruction( void ) instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION; instruction.NrTokens = 0; instruction.Opcode = TGSI_OPCODE_MOV; - instruction.Saturate = TGSI_SAT_NONE; + instruction.Saturate = 0; instruction.Predicate = 0; instruction.NumDstRegs = 1; instruction.NumSrcRegs = 1; @@ -632,7 +632,7 @@ tgsi_build_instruction(unsigned opcode, struct tgsi_instruction instruction; assert (opcode <= TGSI_OPCODE_LAST); - assert (saturate <= TGSI_SAT_MINUS_PLUS_ONE); + assert (saturate <= 1); assert (num_dst_regs <= 3); assert (num_src_regs <= 15); diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index 4147db3..e29ffb3 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -51,6 +51,7 @@ struct dump_ctx int indent; uint indentation; + FILE *file; void (*dump_printf)(struct dump_ctx *ctx, const char *format, ...); }; @@ -61,7 +62,10 @@ dump_ctx_printf(struct dump_ctx *ctx, const char *format, ...) va_list ap; (void)ctx; va_start(ap, format); - _debug_vprintf(format, ap); + if (ctx->file) + vfprintf(ctx->file, format, ap); + else + _debug_vprintf(format, ap); va_end(ap); } @@ -86,6 +90,7 @@ dump_enum( #define INSTID(I) ctx->dump_printf( ctx, "% 3u", I ) #define SID(I) ctx->dump_printf( ctx, "%d", I ) #define FLT(F) ctx->dump_printf( ctx, "%10.4f", F ) +#define DBL(D) ctx->dump_printf( ctx, "%10.8f", D ) #define HFLT(F) ctx->dump_printf( ctx, "0x%08x", fui((F)) ) #define ENM(E,ENUMS) dump_enum( ctx, E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) @@ -242,6 +247,13 @@ dump_imm_data(struct tgsi_iterate_context *iter, assert( num_tokens <= 4 ); for (i = 0; i < num_tokens; i++) { switch (data_type) { + case TGSI_IMM_FLOAT64: { + union di d; + d.ui = data[i].Uint | (uint64_t)data[i+1].Uint << 32; + DBL( d.d ); + i++; + break; + } case TGSI_IMM_FLOAT32: if (ctx->dump_float_as_hex) HFLT( data[i].Float ); @@ -270,14 +282,30 @@ iter_declaration( struct tgsi_full_declaration *decl ) { struct dump_ctx *ctx = (struct dump_ctx *)iter; + boolean patch = decl->Semantic.Name == TGSI_SEMANTIC_PATCH || + decl->Semantic.Name == TGSI_SEMANTIC_TESSINNER || + decl->Semantic.Name == TGSI_SEMANTIC_TESSOUTER || + decl->Semantic.Name == TGSI_SEMANTIC_PRIMID; TXT( "DCL " ); TXT(tgsi_file_name(decl->Declaration.File)); - /* all geometry shader inputs are two dimensional */ + /* all geometry shader inputs and non-patch tessellation shader inputs are + * two dimensional + */ if (decl->Declaration.File == TGSI_FILE_INPUT && - iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) { + (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY || + (!patch && + (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL || + iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL)))) { + TXT("[]"); + } + + /* all non-patch tess ctrl shader outputs are two dimensional */ + if (decl->Declaration.File == TGSI_FILE_OUTPUT && + !patch && + iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL) { TXT("[]"); } @@ -522,17 +550,8 @@ iter_instruction( TXT( info->mnemonic ); - switch (inst->Instruction.Saturate) { - case TGSI_SAT_NONE: - break; - case TGSI_SAT_ZERO_ONE: + if (inst->Instruction.Saturate) { TXT( "_SAT" ); - break; - case TGSI_SAT_MINUS_PLUS_ONE: - TXT( "_SATNV" ); - break; - default: - assert( 0 ); } for (i = 0; i < inst->Instruction.NumDstRegs; i++) { @@ -605,6 +624,7 @@ iter_instruction( case TGSI_OPCODE_BGNLOOP: case TGSI_OPCODE_ENDLOOP: case TGSI_OPCODE_CAL: + case TGSI_OPCODE_BGNSUB: TXT( " :" ); UID( inst->Label.Label ); break; @@ -635,6 +655,7 @@ tgsi_dump_instruction( ctx.indent = 0; ctx.dump_printf = dump_ctx_printf; ctx.indentation = 0; + ctx.file = NULL; iter_instruction( &ctx.iter, (struct tgsi_full_instruction *)inst ); } @@ -650,9 +671,7 @@ prolog( } void -tgsi_dump( - const struct tgsi_token *tokens, - uint flags ) +tgsi_dump_to_file(const struct tgsi_token *tokens, uint flags, FILE *file) { struct dump_ctx ctx; @@ -668,6 +687,7 @@ tgsi_dump( ctx.indent = 0; ctx.dump_printf = dump_ctx_printf; ctx.indentation = 0; + ctx.file = file; if (flags & TGSI_DUMP_FLOAT_AS_HEX) ctx.dump_float_as_hex = TRUE; @@ -677,6 +697,12 @@ tgsi_dump( tgsi_iterate_shader( tokens, &ctx.iter ); } +void +tgsi_dump(const struct tgsi_token *tokens, uint flags) +{ + tgsi_dump_to_file(tokens, flags, NULL); +} + struct str_dump_ctx { struct dump_ctx base; @@ -710,7 +736,7 @@ str_dump_ctx_printf(struct dump_ctx *ctx, const char *format, ...) sctx->nospace = true; } -int +bool tgsi_dump_str( const struct tgsi_token *tokens, uint flags, @@ -731,6 +757,7 @@ tgsi_dump_str( ctx.base.indent = 0; ctx.base.dump_printf = &str_dump_ctx_printf; ctx.base.indentation = 0; + ctx.base.file = NULL; ctx.str = str; ctx.str[0] = 0; @@ -745,7 +772,7 @@ tgsi_dump_str( tgsi_iterate_shader( tokens, &ctx.base.iter ); - return (ctx.nospace == true) ? -1 : 0; + return !ctx.nospace; } void @@ -762,6 +789,7 @@ tgsi_dump_instruction_str( ctx.base.indent = 0; ctx.base.dump_printf = &str_dump_ctx_printf; ctx.base.indentation = 0; + ctx.base.file = NULL; ctx.str = str; ctx.str[0] = 0; diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.h b/src/gallium/auxiliary/tgsi/tgsi_dump.h index db85e1b..c3722d3 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.h +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.h @@ -32,13 +32,15 @@ #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" +#include <stdio.h> + #if defined __cplusplus extern "C" { #endif #define TGSI_DUMP_FLOAT_AS_HEX (1 << 0) -int +bool tgsi_dump_str( const struct tgsi_token *tokens, uint flags, @@ -46,6 +48,9 @@ tgsi_dump_str( size_t size); void +tgsi_dump_to_file(const struct tgsi_token *tokens, uint flags, FILE *file); + +void tgsi_dump( const struct tgsi_token *tokens, uint flags ); diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c index e4d6881..0f9466f 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_info.c +++ b/src/gallium/auxiliary/tgsi/tgsi_info.c @@ -335,6 +335,8 @@ tgsi_opcode_infer_type( uint opcode ) case TGSI_OPCODE_IABS: case TGSI_OPCODE_ISSG: case TGSI_OPCODE_IMUL_HI: + case TGSI_OPCODE_IBFE: + case TGSI_OPCODE_IMSB: return TGSI_TYPE_SIGNED; default: return TGSI_TYPE_FLOAT; diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c index 3d8f000..e04f407 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c @@ -56,12 +56,14 @@ tgsi_scan_shader(const struct tgsi_token *tokens, { uint procType, i; struct tgsi_parse_context parse; + unsigned current_depth = 0; memset(info, 0, sizeof(*info)); for (i = 0; i < TGSI_FILE_COUNT; i++) info->file_max[i] = -1; - for (i = 0; i < ARRAY_SIZE(info->const_file_max); i++) + for (i = 0; i < Elements(info->const_file_max); i++) info->const_file_max[i] = -1; + info->properties[TGSI_PROPERTY_GS_INVOCATIONS] = 1; /** ** Setup to begin parsing input shader @@ -74,6 +76,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens, assert(procType == TGSI_PROCESSOR_FRAGMENT || procType == TGSI_PROCESSOR_VERTEX || procType == TGSI_PROCESSOR_GEOMETRY || + procType == TGSI_PROCESSOR_TESS_CTRL || + procType == TGSI_PROCESSOR_TESS_EVAL || procType == TGSI_PROCESSOR_COMPUTE); info->processor = procType; @@ -97,6 +101,72 @@ tgsi_scan_shader(const struct tgsi_token *tokens, assert(fullinst->Instruction.Opcode < TGSI_OPCODE_LAST); info->opcode_count[fullinst->Instruction.Opcode]++; + switch (fullinst->Instruction.Opcode) { + case TGSI_OPCODE_IF: + case TGSI_OPCODE_UIF: + case TGSI_OPCODE_BGNLOOP: + current_depth++; + info->max_depth = MAX2(info->max_depth, current_depth); + break; + case TGSI_OPCODE_ENDIF: + case TGSI_OPCODE_ENDLOOP: + current_depth--; + break; + default: + break; + } + + if (fullinst->Instruction.Opcode == TGSI_OPCODE_INTERP_CENTROID || + fullinst->Instruction.Opcode == TGSI_OPCODE_INTERP_OFFSET || + fullinst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE) { + const struct tgsi_full_src_register *src0 = &fullinst->Src[0]; + unsigned input; + + if (src0->Register.Indirect && src0->Indirect.ArrayID) + input = info->input_array_first[src0->Indirect.ArrayID]; + else + input = src0->Register.Index; + + /* For the INTERP opcodes, the interpolation is always + * PERSPECTIVE unless LINEAR is specified. + */ + switch (info->input_interpolate[input]) { + case TGSI_INTERPOLATE_COLOR: + case TGSI_INTERPOLATE_CONSTANT: + case TGSI_INTERPOLATE_PERSPECTIVE: + switch (fullinst->Instruction.Opcode) { + case TGSI_OPCODE_INTERP_CENTROID: + info->uses_persp_opcode_interp_centroid = true; + break; + case TGSI_OPCODE_INTERP_OFFSET: + info->uses_persp_opcode_interp_offset = true; + break; + case TGSI_OPCODE_INTERP_SAMPLE: + info->uses_persp_opcode_interp_sample = true; + break; + } + break; + + case TGSI_INTERPOLATE_LINEAR: + switch (fullinst->Instruction.Opcode) { + case TGSI_OPCODE_INTERP_CENTROID: + info->uses_linear_opcode_interp_centroid = true; + break; + case TGSI_OPCODE_INTERP_OFFSET: + info->uses_linear_opcode_interp_offset = true; + break; + case TGSI_OPCODE_INTERP_SAMPLE: + info->uses_linear_opcode_interp_sample = true; + break; + } + break; + } + } + + if (fullinst->Instruction.Opcode >= TGSI_OPCODE_F2D && + fullinst->Instruction.Opcode <= TGSI_OPCODE_DSSG) + info->uses_doubles = true; + for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) { const struct tgsi_full_src_register *src = &fullinst->Src[i]; @@ -136,7 +206,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens, /* MSAA samplers */ if (src->Register.File == TGSI_FILE_SAMPLER) { assert(fullinst->Instruction.Texture); - assert(src->Register.Index < ARRAY_SIZE(info->is_msaa_sampler)); + assert(src->Register.Index < Elements(info->is_msaa_sampler)); if (fullinst->Instruction.Texture && (fullinst->Texture.Texture == TGSI_TEXTURE_2D_MSAA || @@ -165,13 +235,31 @@ tgsi_scan_shader(const struct tgsi_token *tokens, = &parse.FullToken.FullDeclaration; const uint file = fulldecl->Declaration.File; uint reg; - if (fulldecl->Declaration.Array) - info->array_max[file] = MAX2(info->array_max[file], fulldecl->Array.ArrayID); + + if (fulldecl->Declaration.Array) { + unsigned array_id = fulldecl->Array.ArrayID; + + switch (file) { + case TGSI_FILE_INPUT: + assert(array_id < ARRAY_SIZE(info->input_array_first)); + info->input_array_first[array_id] = fulldecl->Range.First; + info->input_array_last[array_id] = fulldecl->Range.Last; + break; + case TGSI_FILE_OUTPUT: + assert(array_id < ARRAY_SIZE(info->output_array_first)); + info->output_array_first[array_id] = fulldecl->Range.First; + info->output_array_last[array_id] = fulldecl->Range.Last; + break; + } + info->array_max[file] = MAX2(info->array_max[file], array_id); + } + for (reg = fulldecl->Range.First; reg <= fulldecl->Range.Last; reg++) { unsigned semName = fulldecl->Semantic.Name; - unsigned semIndex = fulldecl->Semantic.Index; + unsigned semIndex = + fulldecl->Semantic.Index + (reg - fulldecl->Range.First); /* only first 32 regs will appear in this bitfield */ info->file_mask[file] |= (1 << reg); @@ -195,8 +283,48 @@ tgsi_scan_shader(const struct tgsi_token *tokens, info->input_cylindrical_wrap[reg] = (ubyte)fulldecl->Interp.CylindricalWrap; info->num_inputs++; - if (fulldecl->Interp.Location == TGSI_INTERPOLATE_LOC_CENTROID) - info->uses_centroid = TRUE; + /* Only interpolated varyings. Don't include POSITION. + * Don't include integer varyings, because they are not + * interpolated. + */ + if (semName == TGSI_SEMANTIC_GENERIC || + semName == TGSI_SEMANTIC_TEXCOORD || + semName == TGSI_SEMANTIC_COLOR || + semName == TGSI_SEMANTIC_BCOLOR || + semName == TGSI_SEMANTIC_FOG || + semName == TGSI_SEMANTIC_CLIPDIST || + semName == TGSI_SEMANTIC_CULLDIST) { + switch (fulldecl->Interp.Interpolate) { + case TGSI_INTERPOLATE_COLOR: + case TGSI_INTERPOLATE_PERSPECTIVE: + switch (fulldecl->Interp.Location) { + case TGSI_INTERPOLATE_LOC_CENTER: + info->uses_persp_center = true; + break; + case TGSI_INTERPOLATE_LOC_CENTROID: + info->uses_persp_centroid = true; + break; + case TGSI_INTERPOLATE_LOC_SAMPLE: + info->uses_persp_sample = true; + break; + } + break; + case TGSI_INTERPOLATE_LINEAR: + switch (fulldecl->Interp.Location) { + case TGSI_INTERPOLATE_LOC_CENTER: + info->uses_linear_center = true; + break; + case TGSI_INTERPOLATE_LOC_CENTROID: + info->uses_linear_centroid = true; + break; + case TGSI_INTERPOLATE_LOC_SAMPLE: + info->uses_linear_sample = true; + break; + } + break; + /* TGSI_INTERPOLATE_CONSTANT doesn't do any interpolation. */ + } + } if (semName == TGSI_SEMANTIC_PRIMID) info->uses_primid = TRUE; @@ -228,6 +356,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens, } else if (semName == TGSI_SEMANTIC_PRIMID) { info->uses_primid = TRUE; + } else if (semName == TGSI_SEMANTIC_INVOCATIONID) { + info->uses_invocationid = TRUE; } } else if (file == TGSI_FILE_OUTPUT) { @@ -235,21 +365,14 @@ tgsi_scan_shader(const struct tgsi_token *tokens, info->output_semantic_index[reg] = (ubyte) semIndex; info->num_outputs++; + if (semName == TGSI_SEMANTIC_COLOR) + info->colors_written |= 1 << semIndex; + if (procType == TGSI_PROCESSOR_VERTEX || - procType == TGSI_PROCESSOR_GEOMETRY) { - if (semName == TGSI_SEMANTIC_CLIPDIST) { - info->num_written_clipdistance += - util_bitcount(fulldecl->Declaration.UsageMask); - info->clipdist_writemask |= - fulldecl->Declaration.UsageMask << (semIndex*4); - } - else if (semName == TGSI_SEMANTIC_CULLDIST) { - info->num_written_culldistance += - util_bitcount(fulldecl->Declaration.UsageMask); - info->culldist_writemask |= - fulldecl->Declaration.UsageMask << (semIndex*4); - } - else if (semName == TGSI_SEMANTIC_VIEWPORT_INDEX) { + procType == TGSI_PROCESSOR_GEOMETRY || + procType == TGSI_PROCESSOR_TESS_CTRL || + procType == TGSI_PROCESSOR_TESS_EVAL) { + if (semName == TGSI_SEMANTIC_VIEWPORT_INDEX) { info->writes_viewport_index = TRUE; } else if (semName == TGSI_SEMANTIC_LAYER) { @@ -277,6 +400,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens, info->writes_edgeflag = TRUE; } } + } else if (file == TGSI_FILE_SAMPLER) { + info->samplers_declared |= 1 << reg; } } } @@ -298,9 +423,21 @@ tgsi_scan_shader(const struct tgsi_token *tokens, const struct tgsi_full_property *fullprop = &parse.FullToken.FullProperty; unsigned name = fullprop->Property.PropertyName; - - assert(name < ARRAY_SIZE(info->properties)); - info->properties[name] = fullprop->u[0].Data; + unsigned value = fullprop->u[0].Data; + + assert(name < Elements(info->properties)); + info->properties[name] = value; + + switch (name) { + case TGSI_PROPERTY_NUM_CLIPDIST_ENABLED: + info->num_written_clipdistance = value; + info->clipdist_writemask |= (1 << value) - 1; + break; + case TGSI_PROPERTY_NUM_CULLDIST_ENABLED: + info->num_written_culldistance = value; + info->culldist_writemask |= (1 << value) - 1; + break; + } } break; diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h b/src/gallium/auxiliary/tgsi/tgsi_scan.h index 5dc9267..7e9a559 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_scan.h +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h @@ -33,6 +33,10 @@ #include "pipe/p_state.h" #include "pipe/p_shader_tokens.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * Shader summary info */ @@ -60,7 +64,12 @@ struct tgsi_shader_info uint file_count[TGSI_FILE_COUNT]; /**< number of declared registers */ int file_max[TGSI_FILE_COUNT]; /**< highest index of declared registers */ int const_file_max[PIPE_MAX_CONSTANT_BUFFERS]; + unsigned samplers_declared; /**< bitmask of declared samplers */ + ubyte input_array_first[PIPE_MAX_SHADER_INPUTS]; + ubyte input_array_last[PIPE_MAX_SHADER_INPUTS]; + ubyte output_array_first[PIPE_MAX_SHADER_OUTPUTS]; + ubyte output_array_last[PIPE_MAX_SHADER_OUTPUTS]; unsigned array_max[TGSI_FILE_COUNT]; /**< highest index array per register file */ uint immediate_count; /**< number of immediates declared */ @@ -68,25 +77,38 @@ struct tgsi_shader_info uint opcode_count[TGSI_OPCODE_LAST]; /**< opcode histogram */ + ubyte colors_written; boolean reads_position; /**< does fragment shader read position? */ boolean reads_z; /**< does fragment shader read depth? */ boolean writes_z; /**< does fragment shader write Z value? */ boolean writes_stencil; /**< does fragment shader write stencil value? */ boolean writes_edgeflag; /**< vertex shader outputs edgeflag */ boolean uses_kill; /**< KILL or KILL_IF instruction used? */ - boolean uses_centroid; + boolean uses_persp_center; + boolean uses_persp_centroid; + boolean uses_persp_sample; + boolean uses_linear_center; + boolean uses_linear_centroid; + boolean uses_linear_sample; + boolean uses_persp_opcode_interp_centroid; + boolean uses_persp_opcode_interp_offset; + boolean uses_persp_opcode_interp_sample; + boolean uses_linear_opcode_interp_centroid; + boolean uses_linear_opcode_interp_offset; + boolean uses_linear_opcode_interp_sample; boolean uses_instanceid; boolean uses_vertexid; boolean uses_vertexid_nobase; boolean uses_basevertex; boolean uses_primid; boolean uses_frontface; + boolean uses_invocationid; boolean writes_psize; boolean writes_clipvertex; boolean writes_viewport_index; boolean writes_layer; boolean is_msaa_sampler[PIPE_MAX_SAMPLERS]; - + boolean uses_doubles; /**< uses any of the double instructions */ unsigned clipdist_writemask; unsigned culldist_writemask; unsigned num_written_culldistance; @@ -104,6 +126,11 @@ struct tgsi_shader_info unsigned indirect_files_written; unsigned properties[TGSI_PROPERTY_COUNT]; /* index with TGSI_PROPERTY_ */ + + /** + * Max nesting limit of loops/if's + */ + unsigned max_depth; }; extern void @@ -114,5 +141,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens, extern boolean tgsi_is_passthrough_shader(const struct tgsi_token *tokens); +#ifdef __cplusplus +} // extern "C" +#endif #endif /* TGSI_SCAN_H */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.c b/src/gallium/auxiliary/tgsi/tgsi_strings.c index 2cdf945..fc29a23 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_strings.c +++ b/src/gallium/auxiliary/tgsi/tgsi_strings.c @@ -32,11 +32,13 @@ #include "tgsi_strings.h" -const char *tgsi_processor_type_names[4] = +const char *tgsi_processor_type_names[6] = { "FRAG", "VERT", "GEOM", + "TESS_CTRL", + "TESS_EVAL", "COMP" }; @@ -88,6 +90,12 @@ const char *tgsi_semantic_names[TGSI_SEMANTIC_COUNT] = "INVOCATIONID", "VERTEXID_NOBASE", "BASEVERTEX", + "PATCH", + "TESSCOORD", + "TESSOUTER", + "TESSINNER", + "VERTICESIN", + "HELPER_INVOCATION", }; const char *tgsi_texture_names[TGSI_TEXTURE_COUNT] = @@ -124,7 +132,14 @@ const char *tgsi_property_names[TGSI_PROPERTY_COUNT] = "FS_DEPTH_LAYOUT", "VS_PROHIBIT_UCPS", "GS_INVOCATIONS", - "VS_WINDOW_SPACE_POSITION" + "VS_WINDOW_SPACE_POSITION", + "TCS_VERTICES_OUT", + "TES_PRIM_MODE", + "TES_SPACING", + "TES_VERTEX_ORDER_CW", + "TES_POINT_MODE", + "NUM_CLIPDIST_ENABLED", + "NUM_CULLDIST_ENABLED", }; const char *tgsi_return_type_names[TGSI_RETURN_TYPE_COUNT] = @@ -166,7 +181,8 @@ const char *tgsi_primitive_names[PIPE_PRIM_MAX] = "LINES_ADJACENCY", "LINE_STRIP_ADJACENCY", "TRIANGLES_ADJACENCY", - "TRIANGLE_STRIP_ADJACENCY" + "TRIANGLE_STRIP_ADJACENCY", + "PATCHES", }; const char *tgsi_fs_coord_origin_names[2] = @@ -181,23 +197,24 @@ const char *tgsi_fs_coord_pixel_center_names[2] = "INTEGER" }; -const char *tgsi_immediate_type_names[3] = +const char *tgsi_immediate_type_names[4] = { "FLT32", "UINT32", - "INT32" + "INT32", + "FLT64" }; static inline void tgsi_strings_check(void) { - STATIC_ASSERT(ARRAY_SIZE(tgsi_semantic_names) == TGSI_SEMANTIC_COUNT); - STATIC_ASSERT(ARRAY_SIZE(tgsi_texture_names) == TGSI_TEXTURE_COUNT); - STATIC_ASSERT(ARRAY_SIZE(tgsi_property_names) == TGSI_PROPERTY_COUNT); - STATIC_ASSERT(ARRAY_SIZE(tgsi_primitive_names) == PIPE_PRIM_MAX); - STATIC_ASSERT(ARRAY_SIZE(tgsi_interpolate_names) == TGSI_INTERPOLATE_COUNT); - STATIC_ASSERT(ARRAY_SIZE(tgsi_return_type_names) == TGSI_RETURN_TYPE_COUNT); + STATIC_ASSERT(Elements(tgsi_semantic_names) == TGSI_SEMANTIC_COUNT); + STATIC_ASSERT(Elements(tgsi_texture_names) == TGSI_TEXTURE_COUNT); + STATIC_ASSERT(Elements(tgsi_property_names) == TGSI_PROPERTY_COUNT); + STATIC_ASSERT(Elements(tgsi_primitive_names) == PIPE_PRIM_MAX); + STATIC_ASSERT(Elements(tgsi_interpolate_names) == TGSI_INTERPOLATE_COUNT); + STATIC_ASSERT(Elements(tgsi_return_type_names) == TGSI_RETURN_TYPE_COUNT); (void) tgsi_processor_type_names; (void) tgsi_return_type_names; (void) tgsi_immediate_type_names; @@ -209,8 +226,8 @@ tgsi_strings_check(void) const char * tgsi_file_name(unsigned file) { - STATIC_ASSERT(ARRAY_SIZE(tgsi_file_names) == TGSI_FILE_COUNT); - if (file < ARRAY_SIZE(tgsi_file_names)) + STATIC_ASSERT(Elements(tgsi_file_names) == TGSI_FILE_COUNT); + if (file < Elements(tgsi_file_names)) return tgsi_file_names[file]; else return "invalid file"; diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.h b/src/gallium/auxiliary/tgsi/tgsi_strings.h index c842746..71e7437 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_strings.h +++ b/src/gallium/auxiliary/tgsi/tgsi_strings.h @@ -38,7 +38,7 @@ extern "C" { #endif -extern const char *tgsi_processor_type_names[4]; +extern const char *tgsi_processor_type_names[6]; extern const char *tgsi_semantic_names[TGSI_SEMANTIC_COUNT]; @@ -58,7 +58,7 @@ extern const char *tgsi_fs_coord_origin_names[2]; extern const char *tgsi_fs_coord_pixel_center_names[2]; -extern const char *tgsi_immediate_type_names[3]; +extern const char *tgsi_immediate_type_names[4]; const char * diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index ba54321..4a82c9b 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -241,6 +241,24 @@ out: return TRUE; } +static boolean parse_double( const char **pcur, uint32_t *val0, uint32_t *val1) +{ + const char *cur = *pcur; + union { + double dval; + uint32_t uval[2]; + } v; + + v.dval = strtod(cur, (char**)pcur); + if (*pcur == cur) + return FALSE; + + *val0 = v.uval[0]; + *val1 = v.uval[1]; + + return TRUE; +} + struct translate_ctx { const char *text; @@ -250,7 +268,7 @@ struct translate_ctx struct tgsi_token *tokens_end; struct tgsi_header *header; unsigned processor : 4; - int implied_array_size : 5; + unsigned implied_array_size : 6; unsigned num_immediates; }; @@ -288,6 +306,10 @@ static boolean parse_header( struct translate_ctx *ctx ) processor = TGSI_PROCESSOR_VERTEX; else if (str_match_nocase_whole( &ctx->cur, "GEOM" )) processor = TGSI_PROCESSOR_GEOMETRY; + else if (str_match_nocase_whole( &ctx->cur, "TESS_CTRL" )) + processor = TGSI_PROCESSOR_TESS_CTRL; + else if (str_match_nocase_whole( &ctx->cur, "TESS_EVAL" )) + processor = TGSI_PROCESSOR_TESS_EVAL; else if (str_match_nocase_whole( &ctx->cur, "COMP" )) processor = TGSI_PROCESSOR_COMPUTE; else { @@ -662,6 +684,9 @@ parse_register_dcl( eat_opt_white( &cur ); if (cur[0] == '[') { + bool is_in = *file == TGSI_FILE_INPUT; + bool is_out = *file == TGSI_FILE_OUTPUT; + ++cur; ctx->cur = cur; if (!parse_register_dcl_bracket( ctx, &brackets[1] )) @@ -671,7 +696,11 @@ parse_register_dcl( * input primitive. so we want to declare just * the index relevant to the semantics which is in * the second bracket */ - if (ctx->processor == TGSI_PROCESSOR_GEOMETRY && *file == TGSI_FILE_INPUT) { + + /* tessellation has similar constraints to geometry shader */ + if ((ctx->processor == TGSI_PROCESSOR_GEOMETRY && is_in) || + (ctx->processor == TGSI_PROCESSOR_TESS_EVAL && is_in) || + (ctx->processor == TGSI_PROCESSOR_TESS_CTRL && (is_in || is_out))) { brackets[0] = brackets[1]; *num_brackets = 1; } else { @@ -727,6 +756,14 @@ parse_dst_operand( dst->Dimension.Indirect = 0; dst->Dimension.Dimension = 0; dst->Dimension.Index = bracket[0].index; + + if (bracket[0].ind_file != TGSI_FILE_NULL) { + dst->Dimension.Indirect = 1; + dst->DimIndirect.File = bracket[0].ind_file; + dst->DimIndirect.Index = bracket[0].ind_index; + dst->DimIndirect.Swizzle = bracket[0].ind_comp; + dst->DimIndirect.ArrayID = bracket[0].ind_array; + } bracket[0] = bracket[1]; } dst->Register.Index = bracket[0].index; @@ -894,7 +931,7 @@ match_inst(const char **pcur, /* simple case: the whole string matches the instruction name */ if (str_match_nocase_whole(&cur, info->mnemonic)) { *pcur = cur; - *saturate = TGSI_SAT_NONE; + *saturate = 0; return TRUE; } @@ -902,13 +939,7 @@ match_inst(const char **pcur, /* the instruction has a suffix, figure it out */ if (str_match_nocase_whole(&cur, "_SAT")) { *pcur = cur; - *saturate = TGSI_SAT_ZERO_ONE; - return TRUE; - } - - if (str_match_nocase_whole(&cur, "_SATNV")) { - *pcur = cur; - *saturate = TGSI_SAT_MINUS_PLUS_ONE; + *saturate = 1; return TRUE; } } @@ -922,7 +953,7 @@ parse_instruction( boolean has_label ) { uint i; - uint saturate = TGSI_SAT_NONE; + uint saturate = 0; const struct tgsi_opcode_info *info; struct tgsi_full_instruction inst; const char *cur; @@ -1113,6 +1144,10 @@ static boolean parse_immediate_data(struct translate_ctx *ctx, unsigned type, } switch (type) { + case TGSI_IMM_FLOAT64: + ret = parse_double(&ctx->cur, &values[i].Uint, &values[i+1].Uint); + i++; + break; case TGSI_IMM_FLOAT32: ret = parse_float(&ctx->cur, &values[i].Float); break; @@ -1448,11 +1483,11 @@ static boolean parse_immediate( struct translate_ctx *ctx ) report_error( ctx, "Syntax error" ); return FALSE; } - for (type = 0; type < ARRAY_SIZE(tgsi_immediate_type_names); ++type) { + for (type = 0; type < Elements(tgsi_immediate_type_names); ++type) { if (str_match_nocase_whole(&ctx->cur, tgsi_immediate_type_names[type])) break; } - if (type == ARRAY_SIZE(tgsi_immediate_type_names)) { + if (type == Elements(tgsi_immediate_type_names)) { report_error( ctx, "Expected immediate type" ); return FALSE; } @@ -1498,7 +1533,7 @@ parse_fs_coord_origin( const char **pcur, uint *fs_coord_origin ) { uint i; - for (i = 0; i < ARRAY_SIZE(tgsi_fs_coord_origin_names); i++) { + for (i = 0; i < Elements(tgsi_fs_coord_origin_names); i++) { const char *cur = *pcur; if (str_match_nocase_whole( &cur, tgsi_fs_coord_origin_names[i])) { @@ -1515,7 +1550,7 @@ parse_fs_coord_pixel_center( const char **pcur, uint *fs_coord_pixel_center ) { uint i; - for (i = 0; i < ARRAY_SIZE(tgsi_fs_coord_pixel_center_names); i++) { + for (i = 0; i < Elements(tgsi_fs_coord_pixel_center_names); i++) { const char *cur = *pcur; if (str_match_nocase_whole( &cur, tgsi_fs_coord_pixel_center_names[i])) { @@ -1612,6 +1647,10 @@ static boolean translate( struct translate_ctx *ctx ) if (!parse_header( ctx )) return FALSE; + if (ctx->processor == TGSI_PROCESSOR_TESS_CTRL || + ctx->processor == TGSI_PROCESSOR_TESS_EVAL) + ctx->implied_array_size = 32; + while (*ctx->cur != '\0') { uint label_val = 0; if (!eat_white( &ctx->cur )) { diff --git a/src/gallium/auxiliary/util/u_memory.h b/src/gallium/auxiliary/util/u_memory.h index 9835821..d53575e 100644 --- a/src/gallium/auxiliary/util/u_memory.h +++ b/src/gallium/auxiliary/util/u_memory.h @@ -84,6 +84,10 @@ mem_dup(const void *src, uint size) #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) #endif +#ifndef Elements +#define Elements(x) (sizeof(x)/sizeof((x)[0])) +#endif + /** * Offset of a field in a struct, in bytes. diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index fd32c4a..ed5eef1 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -398,31 +398,41 @@ enum pipe_flush_flags { #define PIPE_SHADER_VERTEX 0 #define PIPE_SHADER_FRAGMENT 1 #define PIPE_SHADER_GEOMETRY 2 -#define PIPE_SHADER_COMPUTE 3 -#define PIPE_SHADER_TYPES 4 +#define PIPE_SHADER_TESS_CTRL 3 +#define PIPE_SHADER_TESS_EVAL 4 +#define PIPE_SHADER_COMPUTE 5 +#define PIPE_SHADER_TYPES 6 /** * Primitive types: */ -#define PIPE_PRIM_POINTS 0 -#define PIPE_PRIM_LINES 1 -#define PIPE_PRIM_LINE_LOOP 2 -#define PIPE_PRIM_LINE_STRIP 3 -#define PIPE_PRIM_TRIANGLES 4 -#define PIPE_PRIM_TRIANGLE_STRIP 5 -#define PIPE_PRIM_TRIANGLE_FAN 6 -#define PIPE_PRIM_QUADS 7 -#define PIPE_PRIM_QUAD_STRIP 8 -#define PIPE_PRIM_POLYGON 9 +#define PIPE_PRIM_POINTS 0 +#define PIPE_PRIM_LINES 1 +#define PIPE_PRIM_LINE_LOOP 2 +#define PIPE_PRIM_LINE_STRIP 3 +#define PIPE_PRIM_TRIANGLES 4 +#define PIPE_PRIM_TRIANGLE_STRIP 5 +#define PIPE_PRIM_TRIANGLE_FAN 6 +#define PIPE_PRIM_QUADS 7 +#define PIPE_PRIM_QUAD_STRIP 8 +#define PIPE_PRIM_POLYGON 9 #define PIPE_PRIM_LINES_ADJACENCY 10 -#define PIPE_PRIM_LINE_STRIP_ADJACENCY 11 +#define PIPE_PRIM_LINE_STRIP_ADJACENCY 11 #define PIPE_PRIM_TRIANGLES_ADJACENCY 12 #define PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY 13 -#define PIPE_PRIM_MAX 14 +#define PIPE_PRIM_PATCHES 14 +#define PIPE_PRIM_MAX 15 /** + * Tessellator spacing types + */ +#define PIPE_TESS_SPACING_FRACTIONAL_ODD 0 +#define PIPE_TESS_SPACING_FRACTIONAL_EVEN 1 +#define PIPE_TESS_SPACING_EQUAL 2 + +/** * Query object types */ #define PIPE_QUERY_OCCLUSION_COUNTER 0 diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 25c4aeb..a3137ae 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -43,7 +43,9 @@ struct tgsi_header #define TGSI_PROCESSOR_FRAGMENT 0 #define TGSI_PROCESSOR_VERTEX 1 #define TGSI_PROCESSOR_GEOMETRY 2 -#define TGSI_PROCESSOR_COMPUTE 3 +#define TGSI_PROCESSOR_TESS_CTRL 3 +#define TGSI_PROCESSOR_TESS_EVAL 4 +#define TGSI_PROCESSOR_COMPUTE 5 struct tgsi_processor { @@ -178,7 +180,13 @@ struct tgsi_declaration_interp #define TGSI_SEMANTIC_INVOCATIONID 27 #define TGSI_SEMANTIC_VERTEXID_NOBASE 28 #define TGSI_SEMANTIC_BASEVERTEX 29 -#define TGSI_SEMANTIC_COUNT 30 /**< number of semantic values */ +#define TGSI_SEMANTIC_PATCH 30 /**< generic per-patch semantic */ +#define TGSI_SEMANTIC_TESSCOORD 31 /**< coordinate being processed by tess */ +#define TGSI_SEMANTIC_TESSOUTER 32 /**< outer tessellation levels */ +#define TGSI_SEMANTIC_TESSINNER 33 /**< inner tessellation levels */ +#define TGSI_SEMANTIC_VERTICESIN 34 /**< number of input vertices */ +#define TGSI_SEMANTIC_HELPER_INVOCATION 35 /**< current invocation is helper */ +#define TGSI_SEMANTIC_COUNT 36 /**< number of semantic values */ struct tgsi_declaration_semantic { @@ -255,7 +263,14 @@ union tgsi_immediate_data #define TGSI_PROPERTY_VS_PROHIBIT_UCPS 7 #define TGSI_PROPERTY_GS_INVOCATIONS 8 #define TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION 9 -#define TGSI_PROPERTY_COUNT 10 +#define TGSI_PROPERTY_TCS_VERTICES_OUT 10 +#define TGSI_PROPERTY_TES_PRIM_MODE 11 +#define TGSI_PROPERTY_TES_SPACING 12 +#define TGSI_PROPERTY_TES_VERTEX_ORDER_CW 13 +#define TGSI_PROPERTY_TES_POINT_MODE 14 +#define TGSI_PROPERTY_NUM_CLIPDIST_ENABLED 15 +#define TGSI_PROPERTY_NUM_CULLDIST_ENABLED 16 +#define TGSI_PROPERTY_COUNT 17 struct tgsi_property { unsigned Type : 4; /**< TGSI_TOKEN_TYPE_PROPERTY */ @@ -306,7 +321,7 @@ struct tgsi_property_data { #define TGSI_OPCODE_MAD 16 #define TGSI_OPCODE_SUB 17 #define TGSI_OPCODE_LRP 18 - /* gap */ +#define TGSI_OPCODE_FMA 19 #define TGSI_OPCODE_SQRT 20 #define TGSI_OPCODE_DP2A 21 /* gap */ @@ -390,6 +405,7 @@ struct tgsi_property_data { #define TGSI_OPCODE_ENDLOOP 101 #define TGSI_OPCODE_ENDSUB 102 #define TGSI_OPCODE_TXQ_LZ 103 /* TXQ for mipmap level 0 */ +#define TGSI_OPCODE_TXQS 104 /* gap */ #define TGSI_OPCODE_NOP 107 @@ -404,7 +420,7 @@ struct tgsi_property_data { #define TGSI_OPCODE_BREAKC 115 #define TGSI_OPCODE_KILL_IF 116 /* conditional kill */ #define TGSI_OPCODE_END 117 /* aka HALT */ - /* gap */ +#define TGSI_OPCODE_DFMA 118 #define TGSI_OPCODE_F2I 119 #define TGSI_OPCODE_IDIV 120 #define TGSI_OPCODE_IMAX 121 @@ -495,11 +511,36 @@ struct tgsi_property_data { #define TGSI_OPCODE_INTERP_SAMPLE 193 #define TGSI_OPCODE_INTERP_OFFSET 194 -#define TGSI_OPCODE_LAST 195 - -#define TGSI_SAT_NONE 0 /* do not saturate */ -#define TGSI_SAT_ZERO_ONE 1 /* clamp to [0,1] */ -#define TGSI_SAT_MINUS_PLUS_ONE 2 /* clamp to [-1,1] */ +/* sm5 marked opcodes are supported in D3D11 optionally - also DMOV, DMOVC */ +#define TGSI_OPCODE_F2D 195 /* SM5 */ +#define TGSI_OPCODE_D2F 196 +#define TGSI_OPCODE_DABS 197 +#define TGSI_OPCODE_DNEG 198 /* SM5 */ +#define TGSI_OPCODE_DADD 199 /* SM5 */ +#define TGSI_OPCODE_DMUL 200 /* SM5 */ +#define TGSI_OPCODE_DMAX 201 /* SM5 */ +#define TGSI_OPCODE_DMIN 202 /* SM5 */ +#define TGSI_OPCODE_DSLT 203 /* SM5 */ +#define TGSI_OPCODE_DSGE 204 /* SM5 */ +#define TGSI_OPCODE_DSEQ 205 /* SM5 */ +#define TGSI_OPCODE_DSNE 206 /* SM5 */ +#define TGSI_OPCODE_DRCP 207 /* eg, cayman */ +#define TGSI_OPCODE_DSQRT 208 /* eg, cayman also has DRSQ */ +#define TGSI_OPCODE_DMAD 209 +#define TGSI_OPCODE_DFRAC 210 /* eg, cayman */ +#define TGSI_OPCODE_DLDEXP 211 /* eg, cayman */ +#define TGSI_OPCODE_DFRACEXP 212 /* eg, cayman */ +#define TGSI_OPCODE_D2I 213 +#define TGSI_OPCODE_I2D 214 +#define TGSI_OPCODE_D2U 215 +#define TGSI_OPCODE_U2D 216 +#define TGSI_OPCODE_DRSQ 217 /* eg, cayman also has DRSQ */ +#define TGSI_OPCODE_DTRUNC 218 /* nvc0 */ +#define TGSI_OPCODE_DCEIL 219 /* nvc0 */ +#define TGSI_OPCODE_DFLR 220 /* nvc0 */ +#define TGSI_OPCODE_DROUND 221 /* nvc0 */ +#define TGSI_OPCODE_DSSG 222 +#define TGSI_OPCODE_LAST 223 /** * Opcode is the operation code to execute. A given operation defines the @@ -520,13 +561,13 @@ struct tgsi_instruction unsigned Type : 4; /* TGSI_TOKEN_TYPE_INSTRUCTION */ unsigned NrTokens : 8; /* UINT */ unsigned Opcode : 8; /* TGSI_OPCODE_ */ - unsigned Saturate : 2; /* TGSI_SAT_ */ + unsigned Saturate : 1; /* BOOL */ unsigned NumDstRegs : 2; /* UINT */ unsigned NumSrcRegs : 4; /* UINT */ unsigned Predicate : 1; /* BOOL */ unsigned Label : 1; unsigned Texture : 1; - unsigned Padding : 1; + unsigned Padding : 2; }; /* @@ -648,7 +689,7 @@ struct tgsi_src_register * * File, Index and Swizzle are handled the same as in tgsi_src_register. * - * If ArrayID is zero the whole register file might be is indirectly addressed, + * If ArrayID is zero the whole register file might be indirectly addressed, * if not only the Declaration with this ArrayID is accessed by this operand. * */ diff --git a/src/vrend_shader.c b/src/vrend_shader.c index 5ac5287..ec93987 100644 --- a/src/vrend_shader.c +++ b/src/vrend_shader.c @@ -1839,7 +1839,7 @@ iter_instruction(struct tgsi_iterate_context *iter, break; } - if (inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE) { + if (inst->Instruction.Saturate) { snprintf(buf, 255, "%s = clamp(%s, 0.0, 1.0);\n", dsts[0], dsts[0]); EMIT_BUF_WITH_RET(ctx, buf); } |