summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/tgsi
diff options
context:
space:
mode:
authorZack Rusin <[email protected]>2011-01-24 17:47:10 -0500
committerZack Rusin <[email protected]>2011-01-24 17:47:10 -0500
commitbdbe77f9c6f06cfaa155f27c2ade3c523d7fbea7 (patch)
treed131d945212a92fd9179bbcb1dd08db0f1c99356 /src/gallium/auxiliary/tgsi
parentb0669837808dee576dd05c8c335ca78264dd8e80 (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/tgsi')
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.c59
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump.c32
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c211
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.h1
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info.c15
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h17
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.c4
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.h3
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sanity.c3
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c135
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c91
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.h69
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:
*/