[virglrenderer-devel] [PATCH 3/3] shader: Add support for TGSI_FILE_HW_ATOMIC
Tomeu Vizoso
tomeu.vizoso at collabora.com
Thu Jul 19 13:41:42 UTC 2018
Add support for TGSI's HW atomic counters, implemented here with
atomic_uint.
Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---
src/vrend_shader.c | 54 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 53 insertions(+), 1 deletion(-)
diff --git a/src/vrend_shader.c b/src/vrend_shader.c
index f6247c26aa2a..f5f8eb726188 100644
--- a/src/vrend_shader.c
+++ b/src/vrend_shader.c
@@ -180,6 +180,11 @@ struct dump_ctx {
uint32_t images_used;
bool iviews_used;
+ uint32_t num_abo;
+ int abo_idx[32];
+ int abo_sizes[32];
+ int abo_offsets[32];
+
uint32_t num_ssbo;
struct vrend_ssbo ssbos[32];
@@ -276,6 +281,7 @@ struct source_info {
bool tg4_has_component;
bool override_no_wm[3];
bool override_no_cast[3];
+ bool has_minus_one;
};
static const struct vrend_shader_table conversion_table[] =
@@ -1218,6 +1224,16 @@ iter_declaration(struct tgsi_iterate_context *iter,
break;
case TGSI_FILE_MEMORY:
break;
+ case TGSI_FILE_HW_ATOMIC:
+ if (ctx->num_abo >= ARRAY_SIZE(ctx->abo_idx)) {
+ fprintf(stderr, "Number of atomic counter buffers exceeded, max is %lu\n", ARRAY_SIZE(ctx->abo_idx));
+ return FALSE;
+ }
+ ctx->abo_idx[ctx->num_abo] = decl->Dim.Index2D;
+ ctx->abo_sizes[ctx->num_abo] = decl->Range.Last - decl->Range.First + 1;
+ ctx->abo_offsets[ctx->num_abo] = decl->Range.First;
+ ctx->num_abo++;
+ break;
default:
fprintf(stderr,"unsupported file %d declaration\n", decl->Declaration.File);
break;
@@ -2445,6 +2461,9 @@ translate_load(struct dump_ctx *ctx,
snprintf(buf, 255, "%s.w = (uintBitsToFloat((%s[(uint(floatBitsToUint(%s)) >> 2)+3u])));\n", mydst, srcs[0], srcs[1]);
EMIT_BUF_WITH_RET(ctx, buf);
}
+ } else if (src->Register.File == TGSI_FILE_HW_ATOMIC) {
+ snprintf(buf, 255, "%s = uintBitsToFloat(atomicCounter(%s));\n", dsts[0], srcs[0]);
+ EMIT_BUF_WITH_RET(ctx, buf);
}
return 0;
@@ -2563,7 +2582,12 @@ translate_atomic(struct dump_ctx *ctx,
const char *conversion = sinfo->override_no_cast[1] ? "" : get_string(FLOAT_BITS_TO_UINT);
if (src->Register.File == TGSI_FILE_IMAGE)
snprintf(buf, 512, "%s = %s(imageAtomic%s(%s, %s(%s(%s))%s, %s(%s(%s))%s));\n", dsts[0], get_string(dtypeprefix), opname, srcs[0], get_string(coord_prefix), conversion, srcs[1], ms_str, get_string(stypecast), get_string(stypeprefix), srcs[2], cas_str);
- else
+ else if(src->Register.File == TGSI_FILE_HW_ATOMIC) {
+ if (sinfo->has_minus_one)
+ snprintf(buf, 512, "%s = uintBitsToFloat(atomicCounterDecrement(%s) + 1u);\n", dsts[0], srcs[0]);
+ else
+ snprintf(buf, 512, "%s = uintBitsToFloat(atomicCounterIncrement(%s));\n", dsts[0], srcs[0]);
+ } else
snprintf(buf, 512, "%s = %s(atomic%s(%s[int(floatBitsToInt(%s)) >> 2], uint(%s(%s).x)%s));\n", dsts[0], get_string(dtypeprefix), opname, srcs[0], srcs[1], get_string(stypeprefix), srcs[2], cas_str);
EMIT_BUF_WITH_RET(ctx, buf);
return 0;
@@ -3093,6 +3117,8 @@ get_source_info(struct dump_ctx *ctx,
break;
case TGSI_IMM_INT32:
snprintf(temp, 25, "%d", imd->val[idx].i);
+ if (imd->val[idx].i == -1)
+ sinfo->has_minus_one = true;
break;
case TGSI_IMM_FLOAT64:
snprintf(temp, 48, "%uU", imd->val[idx].ui);
@@ -3160,6 +3186,21 @@ get_source_info(struct dump_ctx *ctx,
sinfo->override_no_wm[i] = ctx->system_values[j].override_no_wm;
break;
}
+ } else if (src->Register.File == TGSI_FILE_HW_ATOMIC) {
+ for (uint32_t j = 0; j < ctx->num_abo; j++) {
+ if (src->Dimension.Index == ctx->abo_idx[j] &&
+ src->Register.Index >= ctx->abo_offsets[j] &&
+ src->Register.Index < ctx->abo_offsets[j] + ctx->abo_sizes[j]) {
+ if (ctx->abo_sizes[j] > 1) {
+ if (ctx->info.indirect_files & (1 << TGSI_FILE_HW_ATOMIC))
+ snprintf(srcs[i], 255, "ac%d[addr%d]", j, src->Indirect.Index);
+ else
+ snprintf(srcs[i], 255, "ac%d[%d]", j, src->Register.Index);
+ } else
+ snprintf(srcs[i], 255, "ac%d", j);
+ }
+ }
+ sinfo->sreg_index = src->Register.Index;
}
if (stype == TGSI_TYPE_DOUBLE) {
@@ -3888,6 +3929,9 @@ static char *emit_header(struct dump_ctx *ctx, char *glsl_hdr)
if (ctx->num_ssbo)
STRCAT_WITH_RET(glsl_hdr, "#extension GL_ARB_shader_storage_buffer_object : require\n");
+ if (ctx->num_abo)
+ STRCAT_WITH_RET(glsl_hdr, "#extension GL_ARB_shader_atomic_counters : require\n");
+
for (uint32_t i = 0; i < ARRAY_SIZE(shader_req_table); i++) {
if (shader_req_table[i].key == SHADER_REQ_SAMPLER_RECT && ctx->glsl_ver_required >= 140)
continue;
@@ -4591,6 +4635,14 @@ static char *emit_ios(struct dump_ctx *ctx, char *glsl_hdr)
}
}
+ for (i = 0; i < ctx->num_abo; i++){
+ if (ctx->abo_sizes[i] > 1)
+ snprintf(buf, 255, "layout (binding = %d, offset = %d) uniform atomic_uint ac%d[%d];\n", ctx->abo_idx[i], ctx->abo_offsets[i] * 4, i, ctx->abo_sizes[i]);
+ else
+ snprintf(buf, 255, "layout (binding = %d, offset = %d) uniform atomic_uint ac%d;\n", ctx->abo_idx[i], ctx->abo_offsets[i] * 4, i);
+ STRCAT_WITH_RET(glsl_hdr, buf);
+ }
+
if (ctx->info.indirect_files & (1 << TGSI_FILE_BUFFER)) {
} else {
--
2.17.1
More information about the virglrenderer-devel
mailing list