implement min/max and abstract ops on vectors
authorZack Rusin <zack@tungstengraphics.com>
Fri, 16 May 2008 18:54:40 +0000 (14:54 -0400)
committerZack Rusin <zack@tungstengraphics.com>
Sat, 17 May 2008 17:58:44 +0000 (13:58 -0400)
src/gallium/auxiliary/gallivm/instructionssoa.cpp
src/gallium/auxiliary/gallivm/instructionssoa.h
src/gallium/auxiliary/gallivm/soabuiltins.c
src/gallium/auxiliary/gallivm/tgsitollvm.cpp

index 4520559ba2b6af9a598fdf312f8b7f1d9a653906..55fdda279162df261e36e95fc007cc9d3fb0f0ef 100644 (file)
@@ -176,14 +176,17 @@ void InstructionsSoa::createFunctionMap()
    m_functionsMap[TGSI_OPCODE_ABS]   = "abs";
    m_functionsMap[TGSI_OPCODE_DP3]   = "dp3";
    m_functionsMap[TGSI_OPCODE_DP4]   = "dp4";
+   m_functionsMap[TGSI_OPCODE_MIN]   = "min";
+   m_functionsMap[TGSI_OPCODE_MAX]   = "max";
    m_functionsMap[TGSI_OPCODE_POWER] = "pow";
 }
 
 void InstructionsSoa::createDependencies()
 {
    {
-      std::vector<std::string> powDeps(1);
+      std::vector<std::string> powDeps(2);
       powDeps[0] = "powf";
+      powDeps[1] = "powvec";
       m_builtinDependencies["pow"] = powDeps;
    }
    {
@@ -191,6 +194,16 @@ void InstructionsSoa::createDependencies()
       absDeps[0] = "fabsf";
       m_builtinDependencies["abs"] = absDeps;
    }
+   {
+      std::vector<std::string> maxDeps(1);
+      maxDeps[0] = "maxvec";
+      m_builtinDependencies["max"] = maxDeps;
+   }
+   {
+      std::vector<std::string> minDeps(1);
+      minDeps[0] = "minvec";
+      m_builtinDependencies["min"] = minDeps;
+   }
 }
 
 llvm::Function * InstructionsSoa::function(int op)
@@ -374,6 +387,21 @@ std::vector<llvm::Value*> InstructionsSoa::pow(const std::vector<llvm::Value*> i
    return callBuiltin(func, in1, in2);
 }
 
+std::vector<llvm::Value*> InstructionsSoa::min(const std::vector<llvm::Value*> in1,
+                                               const std::vector<llvm::Value*> in2)
+{
+   llvm::Function *func = function(TGSI_OPCODE_MIN);
+   return callBuiltin(func, in1, in2);
+}
+
+
+std::vector<llvm::Value*> InstructionsSoa::max(const std::vector<llvm::Value*> in1,
+                                               const std::vector<llvm::Value*> in2)
+{
+   llvm::Function *func = function(TGSI_OPCODE_MAX);
+   return callBuiltin(func, in1, in2);
+}
+
 void checkFunction(Function *func)
 {
    for (Function::const_iterator BI = func->begin(), BE = func->end();
index 02e5fab51fa174992d7ffef813f303b28c719a68..5a7f8fdf727a13365b6f092f00981b135892539c 100644 (file)
@@ -59,6 +59,10 @@ public:
    std::vector<llvm::Value*> madd(const std::vector<llvm::Value*> in1,
                                   const std::vector<llvm::Value*> in2,
                                   const std::vector<llvm::Value*> in3);
+   std::vector<llvm::Value*> max(const std::vector<llvm::Value*> in1,
+                                 const std::vector<llvm::Value*> in2);
+   std::vector<llvm::Value*> min(const std::vector<llvm::Value*> in1,
+                                 const std::vector<llvm::Value*> in2);
    std::vector<llvm::Value*> mul(const std::vector<llvm::Value*> in1,
                                  const std::vector<llvm::Value*> in2);
    std::vector<llvm::Value*> pow(const std::vector<llvm::Value*> in1,
index f04e4c974dbf6b7aedadfd61ee1d392dcda88993..935283f962b0c0c11dbe48e0b6d4b94960e18e69 100644 (file)
@@ -89,18 +89,73 @@ void dp4(float4 *res,
 
 extern float powf(float num, float p);
 
+float4 powvec(float4 vec, float4 q)
+{
+   float4 p;
+   p.x = powf(vec.x, q.x);
+   p.y = powf(vec.y, q.y);
+   p.z = powf(vec.z, q.z);
+   p.w = powf(vec.w, q.w);
+   return p;
+}
+
 void pow(float4 *res,
          float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w,
          float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w)
 {
-   float4 p;
-   p.x = powf(tmp0x.x, tmp1x.x);
-   p.y = powf(tmp0x.y, tmp1x.y);
-   p.z = powf(tmp0x.z, tmp1x.z);
-   p.w = powf(tmp0x.w, tmp1x.w);
-
-   res[0] = p;
-   res[1] = p;
-   res[2] = p;
-   res[3] = p;
+   res[0] = powvec(tmp0x, tmp1x);
+   res[1] = res[0];
+   res[2] = res[0];
+   res[3] = res[0];
+}
+
+void lit(float4 *res,
+         float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w,
+         float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w)
+{
+   const float4 zerovec = (float4) {0, 0, 0, 0};
+   float4 tmpx = tmp0x;
+   float4 tmpy = tmp0y;
+
+   res[0] = (float4){1.0, 1.0, 1.0, 1.0};
+   res[1] = tmpx;
+   res[2] = tmpy;
+   res[3] = (float4){1.0, 1.0, 1.0, 1.0};
+}
+
+float4 minvec(float4 a, float4 b)
+{
+   return (float4){(a.x < b.x) ? a.x : b.x,
+         (a.y < b.y) ? a.y : b.y,
+         (a.z < b.z) ? a.z : b.z,
+         (a.w < b.w) ? a.w : b.w};
+}
+
+void min(float4 *res,
+         float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w,
+         float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w)
+{
+   res[0] = minvec(tmp0x, tmp1x);
+   res[1] = minvec(tmp0y, tmp1y);
+   res[2] = minvec(tmp0z, tmp1z);
+   res[3] = minvec(tmp0w, tmp1w);
+}
+
+
+float4 maxvec(float4 a, float4 b)
+{
+   return (float4){(a.x > b.x) ? a.x : b.x,
+         (a.y > b.y) ? a.y : b.y,
+         (a.z > b.z) ? a.z : b.z,
+         (a.w > b.w) ? a.w : b.w};
+}
+
+void max(float4 *res,
+         float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w,
+         float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w)
+{
+   res[0] = maxvec(tmp0x, tmp1x);
+   res[1] = maxvec(tmp0y, tmp1y);
+   res[2] = maxvec(tmp0z, tmp1z);
+   res[3] = maxvec(tmp0w, tmp1w);
 }
index 5465d3a95ef9f9bb8465147b1dda2a1b7d130614..007b5c169af7dede4ca3f8275d5101e14d3a3675 100644 (file)
@@ -724,9 +724,11 @@ translate_instructionir(llvm::Module *module,
    }
       break;
    case TGSI_OPCODE_MIN: {
+      out = instr->min(inputs[0], inputs[1]);
    }
       break;
    case TGSI_OPCODE_MAX: {
+      out = instr->max(inputs[0], inputs[1]);
    }
       break;
    case TGSI_OPCODE_SLT: {