tgsi: Add support for global / private / input MEMORY

Extend the MEMORY file support to differentiate between global, private
and shared memory, as well as "input" memory.

"MEMORY[x], INPUT" is intended to access OpenCL kernel parameters, a
special memory type is added for this, since the actual storage of these
(e.g. UBO-s) may differ per implementation. The uploading of kernel
parameters is handled by launch_grid, "MEMORY[x], INPUT" allows drivers
to use an access mechanism for parameter reads which matches with the
upload method.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu> (v1)
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> (v2)
This commit is contained in:
Hans de Goede
2016-03-10 13:52:00 +01:00
parent 43ddec2f43
commit 3788e1bf74
8 changed files with 51 additions and 26 deletions

View File

@@ -111,7 +111,7 @@ tgsi_default_declaration( void )
declaration.Local = 0; declaration.Local = 0;
declaration.Array = 0; declaration.Array = 0;
declaration.Atomic = 0; declaration.Atomic = 0;
declaration.Shared = 0; declaration.MemType = TGSI_MEMORY_TYPE_GLOBAL;
declaration.Padding = 0; declaration.Padding = 0;
return declaration; return declaration;
@@ -128,7 +128,7 @@ tgsi_build_declaration(
unsigned local, unsigned local,
unsigned array, unsigned array,
unsigned atomic, unsigned atomic,
unsigned shared, unsigned mem_type,
struct tgsi_header *header ) struct tgsi_header *header )
{ {
struct tgsi_declaration declaration; struct tgsi_declaration declaration;
@@ -146,7 +146,7 @@ tgsi_build_declaration(
declaration.Local = local; declaration.Local = local;
declaration.Array = array; declaration.Array = array;
declaration.Atomic = atomic; declaration.Atomic = atomic;
declaration.Shared = shared; declaration.MemType = mem_type;
header_bodysize_grow( header ); header_bodysize_grow( header );
return declaration; return declaration;
@@ -406,7 +406,7 @@ tgsi_build_full_declaration(
full_decl->Declaration.Local, full_decl->Declaration.Local,
full_decl->Declaration.Array, full_decl->Declaration.Array,
full_decl->Declaration.Atomic, full_decl->Declaration.Atomic,
full_decl->Declaration.Shared, full_decl->Declaration.MemType,
header ); header );
if (maxsize <= size) if (maxsize <= size)

View File

@@ -365,8 +365,13 @@ iter_declaration(
} }
if (decl->Declaration.File == TGSI_FILE_MEMORY) { if (decl->Declaration.File == TGSI_FILE_MEMORY) {
if (decl->Declaration.Shared) switch (decl->Declaration.MemType) {
TXT(", SHARED"); /* Note: ,GLOBAL is optional / the default */
case TGSI_MEMORY_TYPE_GLOBAL: TXT(", GLOBAL"); break;
case TGSI_MEMORY_TYPE_SHARED: TXT(", SHARED"); break;
case TGSI_MEMORY_TYPE_PRIVATE: TXT(", PRIVATE"); break;
case TGSI_MEMORY_TYPE_INPUT: TXT(", INPUT"); break;
}
} }
if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) { if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) {

View File

@@ -1390,8 +1390,18 @@ static boolean parse_declaration( struct translate_ctx *ctx )
ctx->cur = cur; ctx->cur = cur;
} }
} else if (file == TGSI_FILE_MEMORY) { } else if (file == TGSI_FILE_MEMORY) {
if (str_match_nocase_whole(&cur, "SHARED")) { if (str_match_nocase_whole(&cur, "GLOBAL")) {
decl.Declaration.Shared = 1; /* Note this is a no-op global is the default */
decl.Declaration.MemType = TGSI_MEMORY_TYPE_GLOBAL;
ctx->cur = cur;
} else if (str_match_nocase_whole(&cur, "SHARED")) {
decl.Declaration.MemType = TGSI_MEMORY_TYPE_SHARED;
ctx->cur = cur;
} else if (str_match_nocase_whole(&cur, "PRIVATE")) {
decl.Declaration.MemType = TGSI_MEMORY_TYPE_PRIVATE;
ctx->cur = cur;
} else if (str_match_nocase_whole(&cur, "INPUT")) {
decl.Declaration.MemType = TGSI_MEMORY_TYPE_INPUT;
ctx->cur = cur; ctx->cur = cur;
} }
} else { } else {

View File

@@ -191,7 +191,7 @@ struct ureg_program
struct ureg_tokens domain[2]; struct ureg_tokens domain[2];
bool use_shared_memory; bool use_memory[TGSI_MEMORY_TYPE_COUNT];
}; };
static union tgsi_any_token error_tokens[32]; static union tgsi_any_token error_tokens[32];
@@ -730,13 +730,14 @@ struct ureg_src ureg_DECL_buffer(struct ureg_program *ureg, unsigned nr,
return reg; return reg;
} }
/* Allocate a shared memory area. /* Allocate a memory area.
*/ */
struct ureg_src ureg_DECL_shared_memory(struct ureg_program *ureg) struct ureg_src ureg_DECL_memory(struct ureg_program *ureg,
unsigned memory_type)
{ {
struct ureg_src reg = ureg_src_register(TGSI_FILE_MEMORY, 0); struct ureg_src reg = ureg_src_register(TGSI_FILE_MEMORY, memory_type);
ureg->use_shared_memory = true; ureg->use_memory[memory_type] = true;
return reg; return reg;
} }
@@ -1673,7 +1674,7 @@ emit_decl_buffer(struct ureg_program *ureg,
} }
static void static void
emit_decl_shared_memory(struct ureg_program *ureg) emit_decl_memory(struct ureg_program *ureg, unsigned memory_type)
{ {
union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2); union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2);
@@ -1682,11 +1683,11 @@ emit_decl_shared_memory(struct ureg_program *ureg)
out[0].decl.NrTokens = 2; out[0].decl.NrTokens = 2;
out[0].decl.File = TGSI_FILE_MEMORY; out[0].decl.File = TGSI_FILE_MEMORY;
out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
out[0].decl.Shared = true; out[0].decl.MemType = memory_type;
out[1].value = 0; out[1].value = 0;
out[1].decl_range.First = 0; out[1].decl_range.First = memory_type;
out[1].decl_range.Last = 0; out[1].decl_range.Last = memory_type;
} }
static void static void
@@ -1861,8 +1862,10 @@ static void emit_decls( struct ureg_program *ureg )
emit_decl_buffer(ureg, ureg->buffer[i].index, ureg->buffer[i].atomic); emit_decl_buffer(ureg, ureg->buffer[i].index, ureg->buffer[i].atomic);
} }
if (ureg->use_shared_memory) for (i = 0; i < TGSI_MEMORY_TYPE_COUNT; i++) {
emit_decl_shared_memory(ureg); if (ureg->use_memory[i])
emit_decl_memory(ureg, i);
}
if (ureg->const_decls.nr_constant_ranges) { if (ureg->const_decls.nr_constant_ranges) {
for (i = 0; i < ureg->const_decls.nr_constant_ranges; i++) { for (i = 0; i < ureg->const_decls.nr_constant_ranges; i++) {

View File

@@ -340,7 +340,7 @@ struct ureg_src
ureg_DECL_buffer(struct ureg_program *ureg, unsigned nr, bool atomic); ureg_DECL_buffer(struct ureg_program *ureg, unsigned nr, bool atomic);
struct ureg_src struct ureg_src
ureg_DECL_shared_memory(struct ureg_program *ureg); ureg_DECL_memory(struct ureg_program *ureg, unsigned memory_type);
static inline struct ureg_src static inline struct ureg_src
ureg_imm4f( struct ureg_program *ureg, ureg_imm4f( struct ureg_program *ureg,

View File

@@ -864,7 +864,7 @@ public:
std::vector<Resource> resources; std::vector<Resource> resources;
struct MemoryFile { struct MemoryFile {
bool shared; uint8_t mem_type; // TGSI_MEMORY_TYPE_*
}; };
std::vector<MemoryFile> memoryFiles; std::vector<MemoryFile> memoryFiles;
@@ -1222,7 +1222,7 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl)
break; break;
case TGSI_FILE_MEMORY: case TGSI_FILE_MEMORY:
for (i = first; i <= last; ++i) for (i = first; i <= last; ++i)
memoryFiles[i].shared = decl->Declaration.Shared; memoryFiles[i].mem_type = decl->Declaration.MemType;
break; break;
case TGSI_FILE_NULL: case TGSI_FILE_NULL:
case TGSI_FILE_TEMPORARY: case TGSI_FILE_TEMPORARY:
@@ -1527,7 +1527,8 @@ Converter::makeSym(uint tgsiFile, int fileIdx, int idx, int c, uint32_t address)
sym->reg.fileIndex = fileIdx; sym->reg.fileIndex = fileIdx;
if (tgsiFile == TGSI_FILE_MEMORY && code->memoryFiles[fileIdx].shared) if (tgsiFile == TGSI_FILE_MEMORY &&
code->memoryFiles[fileIdx].mem_type == TGSI_MEMORY_TYPE_SHARED)
sym->setFile(FILE_MEMORY_SHARED); sym->setFile(FILE_MEMORY_SHARED);
if (idx >= 0) { if (idx >= 0) {

View File

@@ -117,6 +117,12 @@ enum tgsi_file_type {
#define TGSI_CYLINDRICAL_WRAP_Z (1 << 2) #define TGSI_CYLINDRICAL_WRAP_Z (1 << 2)
#define TGSI_CYLINDRICAL_WRAP_W (1 << 3) #define TGSI_CYLINDRICAL_WRAP_W (1 << 3)
#define TGSI_MEMORY_TYPE_GLOBAL 0 /* OpenCL global */
#define TGSI_MEMORY_TYPE_SHARED 1 /* OpenCL local / GLSL shared */
#define TGSI_MEMORY_TYPE_PRIVATE 2 /* OpenCL private */
#define TGSI_MEMORY_TYPE_INPUT 3 /* OpenCL kernel input params */
#define TGSI_MEMORY_TYPE_COUNT 4
struct tgsi_declaration struct tgsi_declaration
{ {
unsigned Type : 4; /**< TGSI_TOKEN_TYPE_DECLARATION */ unsigned Type : 4; /**< TGSI_TOKEN_TYPE_DECLARATION */
@@ -130,8 +136,8 @@ struct tgsi_declaration
unsigned Local : 1; /**< optimize as subroutine local variable? */ unsigned Local : 1; /**< optimize as subroutine local variable? */
unsigned Array : 1; /**< extra array info? */ unsigned Array : 1; /**< extra array info? */
unsigned Atomic : 1; /**< atomic only? for TGSI_FILE_BUFFER */ unsigned Atomic : 1; /**< atomic only? for TGSI_FILE_BUFFER */
unsigned Shared : 1; /**< shared storage for TGSI_FILE_MEMORY */ unsigned MemType : 2; /**< TGSI_MEMORY_TYPE_x for TGSI_FILE_MEMORY */
unsigned Padding : 4; unsigned Padding : 3;
}; };
struct tgsi_declaration_range struct tgsi_declaration_range

View File

@@ -6345,7 +6345,7 @@ st_translate_program(
} }
if (program->use_shared_memory) if (program->use_shared_memory)
t->shared_memory = ureg_DECL_shared_memory(ureg); t->shared_memory = ureg_DECL_memory(ureg, TGSI_MEMORY_TYPE_SHARED);
for (i = 0; i < program->shader->NumImages; i++) { for (i = 0; i < program->shader->NumImages; i++) {
if (program->images_used & (1 << i)) { if (program->images_used & (1 << i)) {