[virglrenderer-devel] [PATCH 02/10] shader: add image support to shader parsing. (v2.1)
Gert Wollny
gert.wollny at collabora.com
Thu Jul 26 14:24:34 UTC 2018
Am Mittwoch, den 25.07.2018, 09:00 +1000 schrieb Dave Airlie:
> From: Dave Airlie <airlied at redhat.com>
>
> This converts the image related opcodes, and tracks the used
> images.
>
> Images need some extensions for extra features:
> ES_3_1_compatability is needed for r32f image support
> shader_image_size for image size support
>
> v2: image: fix missing emit for atomic,
> use a shader req for images extension
> extend cas_str - we overflowed this
> v2.1: drop extra breaks, use decl last for range check (Tomeu)
> ---
> src/vrend_shader.c | 393
> ++++++++++++++++++++++++++++++++++++++++++++++++++---
> src/vrend_shader.h | 1 +
> 2 files changed, 376 insertions(+), 18 deletions(-)
>
> diff --git a/src/vrend_shader.c b/src/vrend_shader.c
> index a54e56b..6431280 100644
> --- a/src/vrend_shader.c
> +++ b/src/vrend_shader.c
> @@ -56,6 +56,9 @@ extern int vrend_dump_shaders;
> #define SHADER_REQ_GPU_SHADER5 (1 << 12)
> #define SHADER_REQ_DERIVATIVE_CONTROL (1 << 13)
> #define SHADER_REQ_FP64 (1 << 14)
> +#define SHADER_REQ_IMAGE_LOAD_STORE (1 << 15)
> +#define SHADER_REQ_ES31_COMPAT (1 << 16)
> +#define SHADER_REQ_IMAGE_SIZE (1 << 17)
>
> struct vrend_shader_io {
> unsigned name;
> @@ -86,6 +89,12 @@ struct vrend_shader_table {
> const char *string;
> };
>
> +struct vrend_shader_image {
> + struct tgsi_declaration_image decl;
> + enum tgsi_return_type image_return;
> + bool vflag;
> +};
> +
> #define MAX_IMMEDIATE 1024
> struct immed {
> int type;
> @@ -143,6 +152,9 @@ struct dump_ctx {
> uint32_t ssbo_array_base;
> uint32_t ssbo_atomic_array_base;
>
> + struct vrend_shader_image images[32];
> + uint32_t images_used_mask;
> +
> struct vrend_sampler_array *sampler_arrays;
> uint32_t num_sampler_arrays;
> int last_sampler_array_idx;
> @@ -210,6 +222,9 @@ static const struct vrend_shader_table
> shader_req_table[] = {
> { SHADER_REQ_GPU_SHADER5, "GL_ARB_gpu_shader5" },
> { SHADER_REQ_DERIVATIVE_CONTROL, "GL_ARB_derivative_control" },
> { SHADER_REQ_FP64, "GL_ARB_gpu_shader_fp64" },
> + { SHADER_REQ_IMAGE_LOAD_STORE, "GL_ARB_shader_image_load_store"
> },
> + { SHADER_REQ_ES31_COMPAT, "GL_ARB_ES3_1_compatibility" },
> + { SHADER_REQ_IMAGE_SIZE, "GL_ARB_shader_image_size" },
> };
For later: that looks like a candidate that could make use of the new
feature table (i.e. replace the extension strings by feat_* and test
for that).
>
> enum vrend_type_qualifier {
> @@ -301,6 +316,8 @@ static inline const char *get_wm_string(unsigned
> wm)
> }
> }
>
> +const char *get_internalformat_string(int virgl_format, enum
> tgsi_return_type *stype);
> +
> static inline const char *tgsi_proc_to_prefix(int shader_type)
> {
> switch (shader_type) {
> @@ -488,6 +505,29 @@ static struct vrend_temp_range
> *find_temp_range(struct dump_ctx *ctx, int index)
> return NULL;
> }
>
> +static int add_images(struct dump_ctx *ctx, int first, int last,
> + struct tgsi_declaration_image *img_decl)
> +{
> + int i;
> +
> + for (i = first; i <= last; i++) {
> + ctx->images[i].decl = *img_decl;
> + ctx->images[i].vflag = false;
> + ctx->images_used_mask |= (1 << i);
> +
> + if (ctx->images[i].decl.Resource == TGSI_TEXTURE_CUBE_ARRAY)
> + ctx->shader_req_bits |= SHADER_REQ_CUBE_ARRAY;
> + else if (ctx->images[i].decl.Resource == TGSI_TEXTURE_2D_MSAA
> ||
> + ctx->images[i].decl.Resource ==
> TGSI_TEXTURE_2D_ARRAY_MSAA)
> + ctx->shader_req_bits |= SHADER_REQ_SAMPLER_MS;
> + else if (ctx->images[i].decl.Resource == TGSI_TEXTURE_BUFFER)
> + ctx->uses_sampler_buf = true;
> + else if (ctx->images[i].decl.Resource == TGSI_TEXTURE_RECT)
> + ctx->shader_req_bits |= SHADER_REQ_SAMPLER_RECT;
> + }
> + return 0;
> +}
> +
> static int add_sampler_array(struct dump_ctx *ctx, int first, int
> last, int sview_type, int sview_rtype)
> {
> int idx = ctx->num_sampler_arrays;
> @@ -1049,6 +1089,14 @@ iter_declaration(struct tgsi_iterate_context
> *iter,
> }
> }
> break;
> + case TGSI_FILE_IMAGE:
> + ctx->shader_req_bits |= SHADER_REQ_IMAGE_LOAD_STORE;
> + if (decl->Range.Last >= ARRAY_SIZE(ctx->images)) {
> + fprintf(stderr, "Image view exceeded, max is %lu\n",
> ARRAY_SIZE(ctx->images));
> + return FALSE;
> + }
> + add_images(ctx, decl->Range.First, decl->Range.Last, &decl-
> >Image);
> + break;
> case TGSI_FILE_BUFFER:
> if (decl->Range.First >= 32) {
> fprintf(stderr, "Buffer view exceeded, max is 32\n");
> @@ -2144,6 +2192,33 @@ create_swizzled_clipdist(struct dump_ctx *ctx,
> snprintf(result, 255, "%s(vec4(%s,%s,%s,%s))", stypeprefix,
> clipdistvec[0], clipdistvec[1], clipdistvec[2], clipdistvec[3]);
> }
>
> +static enum vrend_type_qualifier get_coord_prefix(int resource, bool
> *is_ms)
> +{
> + switch(resource) {
> + case TGSI_TEXTURE_1D:
> + case TGSI_TEXTURE_BUFFER:
> + return INT;
> + case TGSI_TEXTURE_2D:
> + case TGSI_TEXTURE_RECT:
> + case TGSI_TEXTURE_1D_ARRAY:
> + return IVEC2;
> + case TGSI_TEXTURE_3D:
> + case TGSI_TEXTURE_CUBE:
> + case TGSI_TEXTURE_2D_ARRAY:
> + case TGSI_TEXTURE_CUBE_ARRAY:
> + return IVEC3;
> + case TGSI_TEXTURE_2D_MSAA:
> + *is_ms = true;
> + return IVEC2;
> + case TGSI_TEXTURE_2D_ARRAY_MSAA:
> + *is_ms = true;
> + return IVEC3;
> + default:
> + fprintf(stderr, "NON 2D IMAGE\n");
> + return TYPE_CONVERSION_NONE;
Nit: 1D and BUFFER are also not "2D IMAGE"
> + }
> +}
> +
> static int
> translate_store(struct dump_ctx *ctx,
> struct tgsi_full_instruction *inst,
> @@ -2153,7 +2228,29 @@ translate_store(struct dump_ctx *ctx,
> const struct tgsi_full_dst_register *dst = &inst->Dst[0];
> char buf[512];
>
> - if (dst->Register.File == TGSI_FILE_BUFFER) {
> + if (dst->Register.File == TGSI_FILE_IMAGE) {
> + bool is_ms = false;
> + enum vrend_type_qualifier coord_prefix = get_coord_prefix(ctx-
> >images[dst->Register.Index].decl.Resource, &is_ms);
> + enum tgsi_return_type itype;
> + char ms_str[32] = {};
> + enum vrend_type_qualifier stypeprefix = TYPE_CONVERSION_NONE;
> + get_internalformat_string(inst->Memory.Format, &itype);
> + if (is_ms) {
> + snprintf(ms_str, 32, "int(%s.w),", srcs[0]);
> + }
> + switch (itype) {
> + case TGSI_RETURN_TYPE_UINT:
> + stypeprefix = FLOAT_BITS_TO_UINT;
> + break;
> + case TGSI_RETURN_TYPE_SINT:
> + stypeprefix = FLOAT_BITS_TO_INT;
> + break;
> + default:
> + break;
> + }
> + snprintf(buf, 512,
> "imageStore(%s,%s(floatBitsToInt(%s)),%s%s(%s));\n", dsts[0],
> get_string(coord_prefix), srcs[0], ms_str, get_string(stypeprefix),
> srcs[1]);
> + EMIT_BUF_WITH_RET(ctx, buf);
> + } else if (dst->Register.File == TGSI_FILE_BUFFER) {
> const char *conversion = get_string(FLOAT_BITS_TO_UINT);
> if (inst->Dst[0].Register.WriteMask & 0x1) {
> snprintf(buf, 255, "%s[uint(floatBitsToUint(%s))>>2] =
> %s(%s).x;\n", dsts[0], srcs[0], conversion, srcs[1]);
> @@ -2178,13 +2275,38 @@ translate_store(struct dump_ctx *ctx,
> static int
> translate_load(struct dump_ctx *ctx,
> struct tgsi_full_instruction *inst,
> + struct source_info *sinfo,
> + struct dest_info *dinfo,
> char srcs[4][255],
> - char dsts[3][255])
> + char dsts[3][255],
> + const char *writemask)
> {
> char buf[512];
> const struct tgsi_full_src_register *src = &inst->Src[0];
> -
> - if (src->Register.File == TGSI_FILE_BUFFER) {
> + if (src->Register.File == TGSI_FILE_IMAGE) {
> + bool is_ms = false;
> + enum vrend_type_qualifier coord_prefix = get_coord_prefix(ctx-
> >images[sinfo->sreg_index].decl.Resource, &is_ms);
> + enum vrend_type_qualifier dtypeprefix = TYPE_CONVERSION_NONE;
> + enum tgsi_return_type itype;
> + get_internalformat_string(ctx->images[sinfo-
> >sreg_index].decl.Format, &itype);
> + char ms_str[32] = {};
> + const char *wm = dinfo->dst_override_no_wm[0] ? "" :
> writemask;
> + if (is_ms) {
> + snprintf(ms_str, 32, ", int(%s.w)", srcs[1]);
> + }
> + switch (itype) {
> + case TGSI_RETURN_TYPE_UINT:
> + dtypeprefix = UINT_BITS_TO_FLOAT;
> + break;
> + case TGSI_RETURN_TYPE_SINT:
> + dtypeprefix = INT_BITS_TO_FLOAT;
> + break;
> + default:
> + break;
> + }
> + snprintf(buf, 255, "%s = %s(imageLoad(%s,
> %s(floatBitsToInt(%s))%s)%s);\n", dsts[0], get_string(dtypeprefix),
> srcs[0], get_string(coord_prefix), srcs[1], ms_str, wm);
> + EMIT_BUF_WITH_RET(ctx, buf);
> + } else if (src->Register.File == TGSI_FILE_BUFFER) {
> char mydst[255], atomic_op[9], atomic_src[10];
> strcpy(mydst, dsts[0]);
> char *wmp = strchr(mydst, '.');
> @@ -2270,7 +2392,11 @@ translate_resq(struct dump_ctx *ctx, struct
> tgsi_full_instruction *inst,
> char buf[512];
> const struct tgsi_full_src_register *src = &inst->Src[0];
>
> - if (src->Register.File == TGSI_FILE_BUFFER) {
> + if (src->Register.File == TGSI_FILE_IMAGE) {
> + ctx->shader_req_bits |= SHADER_REQ_IMAGE_SIZE;
> + snprintf(buf, 255, "%s = %s(imageSize(%s));\n", dsts[0],
> get_string(INT_BITS_TO_FLOAT), srcs[0]);
> + EMIT_BUF_WITH_RET(ctx, buf);
> + } else if (src->Register.File == TGSI_FILE_BUFFER) {
> snprintf(buf, 255, "%s = %s(int(%s.length()) << 2);\n",
> dsts[0], get_string(INT_BITS_TO_FLOAT), srcs[0]);
> EMIT_BUF_WITH_RET(ctx, buf);
> }
> @@ -2281,29 +2407,62 @@ translate_resq(struct dump_ctx *ctx, struct
> tgsi_full_instruction *inst,
> static int
> translate_atomic(struct dump_ctx *ctx,
> struct tgsi_full_instruction *inst,
> + struct source_info *sinfo,
> char srcs[4][255],
> char dsts[3][255])
> {
> char buf[512];
> const struct tgsi_full_src_register *src = &inst->Src[0];
> const char *opname;
> - enum vrend_type_qualifier stypeprefix;
> - enum vrend_type_qualifier dtypeprefix;
> - enum vrend_type_qualifier stypecast;
> + enum vrend_type_qualifier stypeprefix = TYPE_CONVERSION_NONE;
> + enum vrend_type_qualifier dtypeprefix = TYPE_CONVERSION_NONE;
> + enum vrend_type_qualifier stypecast = TYPE_CONVERSION_NONE;
> bool is_cas;
> - char cas_str[64] = {};
> -
> - stypeprefix = FLOAT_BITS_TO_UINT;
> - dtypeprefix = UINT_BITS_TO_FLOAT;
> - stypecast = UINT;
> + char cas_str[128] = {};
> +
> + if (src->Register.File == TGSI_FILE_IMAGE) {
> + enum tgsi_return_type itype;
> + get_internalformat_string(ctx->images[sinfo-
> >sreg_index].decl.Format, &itype);
> + switch (itype) {
> + default:
> + case TGSI_RETURN_TYPE_UINT:
> + stypeprefix = FLOAT_BITS_TO_UINT;
> + dtypeprefix = UINT_BITS_TO_FLOAT;
> + stypecast = UINT;
> + break;
> + case TGSI_RETURN_TYPE_SINT:
> + stypeprefix = FLOAT_BITS_TO_INT;
> + dtypeprefix = INT_BITS_TO_FLOAT;
> + stypecast = INT;
> + break;
> + case TGSI_RETURN_TYPE_FLOAT:
> + ctx->shader_req_bits |= SHADER_REQ_ES31_COMPAT;
> + stypecast = FLOAT;
> + break;
> + }
> + } else {
> + stypeprefix = FLOAT_BITS_TO_UINT;
> + dtypeprefix = UINT_BITS_TO_FLOAT;
> + stypecast = UINT;
> + }
>
> opname = get_atomic_opname(inst->Instruction.Opcode, &is_cas);
> if (!opname)
> return -1;
>
> if (is_cas)
> - snprintf(cas_str, 64, ", %s(%s(%s))", get_string(stypecast),
> get_string(stypeprefix), srcs[3]);
> -
> + snprintf(cas_str, 128, ", %s(%s(%s))", get_string(stypecast),
> get_string(stypeprefix), srcs[3]);
> +
> + if (src->Register.File == TGSI_FILE_IMAGE) {
> + bool is_ms = false;
> + enum vrend_type_qualifier coord_prefix = get_coord_prefix(ctx-
> >images[sinfo->sreg_index].decl.Resource, &is_ms);
> + char ms_str[32] = {};
> + if (is_ms) {
> + snprintf(ms_str, 32, ", int(%s.w)", srcs[1]);
> + }
> + snprintf(buf, 512, "%s = %s(imageAtomic%s(%s,
> %s(floatBitsToInt(%s))%s, %s(%s(%s))%s));\n", dsts[0],
> get_string(dtypeprefix), opname, srcs[0], get_string(coord_prefix),
> srcs[1], ms_str, get_string(stypecast), get_string(stypeprefix),
> srcs[2], cas_str);
> + EMIT_BUF_WITH_RET(ctx, buf);
> + }
> if (src->Register.File == TGSI_FILE_BUFFER) {
> 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);
> @@ -2472,6 +2631,14 @@ get_destination_info(struct dump_ctx *ctx,
> snprintf(dsts[i], 255, "temp%d[addr0 + %d]%s", range-
> >first, dst_reg->Register.Index - range->first, writemask);
> } else
> snprintf(dsts[i], 255, "temp%d[%d]%s", range->first,
> dst_reg->Register.Index - range->first, writemask);
> + }
> + else if (dst_reg->Register.File == TGSI_FILE_IMAGE) {
> + const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
> + if (dst_reg->Register.Indirect) {
> + assert(dst_reg->Indirect.File == TGSI_FILE_ADDRESS);
> + snprintf(dsts[i], 255, "%simg[addr%d + %d]", cname,
> dst_reg->Indirect.Index, dst_reg->Register.Index);
> + } else
> + snprintf(dsts[i], 255, "%simg%d", cname, dst_reg-
> >Register.Index);
> } else if (dst_reg->Register.File == TGSI_FILE_BUFFER) {
> const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
> if (ctx->info.indirect_files & (1 << TGSI_FILE_BUFFER)) {
> @@ -2740,6 +2907,14 @@ get_source_info(struct dump_ctx *ctx,
> snprintf(srcs[i], 255, "%ssamp%d%s", cname, src-
> >Register.Index, swizzle);
> }
> sinfo->sreg_index = src->Register.Index;
> + } else if (src->Register.File == TGSI_FILE_IMAGE) {
> + const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
> + if (ctx->info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
> + snprintf(srcs[i], 255, "%simg%d[addr%d + %d]", cname, 0,
> src->Indirect.Index, src->Register.Index);
> + } else {
> + snprintf(srcs[i], 255, "%simg%d%s", cname, src-
> >Register.Index, swizzle);
> + }
> + sinfo->sreg_index = src->Register.Index;
> } else if (src->Register.File == TGSI_FILE_BUFFER) {
> const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
> if (ctx->info.indirect_files & (1 << TGSI_FILE_BUFFER)) {
> @@ -3490,7 +3665,7 @@ iter_instruction(struct tgsi_iterate_context
> *iter,
> return FALSE;
> break;
> case TGSI_OPCODE_LOAD:
> - ret = translate_load(ctx, inst, srcs, dsts);
> + ret = translate_load(ctx, inst, &sinfo, &dinfo, srcs, dsts,
> writemask);
> if (ret)
> return FALSE;
> break;
> @@ -3504,7 +3679,7 @@ iter_instruction(struct tgsi_iterate_context
> *iter,
> case TGSI_OPCODE_ATOMUMAX:
> case TGSI_OPCODE_ATOMIMIN:
> case TGSI_OPCODE_ATOMIMAX:
> - ret = translate_atomic(ctx, inst, srcs, dsts);
> + ret = translate_atomic(ctx, inst, &sinfo, srcs, dsts);
> if (ret)
> return FALSE;
> break;
> @@ -3715,6 +3890,136 @@ static void *emit_sampler_decl(struct
> dump_ctx *ctx, char *glsl_hdr, uint32_t i,
> return glsl_hdr;
> }
>
> +const char *get_internalformat_string(int virgl_format, enum
> tgsi_return_type *stype)
> +{
> + switch (virgl_format) {
> + case PIPE_FORMAT_R11G11B10_FLOAT:
> + *stype = TGSI_RETURN_TYPE_FLOAT;
> + return "layout(r11f_g11f_b10f) ";
> + case PIPE_FORMAT_R10G10B10A2_UNORM:
> + *stype = TGSI_RETURN_TYPE_UNORM;
> + return "layout(rgb10_a2) ";
> + case PIPE_FORMAT_R10G10B10A2_UINT:
> + *stype = TGSI_RETURN_TYPE_UINT;
> + return "layout(rgb10_a2ui) ";
> + case PIPE_FORMAT_R8_UNORM:
> + *stype = TGSI_RETURN_TYPE_UNORM;
> + return "layout(r8) ";
> + case PIPE_FORMAT_R8_SNORM:
> + *stype = TGSI_RETURN_TYPE_SNORM;
> + return "layout(r8_snorm) ";
> + case PIPE_FORMAT_R8_UINT:
> + *stype = TGSI_RETURN_TYPE_UINT;
> + return "layout(r8ui) ";
> + case PIPE_FORMAT_R8_SINT:
> + *stype = TGSI_RETURN_TYPE_SINT;
> + return "layout(r8i) ";
> + case PIPE_FORMAT_R8G8_UNORM:
> + *stype = TGSI_RETURN_TYPE_UNORM;
> + return "layout(rg8) ";
> + case PIPE_FORMAT_R8G8_SNORM:
> + *stype = TGSI_RETURN_TYPE_SNORM;
> + return "layout(rg8_snorm) ";
> + case PIPE_FORMAT_R8G8_UINT:
> + *stype = TGSI_RETURN_TYPE_UINT;
> + return "layout(rg8ui) ";
> + case PIPE_FORMAT_R8G8_SINT:
> + *stype = TGSI_RETURN_TYPE_SINT;
> + return "layout(rg8i) ";
> + case PIPE_FORMAT_R8G8B8A8_UNORM:
> + *stype = TGSI_RETURN_TYPE_UNORM;
> + return "layout(rgba8) ";
> + case PIPE_FORMAT_R8G8B8A8_SNORM:
> + *stype = TGSI_RETURN_TYPE_SNORM;
> + return "layout(rgba8_snorm) ";
> + case PIPE_FORMAT_R8G8B8A8_UINT:
> + *stype = TGSI_RETURN_TYPE_UINT;
> + return "layout(rgba8ui) ";
> + case PIPE_FORMAT_R8G8B8A8_SINT:
> + *stype = TGSI_RETURN_TYPE_SINT;
> + return "layout(rgba8i) ";
> + case PIPE_FORMAT_R16_UNORM:
> + *stype = TGSI_RETURN_TYPE_UNORM;
> + return "layout(r16) ";
> + case PIPE_FORMAT_R16_SNORM:
> + *stype = TGSI_RETURN_TYPE_SNORM;
> + return "layout(r16_snorm) ";
> + case PIPE_FORMAT_R16_UINT:
> + *stype = TGSI_RETURN_TYPE_UINT;
> + return "layout(r16ui) ";
> + case PIPE_FORMAT_R16_SINT:
> + *stype = TGSI_RETURN_TYPE_SINT;
> + return "layout(r16i) ";
> + case PIPE_FORMAT_R16_FLOAT:
> + *stype = TGSI_RETURN_TYPE_FLOAT;
> + return "layout(r16f) ";
> + case PIPE_FORMAT_R16G16_UNORM:
> + *stype = TGSI_RETURN_TYPE_UNORM;
> + return "layout(rg16) ";
> + case PIPE_FORMAT_R16G16_SNORM:
> + *stype = TGSI_RETURN_TYPE_SNORM;
> + return "layout(rg16_snorm) ";
> + case PIPE_FORMAT_R16G16_UINT:
> + *stype = TGSI_RETURN_TYPE_UINT;
> + return "layout(rg16ui) ";
> + case PIPE_FORMAT_R16G16_SINT:
> + *stype = TGSI_RETURN_TYPE_SINT;
> + return "layout(rg16i) ";
> + case PIPE_FORMAT_R16G16_FLOAT:
> + *stype = TGSI_RETURN_TYPE_FLOAT;
> + return "layout(rg16f) ";
> + case PIPE_FORMAT_R16G16B16A16_UNORM:
> + *stype = TGSI_RETURN_TYPE_UNORM;
> + return "layout(rgba16) ";
> + case PIPE_FORMAT_R16G16B16A16_SNORM:
> + *stype = TGSI_RETURN_TYPE_SNORM;
> + return "layout(rgba16_snorm) ";
> + case PIPE_FORMAT_R16G16B16A16_FLOAT:
> + *stype = TGSI_RETURN_TYPE_FLOAT;
> + return "layout(rgba16f) ";
> + case PIPE_FORMAT_R32_FLOAT:
> + *stype = TGSI_RETURN_TYPE_FLOAT;
> + return "layout(r32f) ";
> + case PIPE_FORMAT_R32_UINT:
> + *stype = TGSI_RETURN_TYPE_UINT;
> + return "layout(r32ui) ";
> + case PIPE_FORMAT_R32_SINT:
> + *stype = TGSI_RETURN_TYPE_SINT;
> + return "layout(r32i) ";
> + case PIPE_FORMAT_R32G32_FLOAT:
> + *stype = TGSI_RETURN_TYPE_FLOAT;
> + return "layout(rg32f) ";
> + case PIPE_FORMAT_R32G32_UINT:
> + *stype = TGSI_RETURN_TYPE_UINT;
> + return "layout(rg32ui) ";
> + case PIPE_FORMAT_R32G32_SINT:
> + *stype = TGSI_RETURN_TYPE_SINT;
> + return "layout(rg32i) ";
> + case PIPE_FORMAT_R32G32B32A32_FLOAT:
> + *stype = TGSI_RETURN_TYPE_FLOAT;
> + return "layout(rgba32f) ";
> + case PIPE_FORMAT_R32G32B32A32_UINT:
> + *stype = TGSI_RETURN_TYPE_UINT;
> + return "layout(rgba32ui) ";
> + case PIPE_FORMAT_R16G16B16A16_UINT:
> + *stype = TGSI_RETURN_TYPE_UINT;
> + return "layout(rgba16ui) ";
> + case PIPE_FORMAT_R16G16B16A16_SINT:
> + *stype = TGSI_RETURN_TYPE_SINT;
> + return "layout(rgba16i) ";
> + case PIPE_FORMAT_R32G32B32A32_SINT:
> + *stype = TGSI_RETURN_TYPE_SINT;
> + return "layout(rgba32i) ";
> + case PIPE_FORMAT_NONE:
> + *stype = TGSI_RETURN_TYPE_UNORM;
> + return "";
> + default:
> + *stype = TGSI_RETURN_TYPE_UNORM;
> + fprintf(stderr, "illegal format %d\n", virgl_format);
> + return "";
> + }
> +}
Wouldn't it be better to add this information to the format table in
vrend_format.c?
> +
> static char *emit_ios(struct dump_ctx *ctx, char *glsl_hdr)
> {
> uint32_t i;
> @@ -4130,6 +4435,56 @@ static char *emit_ios(struct dump_ctx *ctx,
> char *glsl_hdr)
> }
> }
>
> + if (ctx->info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
> + uint32_t mask = ctx->images_used_mask;
> + while (mask) {
> + int is_shad = 0;
> + const char *stc;
> + char ptc;
> + i = u_bit_scan(&mask);
> +
> + unsigned array_size = 0;
> + for (uint32_t j = i; j < util_last_bit(ctx-
> >images_used_mask); j++) {
> + if (!(ctx->images_used_mask & (1 << j)))
> + break;
> + if (!memcmp(&ctx->images[i].decl, &ctx->images[j].decl,
> sizeof(ctx->images[j].decl)) &&
> + ctx->images[i].image_return == ctx-
> >images[j].image_return) {
> + mask &= ~(1 << j);
> + array_size++;
> + }
> + }
Just to confirm: The intention is to add for each unique image an array
of the size corresponding to the number this image declaration is
repeated? (This is probably the point were I would start to write unit
tests to see whether the TGSI produces the GLSL code I really want.)
After staring at the code long enough I think I understand it now, but
adding some comment would go along way ;)
> + const char *volatile_str = (ctx->images[i].vflag) ?
> "volatile " : "";
> + const char *writeonly = (ctx->images[i].decl.Format) ? "" :
> "writeonly ";
> + const char *formatstr;
> + enum tgsi_return_type itype;
> + formatstr = get_internalformat_string(ctx-
> >images[i].decl.Format, &itype);
> + ptc = vrend_shader_samplerreturnconv(itype);
> + sname = tgsi_proc_to_prefix(ctx->prog_type);
> + stc = vrend_shader_samplertypeconv(ctx-
> >images[i].decl.Resource, &is_shad);
> + snprintf(buf, 255, "%s%s%suniform %cimage%s
> %simg%d[%d];\n", formatstr, writeonly, volatile_str, ptc, stc, sname,
> i, array_size);
> + STRCAT_WITH_RET(glsl_hdr, buf);
> + }
> + } else {
> + uint32_t mask = ctx->images_used_mask;
> + while (mask) {
> + int is_shad = 0;
> + const char *stc;
> + char ptc;
> +
> + i = u_bit_scan(&mask);
> + const char *volatile_str = (ctx->images[i].vflag) ?
> "volatile " : "";
> + const char *writeonly = (ctx->images[i].decl.Format) ? "" :
> "writeonly ";
> + const char *formatstr;
> + enum tgsi_return_type itype;
> + formatstr = get_internalformat_string(ctx-
> >images[i].decl.Format, &itype);
> + ptc = vrend_shader_samplerreturnconv(itype);
> + sname = tgsi_proc_to_prefix(ctx->prog_type);
> + stc = vrend_shader_samplertypeconv(ctx-
> >images[i].decl.Resource, &is_shad);
> + snprintf(buf, 255, "%s%s%suniform %cimage%s %simg%d;\n",
> formatstr, writeonly, volatile_str, ptc, stc, sname, i);
> + STRCAT_WITH_RET(glsl_hdr, buf);
> + }
> + }
> +
> if (ctx->info.indirect_files & (1 << TGSI_FILE_BUFFER)) {
> uint32_t mask = ctx->ssbo_used_mask;
> while (mask) {
> @@ -4248,7 +4603,8 @@ char *vrend_convert_shader(struct
> vrend_shader_cfg *cfg,
> if (ctx.info.dimension_indirect_files & (1 <<
> TGSI_FILE_CONSTANT))
> require_glsl_ver(&ctx, 150);
>
> - if (ctx.info.indirect_files & (1 << TGSI_FILE_BUFFER)) {
> + if (ctx.info.indirect_files & (1 << TGSI_FILE_BUFFER) ||
> + ctx.info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
> require_glsl_ver(&ctx, 150);
> ctx.shader_req_bits |= SHADER_REQ_GPU_SHADER5;
> }
> @@ -4300,6 +4656,7 @@ char *vrend_convert_shader(struct
> vrend_shader_cfg *cfg,
> sinfo->num_clip_out = has_prop ? ctx.num_clip_dist_prop :
> (ctx.num_clip_dist ? ctx.num_clip_dist : 8);
> sinfo->num_cull_out = has_prop ? ctx.num_cull_dist_prop : 0;
> sinfo->samplers_used_mask = ctx.samplers_used;
> + sinfo->images_used_mask = ctx.images_used_mask;
> sinfo->num_consts = ctx.num_consts;
> sinfo->num_ubos = ctx.num_ubo;
> memcpy(sinfo->ubo_idx, ctx.ubo_idx, ctx.num_ubo *
> sizeof(*ctx.ubo_idx));
> diff --git a/src/vrend_shader.h b/src/vrend_shader.h
> index a19da20..4b0350a 100644
> --- a/src/vrend_shader.h
> +++ b/src/vrend_shader.h
> @@ -46,6 +46,7 @@ struct vrend_sampler_array {
>
> struct vrend_shader_info {
> uint32_t samplers_used_mask;
> + uint32_t images_used_mask;
> uint32_t ssbo_used_mask;
> int num_consts;
> int num_inputs;
More information about the virglrenderer-devel
mailing list