[virglrenderer-devel] [PATCH 08/12] arb_gpu_shader5: add support for interpolation instructions
Dave Airlie
airlied at gmail.com
Thu May 17 01:54:05 UTC 2018
On 16 May 2018 at 13:42, Gurchetan Singh <gurchetansingh at chromium.org> wrote:
> On Mon, May 14, 2018 at 9:38 PM Dave Airlie <airlied at gmail.com> wrote:
>
>> From: Dave Airlie <airlied at redhat.com>
>
>> ---
>> src/vrend_shader.c | 95
> +++++++++++++++++++++++++++++++++++++++++++++---------
>> src/vrend_shader.h | 1 +
>> 2 files changed, 80 insertions(+), 16 deletions(-)
>
>> diff --git a/src/vrend_shader.c b/src/vrend_shader.c
>> index 2585155..2161766 100644
>> --- a/src/vrend_shader.c
>> +++ b/src/vrend_shader.c
>> @@ -37,7 +37,7 @@ extern int vrend_dump_shaders;
>
>> /* start convert of tgsi to glsl */
>
>> -#define INTERP_PREFIX " "
>> +#define INTERP_PREFIX " "
>> #define INVARI_PREFIX "invariant"
>
>> struct vrend_shader_io {
>> @@ -153,6 +153,7 @@ struct dump_ctx {
>> bool uses_sample_shading;
>> bool uses_gpu_shader5;
>> bool write_mul_temp;
>> + bool write_interp_temp;
>> };
>
>> static inline const char *tgsi_proc_to_prefix(int shader_type)
>> @@ -272,6 +273,7 @@ iter_declaration(struct tgsi_iterate_context *iter,
>> ctx->inputs[i].name = decl->Semantic.Name;
>> ctx->inputs[i].sid = decl->Semantic.Index;
>> ctx->inputs[i].interpolate = decl->Interp.Interpolate;
>> + ctx->inputs[i].centroid = decl->Interp.Location ==
> TGSI_INTERPOLATE_LOC_CENTROID;
>> ctx->inputs[i].first = decl->Range.First;
>> ctx->inputs[i].glsl_predefined_no_emit = false;
>> ctx->inputs[i].glsl_no_index = false;
>> @@ -1632,6 +1634,7 @@ iter_instruction(struct tgsi_iterate_context *iter,
>> bool override_no_wm[4];
>> bool dst_override_no_wm[2];
>> char *sret;
>> + char interpSrc0[255], interpSwizzle0[10];
>> int ret;
>> bool tg4_has_component = false;
>> if (ctx->prog_type == -1)
>> @@ -1812,8 +1815,18 @@ iter_instruction(struct tgsi_iterate_context *iter,
>> if (stype == TGSI_TYPE_UNSIGNED &&
>> ctx->inputs[j].is_int)
>> srcstypeprefix = "";
>> - snprintf(srcs[i], 255, "%s(%s%s%s%s)",
>> - srcstypeprefix, prefix,
> ctx->inputs[j].glsl_name, arrayname, ctx->inputs[j].is_int ? "" : swizzle);
>> +
>> + if (inst->Instruction.Opcode ==
> TGSI_OPCODE_INTERP_SAMPLE && i == 1) {
>> + snprintf(srcs[i], 255, "floatBitsToInt(%s%s%s%s)",
> prefix, ctx->inputs[j].glsl_name, arrayname, swizzle);
>> + }
>
>
>
>
>
>
> else
>> + snprintf(srcs[i], 255, "%s(%s%s%s%s)",
> srcstypeprefix, prefix, ctx->inputs[j].glsl_name, arrayname,
> ctx->inputs[j].is_int ? "" : swizzle);
>> + }
>> + if ((inst->Instruction.Opcode ==
> TGSI_OPCODE_INTERP_SAMPLE ||
>> + inst->Instruction.Opcode ==
> TGSI_OPCODE_INTERP_OFFSET ||
>> + inst->Instruction.Opcode ==
> TGSI_OPCODE_INTERP_CENTROID) &&
>> + i == 0) {
>> + snprintf(interpSrc0, 255, "%s",
> ctx->inputs[j].glsl_name);
>> + snprintf(interpSwizzle0, 10, "%s", swizzle);
>> }
>> override_no_wm[i] = ctx->inputs[j].override_no_wm;
>> break;
>> @@ -1823,6 +1836,11 @@ iter_instruction(struct tgsi_iterate_context *iter,
>> struct vrend_temp_range *range = find_temp_range(ctx,
> src->Register.Index);
>> if (!range)
>> return FALSE;
>> + if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i
> == 1) {
>> + stprefix = true;
>> + stypeprefix = "floatBitsToInt";
>> + }
>> +
>> if (src->Register.Indirect) {
>> snprintf(srcs[i], 255, "%s%c%stemp%d[addr0 + %d]%s%c",
> stypeprefix, stprefix ? '(' : ' ', prefix, range->first,
> src->Register.Index - range->first, swizzle, stprefix ? ')' : ' ');
>> } else
>> @@ -1839,7 +1857,9 @@ iter_instruction(struct tgsi_iterate_context *iter,
>> } else {
>> const char *csp;
>> ctx->has_ints = true;
>> - if (stype == TGSI_TYPE_FLOAT || stype == TGSI_TYPE_UNTYPED)
>> + if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE &&
> i == 1)
>> + csp = "ivec4";
>> + else if (stype == TGSI_TYPE_FLOAT || stype ==
> TGSI_TYPE_UNTYPED)
>> csp = "uintBitsToFloat";
>> else if (stype == TGSI_TYPE_SIGNED)
>> csp = "ivec4";
>> @@ -1866,7 +1886,8 @@ iter_instruction(struct tgsi_iterate_context *iter,
>> const char *vtype = "vec4";
>> const char *imm_stypeprefix = stypeprefix;
>
>> - if ((inst->Instruction.Opcode == TGSI_OPCODE_TG4 && i == 1))
>> + if ((inst->Instruction.Opcode == TGSI_OPCODE_TG4 && i == 1) ||
>> + (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i
> == 1))
>> stype = TGSI_TYPE_SIGNED;
>
>> if (imd->type == TGSI_IMM_UINT32 || imd->type ==
> TGSI_IMM_INT32) {
>> @@ -2343,6 +2364,30 @@ iter_instruction(struct tgsi_iterate_context *iter,
>> EMIT_BUF_WITH_RET(ctx, buf);
>> break;
>> }
>> + case TGSI_OPCODE_INTERP_CENTROID:
>> + snprintf(buf, 255, "interp_temp = interpolateAtCentroid(%s);\n",
> interpSrc0);
>> + EMIT_BUF_WITH_RET(ctx, buf);
>> + snprintf(buf, 255, "%s = %s(%s(interp_temp%s));\n", dsts[0],
> dstconv, dtypeprefix, interpSwizzle0);
>
> Why is an interp_temp needed? Also, shouldn't the destination write-mask
> also work (that's what's used for other functions):
>
> %s = %s(%s(interpolateAtCentroid(%s)%s));\n", dsts[0], dstconv,
> dtypeprefix, srcs[0], writemask);
>
> If that doesn't work, it's probably better to name it src_swizzle[0] if
> other instructions need that information.
GLSL interpolateAt instructions are special in they have some constraints
- they have to take an input (not a temp or other intermediate variable)
- the input size must match the output size, no swizzling or writemasks
So we have to do the GLSL call first (hence interp_temp), then convert
the result to match
what TGSI wants.
Dave.
More information about the virglrenderer-devel
mailing list