From 775e976eba27bab7e99e2decbb4e91f4ac49635c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 23 Sep 2015 18:40:27 +1000 Subject: [PATCH] start ARB_gpu_shader5 support. start handling gpu_shader nonconst gpu_shader5: add invocation id support more of textureGather sm5 --- src/vrend_shader.c | 129 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 101 insertions(+), 28 deletions(-) diff --git a/src/vrend_shader.c b/src/vrend_shader.c index 420bc83..9b4841c 100644 --- a/src/vrend_shader.c +++ b/src/vrend_shader.c @@ -125,6 +125,7 @@ struct dump_ctx { int fs_coord_origin, fs_pixel_center; int gs_in_prim, gs_out_prim, gs_max_out_verts; + int gs_num_invocations; struct vrend_shader_key *key; int indent_level; @@ -142,6 +143,7 @@ struct dump_ctx { bool has_frag_viewport_idx; bool vs_has_pervertex; bool uses_sample_shading; + bool uses_gpu_shader5; }; static inline const char *tgsi_proc_to_prefix(int shader_type) @@ -679,6 +681,10 @@ iter_declaration(struct tgsi_iterate_context *iter, } else if (decl->Semantic.Name == TGSI_SEMANTIC_SAMPLEPOS) { name_prefix = "gl_SamplePosition"; ctx->uses_sample_shading = true; + } else if (decl->Semantic.Name == TGSI_SEMANTIC_INVOCATIONID) { + name_prefix = "gl_InvocationID"; + ctx->has_ints = true; + ctx->uses_gpu_shader5 = true; } else { fprintf(stderr, "unsupported system value %d\n", decl->Semantic.Name); name_prefix = "unknown"; @@ -723,6 +729,10 @@ iter_property(struct tgsi_iterate_context *iter, if (prop->Property.PropertyName == TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES) { ctx->gs_max_out_verts = prop->u[0].Data; } + + if (prop->Property.PropertyName == TGSI_PROPERTY_GS_INVOCATIONS) { + ctx->gs_num_invocations = prop->u[0].Data; + } return TRUE; } @@ -1195,6 +1205,8 @@ static int translate_tex(struct dump_ctx *ctx, case TGSI_TEXTURE_3D: if (inst->Instruction.Opcode == TGSI_OPCODE_TXP) twm = ""; + else if (inst->Instruction.Opcode == TGSI_OPCODE_TG4) + twm = ".xy"; else twm = ".xyz"; txfi = "ivec3"; @@ -1218,7 +1230,10 @@ static int translate_tex(struct dump_ctx *ctx, case TGSI_TEXTURE_SHADOWCUBE_ARRAY: case TGSI_TEXTURE_CUBE_ARRAY: default: - twm = ""; + if (inst->Instruction.Opcode == TGSI_OPCODE_TG4 && inst->Texture.Texture != TGSI_TEXTURE_CUBE_ARRAY) + twm = ".xyz"; + else + twm = ""; txfi = ""; break; } @@ -1273,8 +1288,23 @@ static int translate_tex(struct dump_ctx *ctx, snprintf(bias, 128, ", %s%s, %s%s", srcs[1], gwm, srcs[2], gwm); sampler_index = 3; } else if (inst->Instruction.Opcode == TGSI_OPCODE_TG4) { + sampler_index = 2; ctx->uses_tg4 = true; + if (inst->Texture.NumOffsets > 1 || is_shad) + ctx->uses_gpu_shader5 = true; + if (inst->Texture.NumOffsets == 1) { + if (inst->TexOffsets[0].File != TGSI_FILE_IMMEDIATE) + ctx->uses_gpu_shader5 = true; + } + if (is_shad) { + if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE || + inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY || + inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY) + snprintf(bias, 64, ", %s.w", srcs[0]); + else + snprintf(bias, 64, ", %s.z", srcs[0]); + } } else bias[0] = 0; @@ -1298,7 +1328,9 @@ static int translate_tex(struct dump_ctx *ctx, else tex_ext = "Grad"; } else if (inst->Instruction.Opcode == TGSI_OPCODE_TG4) { - if (inst->Texture.NumOffsets == 1) + if (inst->Texture.NumOffsets == 4) + tex_ext = "GatherOffsets"; + else if (inst->Texture.NumOffsets == 1) tex_ext = "GatherOffset"; else tex_ext = "Gather"; @@ -1314,31 +1346,62 @@ static int translate_tex(struct dump_ctx *ctx, fprintf(stderr, "Immediate exceeded, max is %lu\n", ARRAY_SIZE(ctx->imm)); return false; } - struct immed *imd = &ctx->imm[inst->TexOffsets[0].Index]; - switch (inst->Texture.Texture) { - case TGSI_TEXTURE_1D: - case TGSI_TEXTURE_1D_ARRAY: - case TGSI_TEXTURE_SHADOW1D: - case TGSI_TEXTURE_SHADOW1D_ARRAY: - snprintf(offbuf, 25, ", int(%d)", imd->val[inst->TexOffsets[0].SwizzleX].i); - break; - case TGSI_TEXTURE_RECT: - case TGSI_TEXTURE_SHADOWRECT: - case TGSI_TEXTURE_2D: - case TGSI_TEXTURE_2D_ARRAY: - case TGSI_TEXTURE_SHADOW2D: - case TGSI_TEXTURE_SHADOW2D_ARRAY: - snprintf(offbuf, 25, ", ivec2(%d, %d)", imd->val[inst->TexOffsets[0].SwizzleX].i, imd->val[inst->TexOffsets[0].SwizzleY].i); - break; - case TGSI_TEXTURE_3D: - snprintf(offbuf, 25, ", ivec3(%d, %d, %d)", imd->val[inst->TexOffsets[0].SwizzleX].i, imd->val[inst->TexOffsets[0].SwizzleY].i, - imd->val[inst->TexOffsets[0].SwizzleZ].i); - break; - default: - fprintf(stderr, "unhandled texture: %x\n", inst->Texture.Texture); - return false; + if (inst->TexOffsets[0].File == TGSI_FILE_IMMEDIATE) { + struct immed *imd = &ctx->imm[inst->TexOffsets[0].Index]; + switch (inst->Texture.Texture) { + case TGSI_TEXTURE_1D: + case TGSI_TEXTURE_1D_ARRAY: + case TGSI_TEXTURE_SHADOW1D: + case TGSI_TEXTURE_SHADOW1D_ARRAY: + snprintf(offbuf, 25, ", int(%d)", imd->val[inst->TexOffsets[0].SwizzleX].i); + break; + case TGSI_TEXTURE_RECT: + case TGSI_TEXTURE_SHADOWRECT: + case TGSI_TEXTURE_2D: + case TGSI_TEXTURE_2D_ARRAY: + case TGSI_TEXTURE_SHADOW2D: + case TGSI_TEXTURE_SHADOW2D_ARRAY: + snprintf(offbuf, 25, ", ivec2(%d, %d)", imd->val[inst->TexOffsets[0].SwizzleX].i, imd->val[inst->TexOffsets[0].SwizzleY].i); + break; + case TGSI_TEXTURE_3D: + snprintf(offbuf, 25, ", ivec3(%d, %d, %d)", imd->val[inst->TexOffsets[0].SwizzleX].i, imd->val[inst->TexOffsets[0].SwizzleY].i, + imd->val[inst->TexOffsets[0].SwizzleZ].i); + break; + default: + fprintf(stderr, "unhandled texture: %x\n", inst->Texture.Texture); + return false; + } + } else if (inst->TexOffsets[0].File == TGSI_FILE_TEMPORARY) { + switch (inst->Texture.Texture) { + case TGSI_TEXTURE_1D: + case TGSI_TEXTURE_1D_ARRAY: + case TGSI_TEXTURE_SHADOW1D: + case TGSI_TEXTURE_SHADOW1D_ARRAY: + snprintf(offbuf, 120, ", int(floatBitsToInt(temps[%d].%c))", + inst->TexOffsets[0].Index, get_swiz_char(inst->TexOffsets[0].SwizzleX)); + break; + case TGSI_TEXTURE_RECT: + case TGSI_TEXTURE_SHADOWRECT: + case TGSI_TEXTURE_2D: + case TGSI_TEXTURE_2D_ARRAY: + case TGSI_TEXTURE_SHADOW2D: + case TGSI_TEXTURE_SHADOW2D_ARRAY: + snprintf(offbuf, 120, ", ivec2(floatBitsToInt(temps[%d].%c), floatBitsToInt(temps[%d].%c))", + inst->TexOffsets[0].Index, get_swiz_char(inst->TexOffsets[0].SwizzleX), + inst->TexOffsets[0].Index, get_swiz_char(inst->TexOffsets[0].SwizzleY)); + break; + case TGSI_TEXTURE_3D: + snprintf(offbuf, 120, ", ivec2(floatBitsToInt(temps[%d].%c), floatBitsToInt(temps[%d].%c), floatBitsToInt(temps[%d].%c)", + inst->TexOffsets[0].Index, get_swiz_char(inst->TexOffsets[0].SwizzleX), + inst->TexOffsets[0].Index, get_swiz_char(inst->TexOffsets[0].SwizzleY), + inst->TexOffsets[0].Index, get_swiz_char(inst->TexOffsets[0].SwizzleZ)); + break; + default: + fprintf(stderr, "unhandled texture: %x\n", inst->Texture.Texture); + return false; + break; + } } - if (inst->Instruction.Opcode == TGSI_OPCODE_TXL || inst->Instruction.Opcode == TGSI_OPCODE_TXL2 || inst->Instruction.Opcode == TGSI_OPCODE_TXD) { char tmp[128]; strcpy(tmp, offbuf); @@ -1355,7 +1418,7 @@ static int translate_tex(struct dump_ctx *ctx, snprintf(buf, 255, "%s = texture2DRect(%s, %s.xy)%s;\n", dsts[0], srcs[sampler_index], srcs[0], writemask); else if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWRECT) snprintf(buf, 255, "%s = shadow2DRect(%s, %s.xyz)%s;\n", dsts[0], srcs[sampler_index], srcs[0], writemask); - } else if (is_shad) { /* TGSI returns 1.0 in alpha */ + } else if (is_shad && inst->Instruction.Opcode != TGSI_OPCODE_TG4) { /* TGSI returns 1.0 in alpha */ const char *cname = tgsi_proc_to_prefix(ctx->prog_type); const struct tgsi_full_src_register *src = &inst->Src[sampler_index]; snprintf(buf, 255, "%s = %s(%s(vec4(vec4(texture%s(%s, %s%s%s%s)) * %sshadmask%d + %sshadadd%d)%s));\n", dsts[0], dstconv, dtypeprefix, tex_ext, srcs[sampler_index], srcs[0], twm, offbuf, bias, cname, src->Register.Index, cname, src->Register.Index, writemask); @@ -1683,6 +1746,7 @@ iter_instruction(struct tgsi_iterate_context *iter, if (ctx->system_values[j].first == src->Register.Index) { if (ctx->system_values[j].name == TGSI_SEMANTIC_VERTEXID || ctx->system_values[j].name == TGSI_SEMANTIC_INSTANCEID || + ctx->system_values[j].name == TGSI_SEMANTIC_INVOCATIONID || ctx->system_values[j].name == TGSI_SEMANTIC_SAMPLEID) snprintf(srcs[i], 255, "%s(vec4(intBitsToFloat(%s)))", stypeprefix, ctx->system_values[j].glsl_name); else if (ctx->system_values[j].name == TGSI_SEMANTIC_SAMPLEPOS) { @@ -2173,6 +2237,9 @@ static char *emit_header(struct dump_ctx *ctx, char *glsl_hdr) STRCAT_WITH_RET(glsl_hdr, "#extension GL_ARB_fragment_layer_viewport : require\n"); if (ctx->uses_sample_shading) STRCAT_WITH_RET(glsl_hdr, "#extension GL_ARB_sample_shading : require\n"); + if (ctx->uses_gpu_shader5) + STRCAT_WITH_RET(glsl_hdr, "#extension GL_ARB_gpu_shader5 : require\n"); + return glsl_hdr; } @@ -2261,7 +2328,13 @@ static char *emit_ios(struct dump_ctx *ctx, char *glsl_hdr) } } if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY) { - snprintf(buf, 255, "layout(%s) in;\n", prim_to_name(ctx->gs_in_prim)); + char invocbuf[25]; + + if (ctx->gs_num_invocations) + snprintf(invocbuf, 25, ", invocations = %d", ctx->gs_num_invocations); + + snprintf(buf, 255, "layout(%s%s) in;\n", prim_to_name(ctx->gs_in_prim), + ctx->gs_num_invocations > 1 ? invocbuf : ""); STRCAT_WITH_RET(glsl_hdr, buf); snprintf(buf, 255, "layout(%s, max_vertices = %d) out;\n", prim_to_name(ctx->gs_out_prim), ctx->gs_max_out_verts); STRCAT_WITH_RET(glsl_hdr, buf);