vrend_shader: add arb_gpu_shader_fp64 support (v2)

This is a basic step towards GL4.0 and greater,
add support for the FP64 extension.

This requires ARB_gpu_shader5 on the host, to
implement ldexp using bitfieldInsert.

v2: drop fp64_srcs into local var
fix imul regression due to rebase

Signed-off-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
macos/master
Dave Airlie 9 years ago
parent fa9cd7c971
commit b98ea3d919
  1. 4
      src/gallium/auxiliary/tgsi/tgsi_info.c
  2. 1
      src/gallium/auxiliary/tgsi/tgsi_parse.c
  3. 3
      src/gallium/auxiliary/tgsi/tgsi_sanity.c
  4. 8
      src/gallium/auxiliary/tgsi/tgsi_text.c
  5. 3
      src/gallium/include/pipe/p_shader_tokens.h
  6. 5
      src/vrend_renderer.c
  7. 152
      src/vrend_shader.c

@ -262,6 +262,7 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
{ 1, 1, 0, 0, 0, 0, COMP, "DFLR", TGSI_OPCODE_DFLR }, { 1, 1, 0, 0, 0, 0, COMP, "DFLR", TGSI_OPCODE_DFLR },
{ 1, 1, 0, 0, 0, 0, COMP, "DROUND", TGSI_OPCODE_DROUND }, { 1, 1, 0, 0, 0, 0, COMP, "DROUND", TGSI_OPCODE_DROUND },
{ 1, 1, 0, 0, 0, 0, COMP, "DSSG", TGSI_OPCODE_DSSG }, { 1, 1, 0, 0, 0, 0, COMP, "DSSG", TGSI_OPCODE_DSSG },
{ 1, 2, 0, 0, 0, 0, COMP, "DDIV", TGSI_OPCODE_DDIV }
}; };
const struct tgsi_opcode_info * const struct tgsi_opcode_info *
@ -352,6 +353,7 @@ tgsi_opcode_infer_type( uint opcode )
case TGSI_OPCODE_POPC: case TGSI_OPCODE_POPC:
case TGSI_OPCODE_LSB: case TGSI_OPCODE_LSB:
case TGSI_OPCODE_UMSB: case TGSI_OPCODE_UMSB:
case TGSI_OPCODE_D2U:
return TGSI_TYPE_UNSIGNED; return TGSI_TYPE_UNSIGNED;
case TGSI_OPCODE_ARL: case TGSI_OPCODE_ARL:
case TGSI_OPCODE_ARR: case TGSI_OPCODE_ARR:
@ -379,6 +381,7 @@ tgsi_opcode_infer_type( uint opcode )
case TGSI_OPCODE_DSGE: case TGSI_OPCODE_DSGE:
case TGSI_OPCODE_DSLT: case TGSI_OPCODE_DSLT:
case TGSI_OPCODE_DSNE: case TGSI_OPCODE_DSNE:
case TGSI_OPCODE_D2I:
return TGSI_TYPE_SIGNED; return TGSI_TYPE_SIGNED;
case TGSI_OPCODE_DADD: case TGSI_OPCODE_DADD:
case TGSI_OPCODE_DABS: case TGSI_OPCODE_DABS:
@ -399,6 +402,7 @@ tgsi_opcode_infer_type( uint opcode )
case TGSI_OPCODE_DFLR: case TGSI_OPCODE_DFLR:
case TGSI_OPCODE_DROUND: case TGSI_OPCODE_DROUND:
case TGSI_OPCODE_DSSG: case TGSI_OPCODE_DSSG:
case TGSI_OPCODE_DDIV:
case TGSI_OPCODE_F2D: case TGSI_OPCODE_F2D:
case TGSI_OPCODE_I2D: case TGSI_OPCODE_I2D:
case TGSI_OPCODE_U2D: case TGSI_OPCODE_U2D:

@ -154,6 +154,7 @@ tgsi_parse_token(
break; break;
case TGSI_IMM_UINT32: case TGSI_IMM_UINT32:
case TGSI_IMM_FLOAT64:
for (i = 0; i < imm_count; i++) { for (i = 0; i < imm_count; i++) {
next_token(ctx, &imm->u[i].Uint); next_token(ctx, &imm->u[i].Uint);
} }

@ -454,7 +454,8 @@ iter_immediate(
*/ */
if (imm->Immediate.DataType != TGSI_IMM_FLOAT32 && if (imm->Immediate.DataType != TGSI_IMM_FLOAT32 &&
imm->Immediate.DataType != TGSI_IMM_UINT32 && imm->Immediate.DataType != TGSI_IMM_UINT32 &&
imm->Immediate.DataType != TGSI_IMM_INT32) { imm->Immediate.DataType != TGSI_IMM_INT32 &&
imm->Immediate.DataType != TGSI_IMM_FLOAT64) {
report_error( ctx, "(%u): Invalid immediate data type", imm->Immediate.DataType ); report_error( ctx, "(%u): Invalid immediate data type", imm->Immediate.DataType );
return TRUE; return TRUE;
} }

@ -260,6 +260,14 @@ static boolean parse_double( const char **pcur, uint32_t *val0, uint32_t *val1)
uint32_t uval[2]; uint32_t uval[2];
} v; } v;
if (*cur == '0' && *(cur + 1) == 'x') {
*val0 = strtoul(cur, NULL, 16);
cur += 11;
*val1 = strtoul(cur, NULL, 16);
cur += 11;
*pcur = cur;
return TRUE;
}
v.dval = strtod(cur, (char**)pcur); v.dval = strtod(cur, (char**)pcur);
if (*pcur == cur) if (*pcur == cur)
return FALSE; return FALSE;

@ -547,7 +547,8 @@ struct tgsi_property_data {
#define TGSI_OPCODE_DFLR 220 /* nvc0 */ #define TGSI_OPCODE_DFLR 220 /* nvc0 */
#define TGSI_OPCODE_DROUND 221 /* nvc0 */ #define TGSI_OPCODE_DROUND 221 /* nvc0 */
#define TGSI_OPCODE_DSSG 222 #define TGSI_OPCODE_DSSG 222
#define TGSI_OPCODE_LAST 223 #define TGSI_OPCODE_DDIV 223
#define TGSI_OPCODE_LAST 224
/** /**
* Opcode is the operation code to execute. A given operation defines the * Opcode is the operation code to execute. A given operation defines the

@ -6972,6 +6972,7 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
caps->v1.bset.texture_query_lod = 1; caps->v1.bset.texture_query_lod = 1;
caps->v1.bset.has_indirect_draw = 1; caps->v1.bset.has_indirect_draw = 1;
caps->v1.bset.has_sample_shading = 1; caps->v1.bset.has_sample_shading = 1;
caps->v1.bset.has_fp64 = 1;
} else { } else {
if (epoxy_has_gl_extension("GL_ARB_draw_buffers_blend")) if (epoxy_has_gl_extension("GL_ARB_draw_buffers_blend"))
caps->v1.bset.indep_blend_func = 1; caps->v1.bset.indep_blend_func = 1;
@ -6983,6 +6984,10 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
caps->v1.bset.has_indirect_draw = 1; caps->v1.bset.has_indirect_draw = 1;
if (epoxy_has_gl_extension("GL_ARB_sample_shading")) if (epoxy_has_gl_extension("GL_ARB_sample_shading"))
caps->v1.bset.has_sample_shading = 1; caps->v1.bset.has_sample_shading = 1;
/* need gpu shader 5 for bitfield insert */
if (epoxy_has_gl_extension("GL_ARB_gpu_shader_fp64") &&
epoxy_has_gl_extension("GL_ARB_gpu_shader5"))
caps->v1.bset.has_fp64 = 1;
} }
if (gl_ver >= 42) { if (gl_ver >= 42) {

@ -55,6 +55,7 @@ extern int vrend_dump_shaders;
#define SHADER_REQ_SAMPLE_SHADING (1 << 11) #define SHADER_REQ_SAMPLE_SHADING (1 << 11)
#define SHADER_REQ_GPU_SHADER5 (1 << 12) #define SHADER_REQ_GPU_SHADER5 (1 << 12)
#define SHADER_REQ_DERIVATIVE_CONTROL (1 << 13) #define SHADER_REQ_DERIVATIVE_CONTROL (1 << 13)
#define SHADER_REQ_FP64 (1 << 14)
struct vrend_shader_io { struct vrend_shader_io {
unsigned name; unsigned name;
@ -183,6 +184,7 @@ static const struct vrend_shader_table shader_req_table[] = {
{ SHADER_REQ_SAMPLE_SHADING, "GL_ARB_sample_shading" }, { SHADER_REQ_SAMPLE_SHADING, "GL_ARB_sample_shading" },
{ SHADER_REQ_GPU_SHADER5, "GL_ARB_gpu_shader5" }, { SHADER_REQ_GPU_SHADER5, "GL_ARB_gpu_shader5" },
{ SHADER_REQ_DERIVATIVE_CONTROL, "GL_ARB_derivative_control" }, { SHADER_REQ_DERIVATIVE_CONTROL, "GL_ARB_derivative_control" },
{ SHADER_REQ_FP64, "GL_ARB_gpu_shader_fp64" },
}; };
enum vrend_type_qualifier { enum vrend_type_qualifier {
@ -203,6 +205,8 @@ enum vrend_type_qualifier {
UINT_BITS_TO_FLOAT = 14, UINT_BITS_TO_FLOAT = 14,
FLOAT_BITS_TO_INT = 15, FLOAT_BITS_TO_INT = 15,
INT_BITS_TO_FLOAT = 16, INT_BITS_TO_FLOAT = 16,
DOUBLE = 17,
DVEC2 = 18,
}; };
static const struct vrend_shader_table conversion_table[] = static const struct vrend_shader_table conversion_table[] =
@ -224,6 +228,8 @@ static const struct vrend_shader_table conversion_table[] =
{UINT_BITS_TO_FLOAT, "uintBitsToFloat"}, {UINT_BITS_TO_FLOAT, "uintBitsToFloat"},
{FLOAT_BITS_TO_INT, "floatBitsToInt"}, {FLOAT_BITS_TO_INT, "floatBitsToInt"},
{INT_BITS_TO_FLOAT, "intBitsToFloat"}, {INT_BITS_TO_FLOAT, "intBitsToFloat"},
{DOUBLE, "double"},
{DVEC2, "dvec2"},
}; };
static inline const char *get_string(enum vrend_type_qualifier key) static inline const char *get_string(enum vrend_type_qualifier key)
@ -965,7 +971,8 @@ iter_immediate(
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (imm->Immediate.DataType == TGSI_IMM_FLOAT32) { if (imm->Immediate.DataType == TGSI_IMM_FLOAT32) {
ctx->imm[first].val[i].f = imm->u[i].Float; ctx->imm[first].val[i].f = imm->u[i].Float;
} else if (imm->Immediate.DataType == TGSI_IMM_UINT32) { } else if (imm->Immediate.DataType == TGSI_IMM_UINT32 ||
imm->Immediate.DataType == TGSI_IMM_FLOAT64) {
ctx->shader_req_bits |= SHADER_REQ_INTS; ctx->shader_req_bits |= SHADER_REQ_INTS;
ctx->imm[first].val[i].ui = imm->u[i].Uint; ctx->imm[first].val[i].ui = imm->u[i].Uint;
} else if (imm->Immediate.DataType == TGSI_IMM_INT32) { } else if (imm->Immediate.DataType == TGSI_IMM_INT32) {
@ -1843,6 +1850,7 @@ struct dest_info {
enum vrend_type_qualifier dtypeprefix; enum vrend_type_qualifier dtypeprefix;
enum vrend_type_qualifier dstconv; enum vrend_type_qualifier dstconv;
enum vrend_type_qualifier udstconv; enum vrend_type_qualifier udstconv;
enum vrend_type_qualifier idstconv;
bool dst_override_no_wm[2]; bool dst_override_no_wm[2];
}; };
@ -1851,6 +1859,7 @@ get_destination_info(struct dump_ctx *ctx,
const struct tgsi_full_instruction *inst, const struct tgsi_full_instruction *inst,
struct dest_info *dinfo, struct dest_info *dinfo,
char dsts[3][255], char dsts[3][255],
char fp64_dsts[3][255],
char *writemask) char *writemask)
{ {
const struct tgsi_full_dst_register *dst_reg; const struct tgsi_full_dst_register *dst_reg;
@ -1859,6 +1868,11 @@ get_destination_info(struct dump_ctx *ctx,
if (dtype == TGSI_TYPE_SIGNED || dtype == TGSI_TYPE_UNSIGNED) if (dtype == TGSI_TYPE_SIGNED || dtype == TGSI_TYPE_UNSIGNED)
ctx->shader_req_bits |= SHADER_REQ_INTS; ctx->shader_req_bits |= SHADER_REQ_INTS;
if (dtype == TGSI_TYPE_DOUBLE) {
/* we need the uvec2 conversion for doubles */
ctx->shader_req_bits |= SHADER_REQ_INTS | SHADER_REQ_FP64;
}
if (inst->Instruction.Opcode == TGSI_OPCODE_TXQ) { if (inst->Instruction.Opcode == TGSI_OPCODE_TXQ) {
dinfo->dtypeprefix = INT_BITS_TO_FLOAT; dinfo->dtypeprefix = INT_BITS_TO_FLOAT;
} else { } else {
@ -1875,11 +1889,14 @@ get_destination_info(struct dump_ctx *ctx,
} }
for (uint32_t i = 0; i < inst->Instruction.NumDstRegs; i++) { for (uint32_t i = 0; i < inst->Instruction.NumDstRegs; i++) {
char fp64_writemask[6] = {0};
dst_reg = &inst->Dst[i]; dst_reg = &inst->Dst[i];
dinfo->dst_override_no_wm[i] = false; dinfo->dst_override_no_wm[i] = false;
if (dst_reg->Register.WriteMask != TGSI_WRITEMASK_XYZW) { if (dst_reg->Register.WriteMask != TGSI_WRITEMASK_XYZW) {
int wm_idx = 0; int wm_idx = 0, dbl_wm_idx = 0;
writemask[wm_idx++] = '.'; writemask[wm_idx++] = '.';
fp64_writemask[dbl_wm_idx++] = '.';
if (dst_reg->Register.WriteMask & 0x1) if (dst_reg->Register.WriteMask & 0x1)
writemask[wm_idx++] = 'x'; writemask[wm_idx++] = 'x';
if (dst_reg->Register.WriteMask & 0x2) if (dst_reg->Register.WriteMask & 0x2)
@ -1889,11 +1906,30 @@ get_destination_info(struct dump_ctx *ctx,
if (dst_reg->Register.WriteMask & 0x8) if (dst_reg->Register.WriteMask & 0x8)
writemask[wm_idx++] = 'w'; writemask[wm_idx++] = 'w';
if (dtype == TGSI_TYPE_DOUBLE) {
if (dst_reg->Register.WriteMask & 0x3)
fp64_writemask[dbl_wm_idx++] = 'x';
if (dst_reg->Register.WriteMask & 0xc)
fp64_writemask[dbl_wm_idx++] = 'y';
}
if (dtype == TGSI_TYPE_DOUBLE) {
if (dbl_wm_idx == 2)
dinfo->dstconv = DOUBLE;
else
dinfo->dstconv = DVEC2;
} else {
dinfo->dstconv = FLOAT + wm_idx - 2; dinfo->dstconv = FLOAT + wm_idx - 2;
dinfo->udstconv = UINT + wm_idx - 2; dinfo->udstconv = UINT + wm_idx - 2;
dinfo->idstconv = INT + wm_idx - 2;
}
} else { } else {
if (dtype == TGSI_TYPE_DOUBLE)
dinfo->dstconv = DVEC2;
else
dinfo->dstconv = VEC4; dinfo->dstconv = VEC4;
dinfo->udstconv = UVEC4; dinfo->udstconv = UVEC4;
dinfo->idstconv = IVEC4;
} }
if (dst_reg->Register.File == TGSI_FILE_OUTPUT) { if (dst_reg->Register.File == TGSI_FILE_OUTPUT) {
@ -1947,6 +1983,13 @@ get_destination_info(struct dump_ctx *ctx,
else if (dst_reg->Register.File == TGSI_FILE_ADDRESS) { else if (dst_reg->Register.File == TGSI_FILE_ADDRESS) {
snprintf(dsts[i], 255, "addr%d", dst_reg->Register.Index); snprintf(dsts[i], 255, "addr%d", dst_reg->Register.Index);
} }
if (dtype == TGSI_TYPE_DOUBLE) {
strcpy(fp64_dsts[i], dsts[i]);
snprintf(dsts[i], 255, "fp64_dst[%d]%s", i, fp64_writemask);
writemask[0] = 0;
}
} }
return 0; return 0;
@ -1972,8 +2015,15 @@ get_source_info(struct dump_ctx *ctx,
if (stype == TGSI_TYPE_SIGNED || stype == TGSI_TYPE_UNSIGNED) if (stype == TGSI_TYPE_SIGNED || stype == TGSI_TYPE_UNSIGNED)
ctx->shader_req_bits |= SHADER_REQ_INTS; ctx->shader_req_bits |= SHADER_REQ_INTS;
if (stype == TGSI_TYPE_DOUBLE)
ctx->shader_req_bits |= SHADER_REQ_INTS | SHADER_REQ_FP64;
switch (stype) { switch (stype) {
case TGSI_TYPE_DOUBLE:
stypeprefix = FLOAT_BITS_TO_UINT;
sinfo->svec4 = DVEC2;
stprefix = true;
break;
case TGSI_TYPE_UNSIGNED: case TGSI_TYPE_UNSIGNED:
stypeprefix = FLOAT_BITS_TO_UINT; stypeprefix = FLOAT_BITS_TO_UINT;
sinfo->svec4 = UVEC4; sinfo->svec4 = UVEC4;
@ -1993,16 +2043,17 @@ get_source_info(struct dump_ctx *ctx,
char swizzle[8] = {0}; char swizzle[8] = {0};
char prefix[6] = {0}; char prefix[6] = {0};
char arrayname[16] = {0}; char arrayname[16] = {0};
char fp64_src[255];
int swz_idx = 0, pre_idx = 0; int swz_idx = 0, pre_idx = 0;
boolean isabsolute = src->Register.Absolute; boolean isfloatabsolute = src->Register.Absolute && stype != TGSI_TYPE_DOUBLE;
sinfo->override_no_wm[i] = false; sinfo->override_no_wm[i] = false;
if (isabsolute) if (isfloatabsolute)
swizzle[swz_idx++] = ')'; swizzle[swz_idx++] = ')';
if (src->Register.Negate) if (src->Register.Negate)
prefix[pre_idx++] = '-'; prefix[pre_idx++] = '-';
if (isabsolute) if (isfloatabsolute)
strcpy(&prefix[pre_idx++], "abs("); strcpy(&prefix[pre_idx++], "abs(");
if (src->Register.Dimension) { if (src->Register.Dimension) {
@ -2165,6 +2216,12 @@ get_source_info(struct dump_ctx *ctx,
imm_stypeprefix = UINT_BITS_TO_FLOAT; imm_stypeprefix = UINT_BITS_TO_FLOAT;
} else if (stype == TGSI_TYPE_UNSIGNED || stype == TGSI_TYPE_SIGNED) } else if (stype == TGSI_TYPE_UNSIGNED || stype == TGSI_TYPE_SIGNED)
imm_stypeprefix = TYPE_CONVERSION_NONE; imm_stypeprefix = TYPE_CONVERSION_NONE;
} else if (imd->type == TGSI_IMM_FLOAT64) {
vtype = UVEC4;
if (stype == TGSI_TYPE_DOUBLE)
imm_stypeprefix = TYPE_CONVERSION_NONE;
else
imm_stypeprefix = UINT_BITS_TO_FLOAT;
} }
/* build up a vec4 of immediates */ /* build up a vec4 of immediates */
@ -2200,6 +2257,9 @@ get_source_info(struct dump_ctx *ctx,
case TGSI_IMM_INT32: case TGSI_IMM_INT32:
snprintf(temp, 25, "%d", imd->val[idx].i); snprintf(temp, 25, "%d", imd->val[idx].i);
break; break;
case TGSI_IMM_FLOAT64:
snprintf(temp, 48, "%uU", imd->val[idx].ui);
break;
default: default:
fprintf(stderr, "unhandled imm type: %x\n", imd->type); fprintf(stderr, "unhandled imm type: %x\n", imd->type);
return false; return false;
@ -2208,7 +2268,7 @@ get_source_info(struct dump_ctx *ctx,
if (j < 3) if (j < 3)
strcat(srcs[i], ","); strcat(srcs[i], ",");
else { else {
snprintf(temp, 4, "))%c", isabsolute ? ')' : 0); snprintf(temp, 4, "))%c", isfloatabsolute ? ')' : 0);
strncat(srcs[i], temp, 255); strncat(srcs[i], temp, 255);
} }
} }
@ -2232,6 +2292,15 @@ get_source_info(struct dump_ctx *ctx,
break; break;
} }
} }
if (stype == TGSI_TYPE_DOUBLE) {
boolean isabsolute = src->Register.Absolute;
char buf[512];
strcpy(fp64_src, srcs[i]);
snprintf(srcs[i], 255, "fp64_src[%d]", i);
snprintf(buf, 255, "%s.x = %spackDouble2x32(uvec2(%s%s))%s;\n", srcs[i], isabsolute ? "abs(" : "", fp64_src, swizzle, isabsolute ? ")" : "");
EMIT_BUF_WITH_RET(ctx, buf);
}
} }
return 0; return 0;
@ -2245,6 +2314,7 @@ iter_instruction(struct tgsi_iterate_context *iter,
struct dest_info dinfo = { 0 }; struct dest_info dinfo = { 0 };
struct source_info sinfo = { 0 }; struct source_info sinfo = { 0 };
char srcs[4][255], dsts[3][255], buf[512]; char srcs[4][255], dsts[3][255], buf[512];
char fp64_dsts[3][255];
uint instno = ctx->instno++; uint instno = ctx->instno++;
char writemask[6] = {0}; char writemask[6] = {0};
char *sret; char *sret;
@ -2269,7 +2339,7 @@ iter_instruction(struct tgsi_iterate_context *iter,
prepare_so_movs(ctx); prepare_so_movs(ctx);
} }
ret = get_destination_info(ctx, inst, &dinfo, dsts, writemask); ret = get_destination_info(ctx, inst, &dinfo, dsts, fp64_dsts, writemask);
if (ret) if (ret)
return FALSE; return FALSE;
@ -2279,6 +2349,7 @@ iter_instruction(struct tgsi_iterate_context *iter,
switch (inst->Instruction.Opcode) { switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_SQRT: case TGSI_OPCODE_SQRT:
case TGSI_OPCODE_DSQRT:
snprintf(buf, 255, "%s = sqrt(vec4(%s))%s;\n", dsts[0], srcs[0], writemask); snprintf(buf, 255, "%s = sqrt(vec4(%s))%s;\n", dsts[0], srcs[0], writemask);
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
@ -2303,12 +2374,14 @@ iter_instruction(struct tgsi_iterate_context *iter,
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_MAX: case TGSI_OPCODE_MAX:
case TGSI_OPCODE_DMAX:
case TGSI_OPCODE_IMAX: case TGSI_OPCODE_IMAX:
case TGSI_OPCODE_UMAX: case TGSI_OPCODE_UMAX:
snprintf(buf, 255, "%s = %s(%s(max(%s, %s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1]); snprintf(buf, 255, "%s = %s(%s(max(%s, %s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1]);
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_MIN: case TGSI_OPCODE_MIN:
case TGSI_OPCODE_DMIN:
case TGSI_OPCODE_IMIN: case TGSI_OPCODE_IMIN:
case TGSI_OPCODE_UMIN: case TGSI_OPCODE_UMIN:
snprintf(buf, 255, "%s = %s(%s(min(%s, %s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1]); snprintf(buf, 255, "%s = %s(%s(min(%s, %s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1]);
@ -2316,6 +2389,7 @@ iter_instruction(struct tgsi_iterate_context *iter,
break; break;
case TGSI_OPCODE_ABS: case TGSI_OPCODE_ABS:
case TGSI_OPCODE_IABS: case TGSI_OPCODE_IABS:
case TGSI_OPCODE_DABS:
emit_op1("abs"); emit_op1("abs");
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
@ -2404,6 +2478,10 @@ iter_instruction(struct tgsi_iterate_context *iter,
snprintf(buf, 255, "%s = %s(1.0/(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]); snprintf(buf, 255, "%s = %s(1.0/(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_DRCP:
snprintf(buf, 255, "%s = %s(1.0LF/(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
EMIT_BUF_WITH_RET(ctx, buf);
break;
case TGSI_OPCODE_FLR: case TGSI_OPCODE_FLR:
emit_op1("floor"); emit_op1("floor");
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
@ -2421,6 +2499,7 @@ iter_instruction(struct tgsi_iterate_context *iter,
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_FRC: case TGSI_OPCODE_FRC:
case TGSI_OPCODE_DFRAC:
emit_op1("fract"); emit_op1("fract");
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
@ -2433,6 +2512,7 @@ iter_instruction(struct tgsi_iterate_context *iter,
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_RSQ: case TGSI_OPCODE_RSQ:
case TGSI_OPCODE_DRSQ:
snprintf(buf, 255, "%s = %s(inversesqrt(%s.x));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]); snprintf(buf, 255, "%s = %s(inversesqrt(%s.x));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
@ -2441,6 +2521,7 @@ iter_instruction(struct tgsi_iterate_context *iter,
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_ADD: case TGSI_OPCODE_ADD:
case TGSI_OPCODE_DADD:
emit_arit_op2("+"); emit_arit_op2("+");
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
@ -2453,10 +2534,12 @@ iter_instruction(struct tgsi_iterate_context *iter,
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_MUL: case TGSI_OPCODE_MUL:
case TGSI_OPCODE_DMUL:
emit_arit_op2("*"); emit_arit_op2("*");
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_DIV: case TGSI_OPCODE_DIV:
case TGSI_OPCODE_DDIV:
emit_arit_op2("/"); emit_arit_op2("/");
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
@ -2490,6 +2573,7 @@ iter_instruction(struct tgsi_iterate_context *iter,
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_UMAD: case TGSI_OPCODE_UMAD:
case TGSI_OPCODE_DMAD:
snprintf(buf, 255, "%s = %s(%s((%s * %s + %s)%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], srcs[2], writemask); snprintf(buf, 255, "%s = %s(%s((%s * %s + %s)%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], srcs[2], writemask);
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
@ -2533,18 +2617,42 @@ iter_instruction(struct tgsi_iterate_context *iter,
snprintf(buf, 255, "%s = %s(ivec4(%s)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], writemask); snprintf(buf, 255, "%s = %s(ivec4(%s)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], writemask);
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_I2D:
snprintf(buf, 255, "%s = %s(ivec4(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
EMIT_BUF_WITH_RET(ctx, buf);
break;
case TGSI_OPCODE_D2F:
snprintf(buf, 255, "%s = %s(%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
EMIT_BUF_WITH_RET(ctx, buf);
break;
case TGSI_OPCODE_U2F: case TGSI_OPCODE_U2F:
snprintf(buf, 255, "%s = %s(uvec4(%s)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], writemask); snprintf(buf, 255, "%s = %s(uvec4(%s)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], writemask);
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_U2D:
snprintf(buf, 255, "%s = %s(uvec4(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
EMIT_BUF_WITH_RET(ctx, buf);
break;
case TGSI_OPCODE_F2I: case TGSI_OPCODE_F2I:
snprintf(buf, 255, "%s = %s(%s(ivec4(%s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], writemask); snprintf(buf, 255, "%s = %s(%s(ivec4(%s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], writemask);
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_D2I:
snprintf(buf, 255, "%s = %s(%s(%s(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), get_string(dinfo.idstconv), srcs[0]);
EMIT_BUF_WITH_RET(ctx, buf);
break;
case TGSI_OPCODE_F2U: case TGSI_OPCODE_F2U:
snprintf(buf, 255, "%s = %s(%s(uvec4(%s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], writemask); snprintf(buf, 255, "%s = %s(%s(uvec4(%s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], writemask);
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_D2U:
snprintf(buf, 255, "%s = %s(%s(%s(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), get_string(dinfo.udstconv), srcs[0]);
EMIT_BUF_WITH_RET(ctx, buf);
break;
case TGSI_OPCODE_F2D:
snprintf(buf, 255, "%s = %s(%s(%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
EMIT_BUF_WITH_RET(ctx, buf);
break;
case TGSI_OPCODE_NOT: case TGSI_OPCODE_NOT:
snprintf(buf, 255, "%s = %s(uintBitsToFloat(~(uvec4(%s))));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]); snprintf(buf, 255, "%s = %s(uintBitsToFloat(~(uvec4(%s))));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
@ -2553,12 +2661,19 @@ iter_instruction(struct tgsi_iterate_context *iter,
snprintf(buf, 255, "%s = %s(intBitsToFloat(-(ivec4(%s))));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]); snprintf(buf, 255, "%s = %s(intBitsToFloat(-(ivec4(%s))));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_DNEG:
snprintf(buf, 255, "%s = %s(-%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
EMIT_BUF_WITH_RET(ctx, buf);
break;
case TGSI_OPCODE_SEQ: case TGSI_OPCODE_SEQ:
emit_compare("equal"); emit_compare("equal");
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_USEQ: case TGSI_OPCODE_USEQ:
case TGSI_OPCODE_FSEQ: case TGSI_OPCODE_FSEQ:
case TGSI_OPCODE_DSEQ:
if (inst->Instruction.Opcode == TGSI_OPCODE_DSEQ)
strcpy(writemask, ".x");
emit_ucompare("equal"); emit_ucompare("equal");
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
@ -2569,6 +2684,9 @@ iter_instruction(struct tgsi_iterate_context *iter,
case TGSI_OPCODE_ISLT: case TGSI_OPCODE_ISLT:
case TGSI_OPCODE_USLT: case TGSI_OPCODE_USLT:
case TGSI_OPCODE_FSLT: case TGSI_OPCODE_FSLT:
case TGSI_OPCODE_DSLT:
if (inst->Instruction.Opcode == TGSI_OPCODE_DSLT)
strcpy(writemask, ".x");
emit_ucompare("lessThan"); emit_ucompare("lessThan");
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
@ -2578,6 +2696,9 @@ iter_instruction(struct tgsi_iterate_context *iter,
break; break;
case TGSI_OPCODE_USNE: case TGSI_OPCODE_USNE:
case TGSI_OPCODE_FSNE: case TGSI_OPCODE_FSNE:
case TGSI_OPCODE_DSNE:
if (inst->Instruction.Opcode == TGSI_OPCODE_DSNE)
strcpy(writemask, ".x");
emit_ucompare("notEqual"); emit_ucompare("notEqual");
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
@ -2588,6 +2709,9 @@ iter_instruction(struct tgsi_iterate_context *iter,
case TGSI_OPCODE_ISGE: case TGSI_OPCODE_ISGE:
case TGSI_OPCODE_USGE: case TGSI_OPCODE_USGE:
case TGSI_OPCODE_FSGE: case TGSI_OPCODE_FSGE:
case TGSI_OPCODE_DSGE:
if (inst->Instruction.Opcode == TGSI_OPCODE_DSGE)
strcpy(writemask, ".x");
emit_ucompare("greaterThanEqual"); emit_ucompare("greaterThanEqual");
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
@ -2756,6 +2880,13 @@ iter_instruction(struct tgsi_iterate_context *iter,
break; break;
} }
for (uint32_t i = 0; i < 1; i++) {
enum tgsi_opcode_type dtype = tgsi_opcode_infer_dst_type(inst->Instruction.Opcode);
if (dtype == TGSI_TYPE_DOUBLE) {
snprintf(buf, 255, "%s = uintBitsToFloat(unpackDouble2x32(%s));\n", fp64_dsts[0], dsts[0]);
EMIT_BUF_WITH_RET(ctx, buf);
}
}
if (inst->Instruction.Saturate) { if (inst->Instruction.Saturate) {
snprintf(buf, 255, "%s = clamp(%s, 0.0, 1.0);\n", dsts[0], dsts[0]); snprintf(buf, 255, "%s = clamp(%s, 0.0, 1.0);\n", dsts[0], dsts[0]);
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
@ -3131,6 +3262,13 @@ static char *emit_ios(struct dump_ctx *ctx, char *glsl_hdr)
STRCAT_WITH_RET(glsl_hdr, buf); STRCAT_WITH_RET(glsl_hdr, buf);
} }
if (ctx->shader_req_bits & SHADER_REQ_FP64) {
snprintf(buf, 255, "dvec2 fp64_dst[3];\n");
STRCAT_WITH_RET(glsl_hdr, buf);
snprintf(buf, 255, "dvec2 fp64_src[4];\n");
STRCAT_WITH_RET(glsl_hdr, buf);
}
for (i = 0; i < ctx->num_address; i++) { for (i = 0; i < ctx->num_address; i++) {
snprintf(buf, 255, "int addr%d;\n", i); snprintf(buf, 255, "int addr%d;\n", i);
STRCAT_WITH_RET(glsl_hdr, buf); STRCAT_WITH_RET(glsl_hdr, buf);

Loading…
Cancel
Save