From: Zack Rusin Date: Fri, 16 May 2008 18:54:40 +0000 (-0400) Subject: implement min/max and abstract ops on vectors X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ea1a607292ef31df70cda8c6476755e0224c9f7d;p=mesa.git implement min/max and abstract ops on vectors --- diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index 4520559ba2b..55fdda27916 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -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 powDeps(1); + std::vector 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 maxDeps(1); + maxDeps[0] = "maxvec"; + m_builtinDependencies["max"] = maxDeps; + } + { + std::vector minDeps(1); + minDeps[0] = "minvec"; + m_builtinDependencies["min"] = minDeps; + } } llvm::Function * InstructionsSoa::function(int op) @@ -374,6 +387,21 @@ std::vector InstructionsSoa::pow(const std::vector i return callBuiltin(func, in1, in2); } +std::vector InstructionsSoa::min(const std::vector in1, + const std::vector in2) +{ + llvm::Function *func = function(TGSI_OPCODE_MIN); + return callBuiltin(func, in1, in2); +} + + +std::vector InstructionsSoa::max(const std::vector in1, + const std::vector 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(); diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h index 02e5fab51fa..5a7f8fdf727 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.h +++ b/src/gallium/auxiliary/gallivm/instructionssoa.h @@ -59,6 +59,10 @@ public: std::vector madd(const std::vector in1, const std::vector in2, const std::vector in3); + std::vector max(const std::vector in1, + const std::vector in2); + std::vector min(const std::vector in1, + const std::vector in2); std::vector mul(const std::vector in1, const std::vector in2); std::vector pow(const std::vector in1, diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c index f04e4c974db..935283f962b 100644 --- a/src/gallium/auxiliary/gallivm/soabuiltins.c +++ b/src/gallium/auxiliary/gallivm/soabuiltins.c @@ -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); } diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index 5465d3a95ef..007b5c169af 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -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: {