diff options
author | Zack Rusin <[email protected]> | 2011-01-24 17:47:10 -0500 |
---|---|---|
committer | Zack Rusin <[email protected]> | 2011-01-24 17:47:10 -0500 |
commit | bdbe77f9c6f06cfaa155f27c2ade3c523d7fbea7 (patch) | |
tree | d131d945212a92fd9179bbcb1dd08db0f1c99356 /src/gallium/auxiliary | |
parent | b0669837808dee576dd05c8c335ca78264dd8e80 (diff) |
gallium: implement modern sampling scheme
largely a merge of the previously discussed origin/gallium-resource-sampling
but updated.
the idea is to allow arbitrary binding of resources, the way opencl, new gl
versions and dx10+ require, i.e.
DCL RES[0], 2D, FLOAT
LOAD DST[0], SRC[0], RES[0]
SAMPLE DST[0], SRC[0], RES[0], SAMP[0]
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_build.c | 59 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_dump.c | 32 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.c | 211 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.h | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_info.c | 15 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h | 17 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_parse.c | 4 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_parse.h | 3 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_sanity.c | 3 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_text.c | 135 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_ureg.c | 91 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_ureg.h | 69 |
12 files changed, 607 insertions, 33 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index 16a205f2068..d2cb98e84af 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -26,6 +26,7 @@ **************************************************************************/ #include "util/u_debug.h" +#include "pipe/p_format.h" #include "pipe/p_shader_tokens.h" #include "tgsi_build.h" #include "tgsi_parse.h" @@ -226,6 +227,45 @@ tgsi_build_declaration_semantic( return ds; } + +static struct tgsi_declaration_resource +tgsi_default_declaration_resource(void) +{ + struct tgsi_declaration_resource declaration_resource; + + declaration_resource.Resource = TGSI_TEXTURE_UNKNOWN; + declaration_resource.ReturnTypeX = PIPE_TYPE_UNORM; + declaration_resource.ReturnTypeY = PIPE_TYPE_UNORM; + declaration_resource.ReturnTypeZ = PIPE_TYPE_UNORM; + declaration_resource.ReturnTypeW = PIPE_TYPE_UNORM; + + return declaration_resource; +} + +static struct tgsi_declaration_resource +tgsi_build_declaration_resource(unsigned texture, + unsigned return_type_x, + unsigned return_type_y, + unsigned return_type_z, + unsigned return_type_w, + struct tgsi_declaration *declaration, + struct tgsi_header *header) +{ + struct tgsi_declaration_resource declaration_resource; + + declaration_resource = tgsi_default_declaration_resource(); + declaration_resource.Resource = texture; + declaration_resource.ReturnTypeX = return_type_x; + declaration_resource.ReturnTypeY = return_type_y; + declaration_resource.ReturnTypeZ = return_type_z; + declaration_resource.ReturnTypeW = return_type_w; + + declaration_grow(declaration, header); + + return declaration_resource; +} + + struct tgsi_full_declaration tgsi_default_full_declaration( void ) { @@ -235,6 +275,7 @@ tgsi_default_full_declaration( void ) full_declaration.Range = tgsi_default_declaration_range(); full_declaration.Semantic = tgsi_default_declaration_semantic(); full_declaration.ImmediateData.u = NULL; + full_declaration.Resource = tgsi_default_declaration_resource(); return full_declaration; } @@ -324,6 +365,24 @@ tgsi_build_full_declaration( } } + if (full_decl->Declaration.File == TGSI_FILE_RESOURCE) { + struct tgsi_declaration_resource *dr; + + if (maxsize <= size) { + return 0; + } + dr = (struct tgsi_declaration_resource *)&tokens[size]; + size++; + + *dr = tgsi_build_declaration_resource(full_decl->Resource.Resource, + full_decl->Resource.ReturnTypeX, + full_decl->Resource.ReturnTypeY, + full_decl->Resource.ReturnTypeZ, + full_decl->Resource.ReturnTypeW, + declaration, + header); + } + return size; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index 82cd8eaa969..e97698d9a0a 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -104,7 +104,8 @@ tgsi_file_names[TGSI_FILE_COUNT] = "PRED", "SV", "IMMX", - "TEMPX" + "TEMPX", + "RES" }; static const char *interpolate_names[] = @@ -170,6 +171,15 @@ const char *tgsi_property_names[TGSI_PROPERTY_COUNT] = "FS_COLOR0_WRITES_ALL_CBUFS", }; +static const char *tgsi_type_names[] = +{ + "UNORM", + "SNORM", + "SINT", + "UINT", + "FLOAT" +}; + const char *tgsi_primitive_names[PIPE_PRIM_MAX] = { "POINTS", @@ -393,6 +403,26 @@ iter_declaration( } } + if (decl->Declaration.File == TGSI_FILE_RESOURCE) { + TXT(", "); + ENM(decl->Resource.Resource, tgsi_texture_names); + TXT(", "); + if ((decl->Resource.ReturnTypeX == decl->Resource.ReturnTypeY) && + (decl->Resource.ReturnTypeX == decl->Resource.ReturnTypeZ) && + (decl->Resource.ReturnTypeX == decl->Resource.ReturnTypeW)) { + ENM(decl->Resource.ReturnTypeX, tgsi_type_names); + } else { + ENM(decl->Resource.ReturnTypeX, tgsi_type_names); + TXT(", "); + ENM(decl->Resource.ReturnTypeY, tgsi_type_names); + TXT(", "); + ENM(decl->Resource.ReturnTypeZ, tgsi_type_names); + TXT(", "); + ENM(decl->Resource.ReturnTypeW, tgsi_type_names); + } + + } + if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT && decl->Declaration.File == TGSI_FILE_INPUT) { diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 35b27423513..959d978f2eb 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1843,6 +1843,164 @@ exec_txd(struct tgsi_exec_machine *mach, } + +static void +exec_sample(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst, + uint modifier) +{ + const uint resource_unit = inst->Src[1].Register.Index; + const uint sampler_unit = inst->Src[2].Register.Index; + union tgsi_exec_channel r[4]; + const union tgsi_exec_channel *lod = &ZeroVec; + enum tgsi_sampler_control control; + uint chan; + + if (modifier != TEX_MODIFIER_NONE) { + if (modifier == TEX_MODIFIER_LOD_BIAS) + FETCH(&r[3], 3, CHAN_X); + else /*TEX_MODIFIER_LOD*/ + FETCH(&r[3], 0, CHAN_W); + + if (modifier != TEX_MODIFIER_PROJECTED) { + lod = &r[3]; + } + } + + if (modifier == TEX_MODIFIER_EXPLICIT_LOD) { + control = tgsi_sampler_lod_explicit; + } else { + control = tgsi_sampler_lod_bias; + } + + switch (mach->Resources[resource_unit].Resource) { + case TGSI_TEXTURE_1D: + case TGSI_TEXTURE_SHADOW1D: + FETCH(&r[0], 0, CHAN_X); + + if (modifier == TEX_MODIFIER_PROJECTED) { + micro_div(&r[0], &r[0], &r[3]); + } + + fetch_texel(mach->Samplers[sampler_unit], + &r[0], &ZeroVec, &ZeroVec, lod, /* S, T, P, LOD */ + control, + &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */ + break; + + case TGSI_TEXTURE_2D: + case TGSI_TEXTURE_RECT: + case TGSI_TEXTURE_SHADOW2D: + case TGSI_TEXTURE_SHADOWRECT: + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 0, CHAN_Z); + + if (modifier == TEX_MODIFIER_PROJECTED) { + micro_div(&r[0], &r[0], &r[3]); + micro_div(&r[1], &r[1], &r[3]); + micro_div(&r[2], &r[2], &r[3]); + } + + fetch_texel(mach->Samplers[sampler_unit], + &r[0], &r[1], &r[2], lod, /* S, T, P, LOD */ + control, + &r[0], &r[1], &r[2], &r[3]); /* outputs */ + break; + + case TGSI_TEXTURE_3D: + case TGSI_TEXTURE_CUBE: + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 0, CHAN_Z); + + if (modifier == TEX_MODIFIER_PROJECTED) { + micro_div(&r[0], &r[0], &r[3]); + micro_div(&r[1], &r[1], &r[3]); + micro_div(&r[2], &r[2], &r[3]); + } + + fetch_texel(mach->Samplers[sampler_unit], + &r[0], &r[1], &r[2], lod, + control, + &r[0], &r[1], &r[2], &r[3]); + break; + + default: + assert(0); + } + + for (chan = 0; chan < NUM_CHANNELS; chan++) { + if (inst->Dst[0].Register.WriteMask & (1 << chan)) { + store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT); + } + } +} + +static void +exec_sample_d(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + const uint resource_unit = inst->Src[1].Register.Index; + const uint sampler_unit = inst->Src[2].Register.Index; + union tgsi_exec_channel r[4]; + uint chan; + /* + * XXX: This is fake SAMPLE_D -- the derivatives are not taken into account, yet. + */ + + switch (mach->Resources[resource_unit].Resource) { + case TGSI_TEXTURE_1D: + case TGSI_TEXTURE_SHADOW1D: + + FETCH(&r[0], 0, CHAN_X); + + fetch_texel(mach->Samplers[sampler_unit], + &r[0], &ZeroVec, &ZeroVec, &ZeroVec, /* S, T, P, BIAS */ + tgsi_sampler_lod_bias, + &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */ + break; + + case TGSI_TEXTURE_2D: + case TGSI_TEXTURE_RECT: + case TGSI_TEXTURE_SHADOW2D: + case TGSI_TEXTURE_SHADOWRECT: + + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 0, CHAN_Z); + + fetch_texel(mach->Samplers[sampler_unit], + &r[0], &r[1], &r[2], &ZeroVec, /* inputs */ + tgsi_sampler_lod_bias, + &r[0], &r[1], &r[2], &r[3]); /* outputs */ + break; + + case TGSI_TEXTURE_3D: + case TGSI_TEXTURE_CUBE: + + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 0, CHAN_Z); + + fetch_texel(mach->Samplers[sampler_unit], + &r[0], &r[1], &r[2], &ZeroVec, + tgsi_sampler_lod_bias, + &r[0], &r[1], &r[2], &r[3]); + break; + + default: + assert(0); + } + + for (chan = 0; chan < NUM_CHANNELS; chan++) { + if (inst->Dst[0].Register.WriteMask & (1 << chan)) { + store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT); + } + } +} + + /** * Evaluate a constant-valued coefficient at the position of the * current quad. @@ -1914,6 +2072,11 @@ static void exec_declaration(struct tgsi_exec_machine *mach, const struct tgsi_full_declaration *decl) { + if (decl->Declaration.File == TGSI_FILE_RESOURCE) { + mach->Resources[decl->Range.First] = decl->Resource; + return; + } + if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) { if (decl->Declaration.File == TGSI_FILE_INPUT) { uint first, last, mask; @@ -3688,6 +3851,54 @@ exec_instruction( exec_endswitch(mach); break; + case TGSI_OPCODE_LOAD: + assert(0); + break; + + case TGSI_OPCODE_LOAD_MS: + assert(0); + break; + + case TGSI_OPCODE_SAMPLE: + exec_sample(mach, inst, TEX_MODIFIER_NONE); + break; + + case TGSI_OPCODE_SAMPLE_B: + exec_sample(mach, inst, TEX_MODIFIER_LOD_BIAS); + break; + + case TGSI_OPCODE_SAMPLE_C: + exec_sample(mach, inst, TEX_MODIFIER_NONE); + break; + + case TGSI_OPCODE_SAMPLE_C_LZ: + exec_sample(mach, inst, TEX_MODIFIER_LOD_BIAS); + break; + + case TGSI_OPCODE_SAMPLE_D: + exec_sample_d(mach, inst); + break; + + case TGSI_OPCODE_SAMPLE_L: + exec_sample(mach, inst, TEX_MODIFIER_EXPLICIT_LOD); + break; + + case TGSI_OPCODE_GATHER4: + assert(0); + break; + + case TGSI_OPCODE_RESINFO: + assert(0); + break; + + case TGSI_OPCODE_SAMPLE_POS: + assert(0); + break; + + case TGSI_OPCODE_SAMPLE_INFO: + assert(0); + break; + default: assert( 0 ); } diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index 6c204c73714..4a423b5bb4e 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -308,6 +308,7 @@ struct tgsi_exec_machine struct tgsi_full_declaration *Declarations; uint NumDeclarations; + struct tgsi_declaration_resource Resources[PIPE_MAX_SHADER_RESOURCES]; }; struct tgsi_exec_machine * diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c index e59e964ffa7..14ed56a1f6a 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_info.c +++ b/src/gallium/auxiliary/tgsi/tgsi_info.c @@ -175,7 +175,20 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] = { 0, 1, 0, 0, 0, 0, "SWITCH", TGSI_OPCODE_SWITCH }, { 0, 1, 0, 0, 0, 0, "CASE", TGSI_OPCODE_CASE }, { 0, 0, 0, 0, 0, 0, "DEFAULT", TGSI_OPCODE_DEFAULT }, - { 0, 0, 0, 0, 0, 0, "ENDSWITCH", TGSI_OPCODE_ENDSWITCH } + { 0, 0, 0, 0, 0, 0, "ENDSWITCH", TGSI_OPCODE_ENDSWITCH }, + + { 1, 2, 0, 0, 0, 0, "LOAD", TGSI_OPCODE_LOAD }, + { 1, 2, 0, 0, 0, 0, "LOAD_MS", TGSI_OPCODE_LOAD_MS }, + { 1, 3, 0, 0, 0, 0, "SAMPLE", TGSI_OPCODE_SAMPLE }, + { 1, 4, 0, 0, 0, 0, "SAMPLE_B", TGSI_OPCODE_SAMPLE_B }, + { 1, 4, 0, 0, 0, 0, "SAMPLE_C", TGSI_OPCODE_SAMPLE_C }, + { 1, 4, 0, 0, 0, 0, "SAMPLE_C_LZ", TGSI_OPCODE_SAMPLE_C_LZ }, + { 1, 5, 0, 0, 0, 0, "SAMPLE_D", TGSI_OPCODE_SAMPLE_D }, + { 1, 3, 0, 0, 0, 0, "SAMPLE_L", TGSI_OPCODE_SAMPLE_L }, + { 1, 3, 0, 0, 0, 0, "GATHER4", TGSI_OPCODE_GATHER4 }, + { 1, 2, 0, 0, 0, 0, "RESINFO", TGSI_OPCODE_RESINFO }, + { 1, 2, 0, 0, 0, 0, "SAMPLE_POS", TGSI_OPCODE_SAMPLE_POS }, + { 1, 2, 0, 0, 0, 0, "SAMPLE_INFO", TGSI_OPCODE_SAMPLE_INFO }, }; const struct tgsi_opcode_info * diff --git a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h index b3123ed016d..b5d4504425b 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h +++ b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h @@ -168,6 +168,19 @@ OP01(CASE) OP00(DEFAULT) OP00(ENDSWITCH) +OP12(LOAD) +OP12(LOAD_MS) +OP13(SAMPLE) +OP14(SAMPLE_B) +OP14(SAMPLE_C) +OP14(SAMPLE_C_LZ) +OP15(SAMPLE_D) +OP13(SAMPLE_L) +OP13(GATHER4) +OP12(RESINFO) +OP13(SAMPLE_POS) +OP12(SAMPLE_INFO) + #undef OP00 #undef OP01 @@ -180,6 +193,10 @@ OP00(ENDSWITCH) #undef OP14 #endif +#ifdef OP15 +#undef OP15 +#endif + #undef OP00_LBL #undef OP01_LBL diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c index 1891203abe1..fb36f9de32d 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_parse.c +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c @@ -128,6 +128,10 @@ tgsi_parse_token( } } + if (decl->Declaration.File == TGSI_FILE_RESOURCE) { + next_token(ctx, &decl->Resource); + } + break; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h index 2aafa2a6e83..b7a3c9bc0e6 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_parse.h +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h @@ -69,6 +69,7 @@ struct tgsi_full_declaration struct tgsi_declaration_dimension Dim; struct tgsi_declaration_semantic Semantic; struct tgsi_immediate_array_data ImmediateData; + struct tgsi_declaration_resource Resource; }; struct tgsi_full_immediate @@ -84,7 +85,7 @@ struct tgsi_full_property }; #define TGSI_FULL_MAX_DST_REGISTERS 2 -#define TGSI_FULL_MAX_SRC_REGISTERS 4 /* TXD has 4 */ +#define TGSI_FULL_MAX_SRC_REGISTERS 5 /* SAMPLE_D has 5 */ struct tgsi_full_instruction { diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c index acbff103efe..509c5346837 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c @@ -258,7 +258,8 @@ static const char *file_names[TGSI_FILE_COUNT] = "PRED", "SV", "IMMX", - "TEMPX" + "TEMPX", + "RES" }; static boolean diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index 819b0725a1f..1eac762e6e5 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -283,7 +283,8 @@ static const char *file_names[TGSI_FILE_COUNT] = "PRED", "SV", "IMMX", - "TEMPX" + "TEMPX", + "RES" }; static boolean @@ -828,6 +829,15 @@ static const char *texture_names[TGSI_TEXTURE_COUNT] = "SHADOWRECT" }; +static const char *type_names[] = +{ + "UNORM", + "SNORM", + "SINT", + "UINT", + "FLOAT" +}; + static boolean match_inst_mnemonic(const char **pcur, const struct tgsi_opcode_info *info) @@ -1104,42 +1114,113 @@ static boolean parse_declaration( struct translate_ctx *ctx ) cur = ctx->cur; eat_opt_white( &cur ); if (*cur == ',' && !is_vs_input) { - uint i; + uint i, j; cur++; eat_opt_white( &cur ); - for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) { - if (str_match_no_case( &cur, semantic_names[i] )) { - const char *cur2 = cur; - uint index; - - if (is_digit_alpha_underscore( cur )) - continue; - eat_opt_white( &cur2 ); - if (*cur2 == '[') { - cur2++; - eat_opt_white( &cur2 ); - if (!parse_uint( &cur2, &index )) { - report_error( ctx, "Expected literal integer" ); + if (file == TGSI_FILE_RESOURCE) { + for (i = 0; i < TGSI_TEXTURE_COUNT; i++) { + if (str_match_no_case(&cur, texture_names[i])) { + if (!is_digit_alpha_underscore(cur)) { + decl.Resource.Resource = i; + break; + } + } + } + if (i == TGSI_TEXTURE_COUNT) { + report_error(ctx, "Expected texture target"); + return FALSE; + } + eat_opt_white( &cur ); + if (*cur != ',') { + report_error( ctx, "Expected `,'" ); + return FALSE; + } + ++cur; + eat_opt_white( &cur ); + for (j = 0; j < 4; ++j) { + for (i = 0; i < PIPE_TYPE_COUNT; ++i) { + if (str_match_no_case(&cur, type_names[i])) { + if (!is_digit_alpha_underscore(cur)) { + switch (j) { + case 0: + decl.Resource.ReturnTypeX = i; + break; + case 1: + decl.Resource.ReturnTypeY = i; + break; + case 2: + decl.Resource.ReturnTypeZ = i; + break; + case 3: + decl.Resource.ReturnTypeW = i; + break; + default: + assert(0); + } + break; + } + } + } + if (i == PIPE_TYPE_COUNT) { + if (j == 0 || j > 2) { + report_error(ctx, "Expected type name"); return FALSE; } + break; + } else { + const char *cur2 = cur; eat_opt_white( &cur2 ); - if (*cur2 != ']') { - report_error( ctx, "Expected `]'" ); - return FALSE; + if (*cur2 == ',') { + cur2++; + eat_opt_white( &cur2 ); + cur = cur2; + continue; + } else + break; + } + } + if (j < 4) { + decl.Resource.ReturnTypeY = + decl.Resource.ReturnTypeZ = + decl.Resource.ReturnTypeW = + decl.Resource.ReturnTypeX; + } + ctx->cur = cur; + } else { + for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) { + if (str_match_no_case( &cur, semantic_names[i] )) { + const char *cur2 = cur; + uint index; + + if (is_digit_alpha_underscore( cur )) + continue; + eat_opt_white( &cur2 ); + if (*cur2 == '[') { + cur2++; + eat_opt_white( &cur2 ); + if (!parse_uint( &cur2, &index )) { + report_error( ctx, "Expected literal integer" ); + return FALSE; + } + eat_opt_white( &cur2 ); + if (*cur2 != ']') { + report_error( ctx, "Expected `]'" ); + return FALSE; + } + cur2++; + + decl.Semantic.Index = index; + + cur = cur2; } - cur2++; - decl.Semantic.Index = index; + decl.Declaration.Semantic = 1; + decl.Semantic.Name = i; - cur = cur2; + ctx->cur = cur; + break; } - - decl.Declaration.Semantic = 1; - decl.Semantic.Name = i; - - ctx->cur = cur; - break; } } } else if (is_imm_array) { diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c index 02de12d77d5..4564ab81f99 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2009 VMware, Inc. + * Copyright 2009-2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -47,6 +47,7 @@ union tgsi_any_token { struct tgsi_declaration_range decl_range; struct tgsi_declaration_dimension decl_dim; struct tgsi_declaration_semantic decl_semantic; + struct tgsi_declaration_resource decl_resource; struct tgsi_immediate imm; union tgsi_immediate_data imm_data; struct tgsi_instruction insn; @@ -137,6 +138,16 @@ struct ureg_program struct ureg_src sampler[PIPE_MAX_SAMPLERS]; unsigned nr_samplers; + struct { + unsigned index; + unsigned target; + unsigned return_type_x; + unsigned return_type_y; + unsigned return_type_z; + unsigned return_type_w; + } resource[PIPE_MAX_SHADER_RESOURCES]; + unsigned nr_resources; + unsigned temps_active[UREG_MAX_TEMP / 32]; unsigned nr_temps; @@ -578,6 +589,41 @@ struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg, return ureg->sampler[0]; } +/* + * Allocate a new shader resource. + */ +struct ureg_src +ureg_DECL_resource(struct ureg_program *ureg, + unsigned index, + unsigned target, + unsigned return_type_x, + unsigned return_type_y, + unsigned return_type_z, + unsigned return_type_w) +{ + struct ureg_src reg = ureg_src_register(TGSI_FILE_RESOURCE, index); + uint i; + + for (i = 0; i < ureg->nr_resources; i++) { + if (ureg->resource[i].index == index) { + return reg; + } + } + + if (i < PIPE_MAX_SHADER_RESOURCES) { + ureg->resource[i].index = index; + ureg->resource[i].target = target; + ureg->resource[i].return_type_x = return_type_x; + ureg->resource[i].return_type_y = return_type_y; + ureg->resource[i].return_type_z = return_type_z; + ureg->resource[i].return_type_w = return_type_w; + ureg->nr_resources++; + return reg; + } + + assert(0); + return reg; +} static int match_or_expand_immediate( const unsigned *v, @@ -821,9 +867,10 @@ ureg_emit_dst( struct ureg_program *ureg, assert(dst.File != TGSI_FILE_CONSTANT); assert(dst.File != TGSI_FILE_INPUT); assert(dst.File != TGSI_FILE_SAMPLER); + assert(dst.File != TGSI_FILE_RESOURCE); assert(dst.File != TGSI_FILE_IMMEDIATE); assert(dst.File < TGSI_FILE_COUNT); - + out[n].value = 0; out[n].dst.File = dst.File; out[n].dst.WriteMask = dst.WriteMask; @@ -1206,6 +1253,36 @@ emit_decl_range2D(struct ureg_program *ureg, } static void +emit_decl_resource(struct ureg_program *ureg, + unsigned index, + unsigned target, + unsigned return_type_x, + unsigned return_type_y, + unsigned return_type_z, + unsigned return_type_w ) +{ + union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3); + + out[0].value = 0; + out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; + out[0].decl.NrTokens = 3; + out[0].decl.File = TGSI_FILE_RESOURCE; + out[0].decl.UsageMask = 0xf; + out[0].decl.Interpolate = TGSI_INTERPOLATE_CONSTANT; + + out[1].value = 0; + out[1].decl_range.First = index; + out[1].decl_range.Last = index; + + out[2].value = 0; + out[2].decl_resource.Resource = target; + out[2].decl_resource.ReturnTypeX = return_type_x; + out[2].decl_resource.ReturnTypeY = return_type_y; + out[2].decl_resource.ReturnTypeZ = return_type_z; + out[2].decl_resource.ReturnTypeW = return_type_w; +} + +static void emit_immediate( struct ureg_program *ureg, const unsigned *v, unsigned type ) @@ -1341,6 +1418,16 @@ static void emit_decls( struct ureg_program *ureg ) ureg->sampler[i].Index, 1 ); } + for (i = 0; i < ureg->nr_resources; i++) { + emit_decl_resource(ureg, + ureg->resource[i].index, + ureg->resource[i].target, + ureg->resource[i].return_type_x, + ureg->resource[i].return_type_y, + ureg->resource[i].return_type_z, + ureg->resource[i].return_type_w); + } + if (ureg->const_decls.nr_constant_ranges) { for (i = 0; i < ureg->const_decls.nr_constant_ranges; i++) { emit_decl_range(ureg, diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h index 807128a5e52..b8d193f3f89 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h @@ -270,6 +270,15 @@ struct ureg_src ureg_DECL_sampler( struct ureg_program *, unsigned index ); +struct ureg_src +ureg_DECL_resource(struct ureg_program *, + unsigned index, + unsigned target, + unsigned return_type_x, + unsigned return_type_y, + unsigned return_type_z, + unsigned return_type_w ); + static INLINE struct ureg_src ureg_imm4f( struct ureg_program *ureg, @@ -733,6 +742,66 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \ } +#define OP14( op ) \ +static INLINE void ureg_##op( struct ureg_program *ureg, \ + struct ureg_dst dst, \ + struct ureg_src src0, \ + struct ureg_src src1, \ + struct ureg_src src2, \ + struct ureg_src src3 ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned insn = ureg_emit_insn(ureg, \ + opcode, \ + dst.Saturate, \ + dst.Predicate, \ + dst.PredNegate, \ + dst.PredSwizzleX, \ + dst.PredSwizzleY, \ + dst.PredSwizzleZ, \ + dst.PredSwizzleW, \ + 1, \ + 4).insn_token; \ + ureg_emit_dst( ureg, dst ); \ + ureg_emit_src( ureg, src0 ); \ + ureg_emit_src( ureg, src1 ); \ + ureg_emit_src( ureg, src2 ); \ + ureg_emit_src( ureg, src3 ); \ + ureg_fixup_insn_size( ureg, insn ); \ +} + + +#define OP15( op ) \ +static INLINE void ureg_##op( struct ureg_program *ureg, \ + struct ureg_dst dst, \ + struct ureg_src src0, \ + struct ureg_src src1, \ + struct ureg_src src2, \ + struct ureg_src src3, \ + struct ureg_src src4 ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned insn = ureg_emit_insn(ureg, \ + opcode, \ + dst.Saturate, \ + dst.Predicate, \ + dst.PredNegate, \ + dst.PredSwizzleX, \ + dst.PredSwizzleY, \ + dst.PredSwizzleZ, \ + dst.PredSwizzleW, \ + 1, \ + 5).insn_token; \ + ureg_emit_dst( ureg, dst ); \ + ureg_emit_src( ureg, src0 ); \ + ureg_emit_src( ureg, src1 ); \ + ureg_emit_src( ureg, src2 ); \ + ureg_emit_src( ureg, src3 ); \ + ureg_emit_src( ureg, src4 ); \ + ureg_fixup_insn_size( ureg, insn ); \ +} + + /* Use a template include to generate a correctly-typed ureg_OP() * function for each TGSI opcode: */ |