summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nouveau
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2014-01-10 17:58:37 -0500
committerMaarten Lankhorst <[email protected]>2014-01-27 16:40:42 +0100
commit18d97a8df776863c89c52294055160a17fc0f9e6 (patch)
treef79284462588e22fd4e5eda65381be71c7958919 /src/gallium/drivers/nouveau
parent45b64e52f4df49ac01ac100fba2c01633d492a6d (diff)
nouveau/codegen: set dType to S32 for OP_NEG U32
It doesn't make sense to do an OP_NEG from U32 to U32. This was manifested on nv50 in glsl-fs-atan-3 which was generating a UMAD TEMP[0].x, TEMP[0].xxxx, -TEMP[5].xxxx, TEMP[0].xxxx instruction. (For some reason, nvc0 causes a different shader to be generated.) This led to a cvt neg u32 $r1 u32 $r1 Which did not yield the desired result. This changes the final output to cvt neg s32 $r1 u32 $r1 which produces the desired output and the piglit tests passes. My assumption is that this is also what we want on nvc0, but could not test as there was no suitable shader that generated the problem instruction. Signed-off-by: Ilia Mirkin <[email protected]>
Diffstat (limited to 'src/gallium/drivers/nouveau')
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp12
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp8
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp14
3 files changed, 27 insertions, 7 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
index ac59187130c..fe428cacee4 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
@@ -808,6 +808,14 @@ CodeEmitterGK110::emitCVT(const Instruction *i)
break;
}
+ DataType dType;
+
+ if (i->op == OP_NEG && i->dType == TYPE_U32)
+ dType = TYPE_S32;
+ else
+ dType = i->dType;
+
+
uint32_t op;
if (f2f) op = 0x254;
@@ -824,10 +832,10 @@ CodeEmitterGK110::emitCVT(const Instruction *i)
emitRoundMode(rnd, 32 + 10, f2f ? (32 + 13) : -1);
- code[0] |= typeSizeofLog2(i->dType) << 10;
+ code[0] |= typeSizeofLog2(dType) << 10;
code[0] |= typeSizeofLog2(i->sType) << 12;
- if (isSignedIntType(i->dType))
+ if (isSignedIntType(dType))
code[0] |= 0x4000;
if (isSignedIntType(i->sType))
code[0] |= 0x8000;
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp
index 3eca27d0bbc..3eabfa6ae8f 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp
@@ -1106,6 +1106,7 @@ CodeEmitterNV50::emitCVT(const Instruction *i)
{
const bool f2f = isFloatType(i->dType) && isFloatType(i->sType);
RoundMode rnd;
+ DataType dType;
switch (i->op) {
case OP_CEIL: rnd = f2f ? ROUND_PI : ROUND_P; break;
@@ -1116,9 +1117,14 @@ CodeEmitterNV50::emitCVT(const Instruction *i)
break;
}
+ if (i->op == OP_NEG && i->dType == TYPE_U32)
+ dType = TYPE_S32;
+ else
+ dType = i->dType;
+
code[0] = 0xa0000000;
- switch (i->dType) {
+ switch (dType) {
case TYPE_F64:
switch (i->sType) {
case TYPE_F64: code[1] = 0xc4404000; break;
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
index 90c409d35e6..96a4af4262e 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
@@ -921,6 +921,7 @@ void
CodeEmitterNVC0::emitCVT(Instruction *i)
{
const bool f2f = isFloatType(i->dType) && isFloatType(i->sType);
+ DataType dType;
switch (i->op) {
case OP_CEIL: i->rnd = f2f ? ROUND_PI : ROUND_P; break;
@@ -934,13 +935,18 @@ CodeEmitterNVC0::emitCVT(Instruction *i)
const bool abs = (i->op == OP_ABS) || i->src(0).mod.abs();
const bool neg = (i->op == OP_NEG) || i->src(0).mod.neg();
+ if (i->op == OP_NEG && i->dType == TYPE_U32)
+ dType = TYPE_S32;
+ else
+ dType = i->dType;
+
if (i->encSize == 8) {
emitForm_B(i, HEX64(10000000, 00000004));
roundMode_C(i);
// cvt u16 f32 sets high bits to 0, so we don't have to use Value::Size()
- code[0] |= util_logbase2(typeSizeof(i->dType)) << 20;
+ code[0] |= util_logbase2(typeSizeof(dType)) << 20;
code[0] |= util_logbase2(typeSizeof(i->sType)) << 23;
if (sat)
@@ -953,12 +959,12 @@ CodeEmitterNVC0::emitCVT(Instruction *i)
if (i->ftz)
code[1] |= 1 << 23;
- if (isSignedIntType(i->dType))
+ if (isSignedIntType(dType))
code[0] |= 0x080;
if (isSignedIntType(i->sType))
code[0] |= 0x200;
- if (isFloatType(i->dType)) {
+ if (isFloatType(dType)) {
if (!isFloatType(i->sType))
code[1] |= 0x08000000;
} else {
@@ -971,7 +977,7 @@ CodeEmitterNVC0::emitCVT(Instruction *i)
if (i->op == OP_CEIL || i->op == OP_FLOOR || i->op == OP_TRUNC) {
code[0] = 0x298;
} else
- if (isFloatType(i->dType)) {
+ if (isFloatType(dType)) {
if (isFloatType(i->sType))
code[0] = 0x098;
else