#include "core/TensorUtils.hpp" #include "core/Macro.h" #include "../compute/CommonOptFunction.h" #include "../CPUBackend.hpp" #include #include #include #include "half.hpp" #define MNN_OPEN_TIME_TRACE #include namespace MNN { #ifdef MNN_SUPPORT_RENDER struct Point { float x; float y; float z; float w; }; class CPURasterAndInterpolate : public Execution { public: CPURasterAndInterpolate(Backend* bn, bool hasIndice, int primitiveType) : Execution(bn) { mIndice = hasIndice; mType = primitiveType; } virtual ~ CPURasterAndInterpolate() { // Do nothing } virtual ErrorCode onResize(const std::vector &inputs, const std::vector &outputs) override { return NO_ERROR; } void _rasterPointWithPointsize(const std::vector &inputs, const std::vector &outputs) { auto rasterOutput = outputs[0]; auto width = rasterOutput->length(2); auto height = rasterOutput->length(1); auto rasterBufferPtr = rasterOutput->host(); int pixelSize = height * width; auto pointSize = inputs[1]; auto position = inputs[2]; auto pointSizePtr = pointSize->host(); auto posPtr = position->host(); auto numberPoint = pointSize->length(0); auto tY = [height](float x) { return ((x + 1.0f) * 0.5f * height) - 0.5f; }; auto tX = [width](float x) { return ((x + 1.0f) * 0.5f * width) - 0.5f; }; for (int index=0; index dstPtr[2]) { continue; } dstPtr[2] = curZ; dstPtr[3] = index; dstPtr[0] = 0.0; dstPtr[1] = 0.0; for (int i=1; ilength(3); auto srcPtr = inputs[i+2]->host(); auto ndstPtr = outputs[i]->host() + (yi*width + xi) * unit; auto src = srcPtr + index * unit; for (int j=0; j &inputs, const std::vector &outputs) { auto rasterOutput = outputs[0]; auto width = rasterOutput->length(2); auto height = rasterOutput->length(1); auto rasterBufferPtr = rasterOutput->host(); int pixelSize = height * width; auto indice = inputs[1]; auto position = inputs[2]; auto indicePtr = indice->host(); auto posPtr = position->host(); auto numberTriangle = indice->elementSize() / 3;; for (int triangleIndex=0; triangleIndex < numberTriangle; ++triangleIndex) { auto i0 = indicePtr[3 * triangleIndex + 0]; auto i1 = indicePtr[3 * triangleIndex + 1]; auto i2 = indicePtr[3 * triangleIndex + 2]; auto x0 = posPtr[4 * i0 + 0]; auto x1 = posPtr[4 * i1 + 0]; auto x2 = posPtr[4 * i2 + 0]; auto y0 = posPtr[4 * i0 + 1]; auto y1 = posPtr[4 * i1 + 1]; auto y2 = posPtr[4 * i2 + 1]; auto z0 = posPtr[4 * i0 + 2]; auto z1 = posPtr[4 * i1 + 2]; auto z2 = posPtr[4 * i2 + 2]; auto w0 = posPtr[4 * i0 + 3]; auto w1 = posPtr[4 * i1 + 3]; auto w2 = posPtr[4 * i2 + 3]; std::vector points { {x0, y0, z0, w0}, {x1, y1, z1, w1}, {x2, y2, z2, w2}, }; // TODO: Clip auto tY = [height](float x) { return ((x + 1.0f) * 0.5f * height); }; auto rY = [height](int y) { return (float)y / (float)height * 2.0f - 1.0f; }; auto tX = [width](float x) { return ((x + 1.0f) * 0.5f * width); }; auto rX = [width](int y) { return (float)y / (float)width * 2.0f - 1.0f; }; for (int i=2; i myi) { std::swap(y0i, myi); } if (y0i < 0) { y0i = 0; } if (myi > height) { myi = height; } for (int yi=y0i; yi xri) { std::swap(xli, xri); } int xs = floorf(xli); int xe = ceilf(xri); if (xs < 0) { xs = 0; } if (xe > width) { xe = width; } for (int xi=xs; xi 1.0f) { continue; } if (b1 < 0.0f || b1 > 1.0f) { continue; } if (b0 < 0.0f || b0 > 1.0f) { continue; } // Clamps to avoid NaNs. b0 = fmaxf(fminf(b0, 1.0f), 0.0f); // Clamp to [+0.0, 1.0]. b1 = fmaxf(fminf(b1, 1.0f), 0.0f); // Clamp to [+0.0, 1.0]. zw = fmaxf(fminf(zw, 1.f), -1.f); float curZ = zw; if (curZ > dstPtr[2]) { continue; } dstPtr[2] = curZ; dstPtr[3] = triangleIndex; dstPtr[0] = b0; dstPtr[1] = b1; for (int i=1; ilength(3); auto srcPtr = inputs[i+2]->host(); auto ndstPtr = outputs[i]->host() + (yi*width + xi) * unit; auto src0 = srcPtr + i0 * unit; auto src1 = srcPtr + i1 * unit; auto src2 = srcPtr + i2 * unit; for (int j=0; j &inputs, const std::vector &outputs) override { auto rasterOutput = outputs[0]; auto width = rasterOutput->length(2); auto height = rasterOutput->length(1); // Init Output, index + 1, w0, w1, z int pixelSize = height * width; auto rasterBufferPtr = rasterOutput->host(); for (int i=0; ihost(); ::memset(ptr, 0, pixelSize * outputs[i]->length(3) * sizeof(float)); } if (mIndice && mType == 4) { _rasterTriangleWithIndice(inputs, outputs); } else if ((!mIndice) && (mType == 0)) { _rasterPointWithPointsize(inputs, outputs); } return NO_ERROR; } private: bool mIndice; int mType; }; class CPURasterSort : public Execution { private: std::vector> mKV; std::array mHistorm; std::array mHistormOffset; public: CPURasterSort(Backend* bn) : Execution(bn) { } virtual ~ CPURasterSort() { // Do nothing } virtual ErrorCode onResize(const std::vector &inputs, const std::vector &outputs) override { auto number = inputs[0]->length(0); mKV.resize(number); return NO_ERROR; } virtual ErrorCode onExecute(const std::vector &inputs, const std::vector &outputs) override { auto number = inputs[0]->length(0); auto attr = inputs[0]; auto viewProj = inputs[1]->host(); auto numAttr = attr->length(1); auto outputPtr = outputs[1]->host(); for (int i=0; ihost() + numAttr * i); auto x = srcPtr[0]; auto y = srcPtr[1]; auto z = srcPtr[2]; auto depth = viewProj[2] * x + viewProj[6] * y + viewProj[10] * z + viewProj[14]; auto dw = viewProj[3] * x + viewProj[7] * y + viewProj[11] * z + viewProj[15]; depth = depth / dw; if (depth < minDepth || depth > maxDepth) { continue; } uint32_t key = scale * (depth - minDepth) * 65535.0f; mKV[validNumber].second = i; mKV[validNumber].first = key; validNumber++; mHistorm[key]++; } } else { for (int i=0; ihost() + numAttr * i); auto x = srcPtr[0]; auto y = srcPtr[1]; auto z = srcPtr[2]; auto depth = viewProj[2] * x + viewProj[6] * y + viewProj[10] * z + viewProj[14]; auto dw = viewProj[3] * x + viewProj[7] * y + viewProj[11] * z + viewProj[15]; depth = depth / dw; if (depth < minDepth || depth > maxDepth) { continue; } uint32_t key = scale * (depth - minDepth) * 65535.0f; mKV[validNumber].second = i; mKV[validNumber].first = key; validNumber++; mHistorm[key]++; } } mHistormOffset[0] = 0; for (int i=1; i*)(outputs[1]->host()); for (int i=0; ihost()[0] = validNumber; return NO_ERROR; } }; class CPURasterAndInterpolateCreator : public CPUBackend::Creator { virtual Execution* onCreate(const std::vector &inputs, const std::vector &outputs, const MNN::Op *op, Backend *backend) const override { bool hasIndice = true; int type = 4; if (op->main_type() == OpParameter_Extra) { auto extra = op->main_as_Extra(); if (nullptr != extra->attr()) { for (int i=0; iattr()->size(); ++i) { auto attr = extra->attr()->GetAs(i); if (attr->key()->str() == "index") { hasIndice = attr->b(); continue; } if (attr->key()->str() == "primitiveType") { type = attr->i(); continue; } } } } if (6 == type) { return new CPURasterSort(backend); } return new CPURasterAndInterpolate(backend, hasIndice, type); } }; #endif REGISTER_CPU_OP_CREATOR_RENDER(CPURasterAndInterpolateCreator, OpType_RasterAndInterpolate); } // namespace MNN