summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlia Mirkin <imirkin@alum.mit.edu>2015-11-07 02:25:20 -0500
committerIlia Mirkin <imirkin@alum.mit.edu>2016-01-08 15:10:32 -0500
commit50b8488926c4fa45ed79148217b81e54252788e7 (patch)
tree087c2e57e6be421f07dd7ce2951029ae9ac67485
parent888ddd632d7f6af635cc948f1b3e8982b43800d2 (diff)
tgsi: provide a way to encode memory qualifiers for SSBO
Each load/store on most hardware can specify what caching to do. Since SSBO allows individual variables to also have separate caching modes, allow loads/stores to have the qualifiers instead of attempting to encode them in declarations. Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> Reviewed-by: Marek Olšák <marek.olsak@amd.com>
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.c50
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump.c10
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.c4
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.h1
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_strings.c7
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_strings.h2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c27
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c52
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.h13
-rw-r--r--src/gallium/include/pipe/p_shader_tokens.h16
10 files changed, 180 insertions, 2 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
index bb9d0cbe25..ea207461d2 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
@@ -620,7 +620,8 @@ tgsi_default_instruction( void )
instruction.NumSrcRegs = 1;
instruction.Label = 0;
instruction.Texture = 0;
- instruction.Padding = 0;
+ instruction.Memory = 0;
+ instruction.Padding = 0;
return instruction;
}
@@ -766,6 +767,34 @@ tgsi_build_instruction_texture(
return instruction_texture;
}
+static struct tgsi_instruction_memory
+tgsi_default_instruction_memory( void )
+{
+ struct tgsi_instruction_memory instruction_memory;
+
+ instruction_memory.Qualifier = 0;
+ instruction_memory.Padding = 0;
+
+ return instruction_memory;
+}
+
+static struct tgsi_instruction_memory
+tgsi_build_instruction_memory(
+ unsigned qualifier,
+ struct tgsi_token *prev_token,
+ struct tgsi_instruction *instruction,
+ struct tgsi_header *header )
+{
+ struct tgsi_instruction_memory instruction_memory;
+
+ instruction_memory.Qualifier = qualifier;
+ instruction_memory.Padding = 0;
+ instruction->Memory = 1;
+
+ instruction_grow( instruction, header );
+
+ return instruction_memory;
+}
static struct tgsi_texture_offset
tgsi_default_texture_offset( void )
@@ -1012,6 +1041,7 @@ tgsi_default_full_instruction( void )
full_instruction.Predicate = tgsi_default_instruction_predicate();
full_instruction.Label = tgsi_default_instruction_label();
full_instruction.Texture = tgsi_default_instruction_texture();
+ full_instruction.Memory = tgsi_default_instruction_memory();
for( i = 0; i < TGSI_FULL_MAX_TEX_OFFSETS; i++ ) {
full_instruction.TexOffsets[i] = tgsi_default_texture_offset();
}
@@ -1123,6 +1153,24 @@ tgsi_build_full_instruction(
prev_token = (struct tgsi_token *) texture_offset;
}
}
+
+ if (full_inst->Instruction.Memory) {
+ struct tgsi_instruction_memory *instruction_memory;
+
+ if( maxsize <= size )
+ return 0;
+ instruction_memory =
+ (struct tgsi_instruction_memory *) &tokens[size];
+ size++;
+
+ *instruction_memory = tgsi_build_instruction_memory(
+ full_inst->Memory.Qualifier,
+ prev_token,
+ instruction,
+ header );
+ prev_token = (struct tgsi_token *) instruction_memory;
+ }
+
for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) {
const struct tgsi_full_dst_register *reg = &full_inst->Dst[i];
struct tgsi_dst_register *dst_register;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index de3aae5337..2ad29b9d49 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -624,6 +624,16 @@ iter_instruction(
}
}
+ if (inst->Instruction.Memory) {
+ uint32_t qualifier = inst->Memory.Qualifier;
+ while (qualifier) {
+ int bit = ffs(qualifier) - 1;
+ qualifier &= ~(1U << bit);
+ TXT(", ");
+ ENM(bit, tgsi_memory_names);
+ }
+ }
+
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_IF:
case TGSI_OPCODE_UIF:
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
index 9a52bbbf5c..ae95ebd82a 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
@@ -195,6 +195,10 @@ tgsi_parse_token(
}
}
+ if (inst->Instruction.Memory) {
+ next_token(ctx, &inst->Memory);
+ }
+
assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS );
for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h
index 5ed1a83b02..4689fb797d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
@@ -91,6 +91,7 @@ struct tgsi_full_instruction
struct tgsi_instruction_predicate Predicate;
struct tgsi_instruction_label Label;
struct tgsi_instruction_texture Texture;
+ struct tgsi_instruction_memory Memory;
struct tgsi_full_dst_register Dst[TGSI_FULL_MAX_DST_REGISTERS];
struct tgsi_full_src_register Src[TGSI_FULL_MAX_SRC_REGISTERS];
struct tgsi_texture_offset TexOffsets[TGSI_FULL_MAX_TEX_OFFSETS];
diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.c b/src/gallium/auxiliary/tgsi/tgsi_strings.c
index c0dd04497f..f2d70d4983 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_strings.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_strings.c
@@ -208,6 +208,13 @@ const char *tgsi_immediate_type_names[4] =
"FLT64"
};
+const char *tgsi_memory_names[3] =
+{
+ "COHERENT",
+ "RESTRICT",
+ "VOLATILE",
+};
+
static inline void
tgsi_strings_check(void)
diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.h b/src/gallium/auxiliary/tgsi/tgsi_strings.h
index 71e74372f2..031d32278c 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_strings.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_strings.h
@@ -60,6 +60,8 @@ extern const char *tgsi_fs_coord_pixel_center_names[2];
extern const char *tgsi_immediate_type_names[4];
+extern const char *tgsi_memory_names[3];
+
const char *
tgsi_file_name(unsigned file);
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index d72d843951..97b1869a66 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -1039,6 +1039,12 @@ parse_instruction(
inst.Texture.Texture = TGSI_TEXTURE_UNKNOWN;
}
+ if ((i >= TGSI_OPCODE_LOAD && i <= TGSI_OPCODE_ATOMIMAX) ||
+ i == TGSI_OPCODE_RESQ) {
+ inst.Instruction.Memory = 1;
+ inst.Memory.Qualifier = 0;
+ }
+
/* Parse instruction operands.
*/
for (i = 0; i < info->num_dst + info->num_src + info->is_tex; i++) {
@@ -1091,6 +1097,27 @@ parse_instruction(
inst.Texture.NumOffsets = i;
cur = ctx->cur;
+ eat_opt_white(&cur);
+ for (i = 0; inst.Instruction.Memory && *cur == ','; i++) {
+ uint j;
+ cur++;
+ eat_opt_white(&cur);
+ ctx->cur = cur;
+ for (j = 0; j < 3; j++) {
+ if (str_match_nocase_whole(&ctx->cur, tgsi_memory_names[j])) {
+ inst.Memory.Qualifier |= 1U << j;
+ break;
+ }
+ }
+ if (j == 3) {
+ report_error(ctx, "Expected memory qualifier");
+ return FALSE;
+ }
+ cur = ctx->cur;
+ eat_opt_white(&cur);
+ }
+
+ cur = ctx->cur;
eat_opt_white( &cur );
if (info->is_branch && *cur == ':') {
uint target;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index 0ad23dd5e5..d6811501d1 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -60,6 +60,7 @@ union tgsi_any_token {
struct tgsi_instruction_predicate insn_predicate;
struct tgsi_instruction_label insn_label;
struct tgsi_instruction_texture insn_texture;
+ struct tgsi_instruction_memory insn_memory;
struct tgsi_texture_offset insn_texture_offset;
struct tgsi_src_register src;
struct tgsi_ind_register ind;
@@ -1226,6 +1227,21 @@ ureg_emit_texture_offset(struct ureg_program *ureg,
}
+void
+ureg_emit_memory(struct ureg_program *ureg,
+ unsigned extended_token,
+ unsigned qualifier)
+{
+ union tgsi_any_token *out, *insn;
+
+ out = get_tokens( ureg, DOMAIN_INSN, 1 );
+ insn = retrieve_token( ureg, DOMAIN_INSN, extended_token );
+
+ insn->insn.Memory = 1;
+
+ out[0].value = 0;
+ out[0].insn_memory.Qualifier = qualifier;
+}
void
ureg_fixup_insn_size(struct ureg_program *ureg,
@@ -1378,6 +1394,42 @@ ureg_label_insn(struct ureg_program *ureg,
}
+void
+ureg_memory_insn(struct ureg_program *ureg,
+ unsigned opcode,
+ const struct ureg_dst *dst,
+ unsigned nr_dst,
+ const struct ureg_src *src,
+ unsigned nr_src,
+ unsigned qualifier)
+{
+ struct ureg_emit_insn_result insn;
+ unsigned i;
+
+ insn = ureg_emit_insn(ureg,
+ opcode,
+ FALSE,
+ FALSE,
+ FALSE,
+ TGSI_SWIZZLE_X,
+ TGSI_SWIZZLE_Y,
+ TGSI_SWIZZLE_Z,
+ TGSI_SWIZZLE_W,
+ nr_dst,
+ nr_src);
+
+ ureg_emit_memory(ureg, insn.extended_token, qualifier);
+
+ for (i = 0; i < nr_dst; i++)
+ ureg_emit_dst(ureg, dst[i]);
+
+ for (i = 0; i < nr_src; i++)
+ ureg_emit_src(ureg, src[i]);
+
+ ureg_fixup_insn_size(ureg, insn.insn_token);
+}
+
+
static void
emit_decl_semantic(struct ureg_program *ureg,
unsigned file,
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
index 4a411c6649..86e58a9134 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -531,6 +531,14 @@ ureg_label_insn(struct ureg_program *ureg,
unsigned nr_src,
unsigned *label);
+void
+ureg_memory_insn(struct ureg_program *ureg,
+ unsigned opcode,
+ const struct ureg_dst *dst,
+ unsigned nr_dst,
+ const struct ureg_src *src,
+ unsigned nr_src,
+ unsigned qualifier);
/***********************************************************************
* Internal instruction helpers, don't call these directly:
@@ -568,6 +576,11 @@ void
ureg_emit_texture_offset(struct ureg_program *ureg,
const struct tgsi_texture_offset *offset);
+void
+ureg_emit_memory(struct ureg_program *ureg,
+ unsigned insn_token,
+ unsigned qualifier);
+
void
ureg_emit_dst( struct ureg_program *ureg,
struct ureg_dst dst );
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index 815aff1dab..43a5561882 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -572,7 +572,8 @@ struct tgsi_instruction
unsigned Predicate : 1; /* BOOL */
unsigned Label : 1;
unsigned Texture : 1;
- unsigned Padding : 2;
+ unsigned Memory : 1;
+ unsigned Padding : 1;
};
/*
@@ -729,6 +730,19 @@ struct tgsi_dst_register
unsigned Padding : 6;
};
+#define TGSI_MEMORY_COHERENT (1 << 0)
+#define TGSI_MEMORY_RESTRICT (1 << 1)
+#define TGSI_MEMORY_VOLATILE (1 << 2)
+
+/**
+ * Specifies the type of memory access to do for the LOAD/STORE instruction.
+ */
+struct tgsi_instruction_memory
+{
+ unsigned Qualifier : 3; /* TGSI_MEMORY_ */
+ unsigned Padding : 29;
+};
+
#ifdef __cplusplus
}