From ed37dcbc175d07134cb0493f5e379a19e97c82f5 Mon Sep 17 00:00:00 2001 From: lucy96chen <47800040+lucy96chen@users.noreply.github.com> Date: Wed, 27 Jul 2022 15:53:36 -0700 Subject: Split render-cpu into smaller files (#2340) * render-cpu split, does not compile * split finished, one compile error * added missing include and missing destructor implementation * Rerun TeamCity CI --- tools/gfx/cpu/cpu-texture.cpp | 231 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 tools/gfx/cpu/cpu-texture.cpp (limited to 'tools/gfx/cpu/cpu-texture.cpp') diff --git a/tools/gfx/cpu/cpu-texture.cpp b/tools/gfx/cpu/cpu-texture.cpp new file mode 100644 index 000000000..d5367bd96 --- /dev/null +++ b/tools/gfx/cpu/cpu-texture.cpp @@ -0,0 +1,231 @@ +// cpu-texture.cpp +#include "cpu-texture.h" + +namespace gfx +{ +using namespace Slang; + +namespace cpu +{ + +static CPUTextureBaseShapeInfo const* _getBaseShapeInfo(ITextureResource::Type baseShape) +{ + return &kCPUTextureBaseShapeInfos[(int)baseShape]; +} + +template +void _unpackFloatTexel(void const* texelData, void* outData, size_t outSize) +{ + auto input = (float const*)texelData; + + float temp[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + for (int i = 0; i < N; ++i) + temp[i] = input[i]; + + memcpy(outData, temp, outSize); +} + +template +void _unpackFloat16Texel(void const* texelData, void* outData, size_t outSize) +{ + auto input = (int16_t const*)texelData; + + float temp[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + for (int i = 0; i < N; ++i) + temp[i] = HalfToFloat(input[i]); + + memcpy(outData, temp, outSize); +} + +static inline float _unpackUnorm8Value(uint8_t value) +{ + return value / 255.0f; +} + +template +void _unpackUnorm8Texel(void const* texelData, void* outData, size_t outSize) +{ + auto input = (uint8_t const*)texelData; + + float temp[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + for (int i = 0; i < N; ++i) + temp[i] = _unpackUnorm8Value(input[i]); + + memcpy(outData, temp, outSize); +} + +void _unpackUnormBGRA8Texel(void const* texelData, void* outData, size_t outSize) +{ + auto input = (uint8_t const*)texelData; + + float temp[4]; + temp[0] = _unpackUnorm8Value(input[2]); + temp[1] = _unpackUnorm8Value(input[1]); + temp[2] = _unpackUnorm8Value(input[0]); + temp[3] = _unpackUnorm8Value(input[3]); + + memcpy(outData, temp, outSize); +} + +template +void _unpackUInt16Texel(void const* texelData, void* outData, size_t outSize) +{ + auto input = (uint16_t const*)texelData; + + uint32_t temp[4] = { 0, 0, 0, 0 }; + for (int i = 0; i < N; ++i) + temp[i] = input[i]; + + memcpy(outData, temp, outSize); +} + +template +void _unpackUInt32Texel(void const* texelData, void* outData, size_t outSize) +{ + auto input = (uint32_t const*)texelData; + + uint32_t temp[4] = { 0, 0, 0, 0 }; + for (int i = 0; i < N; ++i) + temp[i] = input[i]; + + memcpy(outData, temp, outSize); +} + +TextureResourceImpl::~TextureResourceImpl() +{ + free(m_data); +} + +Result TextureResourceImpl::init(ITextureResource::SubresourceData const* initData) +{ + auto desc = m_desc; + + // The format of the texture will determine the + // size of the texels we allocate. + // + // TODO: Compressed formats usually work in terms + // of a fixed block size, so that we cannot actually + // compute a simple `texelSize` like this. Instead + // we should be computing a `blockSize` and then + // a `blockExtents` value that gives the extent + // in texels of each block. For uncompressed formats + // the block extents would be 1 along each axis. + // + auto format = desc.format; + FormatInfo texelInfo; + gfxGetFormatInfo(format, &texelInfo); + uint32_t texelSize = uint32_t(texelInfo.blockSizeInBytes / texelInfo.pixelsPerBlock); + m_texelSize = texelSize; + + int32_t formatBlockSize[kMaxRank] = { 1, 1, 1 }; + + auto baseShapeInfo = _getBaseShapeInfo(desc.type); + m_baseShape = baseShapeInfo; + if(!baseShapeInfo) + return SLANG_FAIL; + + auto formatInfo = _getFormatInfo(desc.format); + m_formatInfo = formatInfo; + if(!formatInfo) + return SLANG_FAIL; + + int32_t rank = baseShapeInfo->rank; + int32_t effectiveArrayElementCount = desc.arraySize ? desc.arraySize : 1; + effectiveArrayElementCount *= baseShapeInfo->implicitArrayElementCount; + m_effectiveArrayElementCount = effectiveArrayElementCount; + + int32_t extents[kMaxRank]; + extents[0] = desc.size.width; + extents[1] = desc.size.height; + extents[2] = desc.size.depth; + + for(int32_t axis = rank; axis < kMaxRank; ++axis) + extents[axis] = 1; + + int32_t levelCount = desc.numMipLevels; + + m_mipLevels.setCount(levelCount); + + int64_t totalDataSize = 0; + for( int32_t levelIndex = 0; levelIndex < levelCount; ++levelIndex ) + { + auto& level = m_mipLevels[levelIndex]; + + for( int32_t axis = 0; axis < kMaxRank; ++axis ) + { + int32_t extent = extents[axis] >> levelIndex; + if(extent < 1) extent = 1; + level.extents[axis] = extent; + } + + level.strides[0] = texelSize; + for( int32_t axis = 1; axis < kMaxRank+1; ++axis) + { + level.strides[axis] = level.strides[axis-1]*level.extents[axis-1]; + } + + int64_t levelDataSize = texelSize; + levelDataSize *= effectiveArrayElementCount; + for( int32_t axis = 0; axis < rank; ++axis) + levelDataSize *= int64_t(level.extents[axis]); + + level.offset = totalDataSize; + totalDataSize += levelDataSize; + } + + void* textureData = malloc((size_t)totalDataSize); + m_data = textureData; + + if( initData ) + { + int32_t subResourceCounter = 0; + for(int32_t arrayElementIndex = 0; arrayElementIndex < effectiveArrayElementCount; ++arrayElementIndex) + { + for(int32_t mipLevel = 0; mipLevel < m_desc.numMipLevels; ++mipLevel) + { + int32_t subResourceIndex = subResourceCounter++; + + auto dstRowStride = m_mipLevels[mipLevel].strides[1]; + auto dstLayerStride = m_mipLevels[mipLevel].strides[2]; + auto dstArrayStride = m_mipLevels[mipLevel].strides[3]; + + auto textureRowSize = m_mipLevels[mipLevel].extents[0]*texelSize; + + auto rowCount = m_mipLevels[mipLevel].extents[1]; + auto depthLayerCount = m_mipLevels[mipLevel].extents[2]; + + auto& srcImage = initData[subResourceIndex]; + ptrdiff_t srcRowStride = ptrdiff_t(srcImage.strideY); + ptrdiff_t srcLayerStride = ptrdiff_t(srcImage.strideZ); + + char* dstLevel = (char*)textureData + m_mipLevels[mipLevel].offset; + char* dstImage = dstLevel + dstArrayStride*arrayElementIndex; + + const char* srcLayer = (const char*) srcImage.data; + char* dstLayer = dstImage; + + for(int32_t depthLayer = 0; depthLayer < depthLayerCount; ++depthLayer) + { + const char* srcRow = srcLayer; + char* dstRow = dstLayer; + + for(int32_t row = 0; row < rowCount; ++row) + { + memcpy(dstRow, srcRow, textureRowSize); + + srcRow += srcRowStride; + dstRow += dstRowStride; + } + + srcLayer += srcLayerStride; + dstLayer += dstLayerStride; + } + } + } + } + + return SLANG_OK; +} + +} // namespace cpu +} // namespace gfx -- cgit v1.2.3