|
|
|
@ -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); |
|
|
|
|