yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// cpu-texture.cpp 2#include "cpu-texture.h" 3 4namespace gfx 5{ 6using namespace Slang ; 7 8namespace cpu 9{ 10 11static CPUTextureBaseShapeInfo const * _getBaseShapeInfo (ITextureResource ::Type baseShape ) 12{ 13return & kCPUTextureBaseShapeInfos [(int )baseShape ]; 14} 15 16template < int N > 17void _unpackFloatTexel (void const * texelData ,void * outData ,size_t outSize ) 18{ 19auto input = (float const * )texelData ; 20 21float temp [4 ]= {0.0f ,0.0f ,0.0f ,1.0f }; 22for (int i = 0 ;i < N ;++ i ) 23temp [i ]= input [i ]; 24 25memcpy (outData ,temp ,outSize ); 26} 27 28template < int N > 29void _unpackFloat16Texel (void const * texelData ,void * outData ,size_t outSize ) 30{ 31auto input = (int16_t const * )texelData ; 32 33float temp [4 ]= {0.0f ,0.0f ,0.0f ,1.0f }; 34for (int i = 0 ;i < N ;++ i ) 35temp [i ]= HalfToFloat (input [i ]); 36 37memcpy (outData ,temp ,outSize ); 38} 39 40static inline float _unpackUnorm8Value (uint8_t value ) 41{ 42return value /255.0f ; 43} 44 45template < int N > 46void _unpackUnorm8Texel (void const * texelData ,void * outData ,size_t outSize ) 47{ 48auto input = (uint8_t const * )texelData ; 49 50float temp [4 ]= {0.0f ,0.0f ,0.0f ,1.0f }; 51for (int i = 0 ;i < N ;++ i ) 52temp [i ]= _unpackUnorm8Value (input [i ]); 53 54memcpy (outData ,temp ,outSize ); 55} 56 57void _unpackUnormBGRA8Texel (void const * texelData ,void * outData ,size_t outSize ) 58{ 59auto input = (uint8_t const * )texelData ; 60 61float temp [4 ]; 62temp [0 ]= _unpackUnorm8Value (input [2 ]); 63temp [1 ]= _unpackUnorm8Value (input [1 ]); 64temp [2 ]= _unpackUnorm8Value (input [0 ]); 65temp [3 ]= _unpackUnorm8Value (input [3 ]); 66 67memcpy (outData ,temp ,outSize ); 68} 69 70template < int N > 71void _unpackUInt16Texel (void const * texelData ,void * outData ,size_t outSize ) 72{ 73auto input = (uint16_t const * )texelData ; 74 75uint32_t temp [4 ]= {0 ,0 ,0 ,0 }; 76for (int i = 0 ;i < N ;++ i ) 77temp [i ]= input [i ]; 78 79memcpy (outData ,temp ,outSize ); 80} 81 82template < int N > 83void _unpackUInt32Texel (void const * texelData ,void * outData ,size_t outSize ) 84{ 85auto input = (uint32_t const * )texelData ; 86 87uint32_t temp [4 ]= {0 ,0 ,0 ,0 }; 88for (int i = 0 ;i < N ;++ i ) 89temp [i ]= input [i ]; 90 91memcpy (outData ,temp ,outSize ); 92} 93 94TextureResourceImpl ::~TextureResourceImpl () 95{ 96free (m_data ); 97} 98 99Result TextureResourceImpl ::init (ITextureResource ::SubresourceData const * initData ) 100{ 101auto desc = m_desc ; 102 103// The format of the texture will determine the 104// size of the texels we allocate. 105// 106// TODO: Compressed formats usually work in terms 107// of a fixed block size, so that we cannot actually 108// compute a simple `texelSize` like this. Instead 109// we should be computing a `blockSize` and then 110// a `blockExtents` value that gives the extent 111// in texels of each block. For uncompressed formats 112// the block extents would be 1 along each axis. 113// 114auto format = desc .format ; 115FormatInfo texelInfo ; 116gfxGetFormatInfo (format ,& texelInfo ); 117uint32_t texelSize = uint32_t (texelInfo .blockSizeInBytes /texelInfo .pixelsPerBlock ); 118m_texelSize = texelSize ; 119 120int32_t formatBlockSize [kMaxRank ]= {1 ,1 ,1 }; 121 122auto baseShapeInfo = _getBaseShapeInfo (desc .type ); 123m_baseShape = baseShapeInfo ; 124if (!baseShapeInfo ) 125return SLANG_FAIL ; 126 127auto formatInfo = _getFormatInfo (desc .format ); 128m_formatInfo = formatInfo ; 129if (!formatInfo ) 130return SLANG_FAIL ; 131 132int32_t rank = baseShapeInfo -> rank ; 133int32_t effectiveArrayElementCount = desc .arraySize ?desc .arraySize :1 ; 134effectiveArrayElementCount *=baseShapeInfo -> implicitArrayElementCount ; 135m_effectiveArrayElementCount = effectiveArrayElementCount ; 136 137int32_t extents [kMaxRank ]; 138extents [0 ]= desc .size .width ; 139extents [1 ]= desc .size .height ; 140extents [2 ]= desc .size .depth ; 141 142for (int32_t axis = rank ;axis < kMaxRank ;++ axis ) 143extents [axis ]= 1 ; 144 145int32_t levelCount = desc .numMipLevels ; 146 147m_mipLevels .setCount (levelCount ); 148 149int64_t totalDataSize = 0 ; 150for (int32_t levelIndex = 0 ;levelIndex < levelCount ;++ levelIndex ) 151 { 152auto & level = m_mipLevels [levelIndex ]; 153 154for (int32_t axis = 0 ;axis < kMaxRank ;++ axis ) 155 { 156int32_t extent = extents [axis ] >>levelIndex ; 157if (extent < 1 ) 158extent = 1 ; 159level .extents [axis ]= extent ; 160 } 161 162level .strides [0 ]= texelSize ; 163for (int32_t axis = 1 ;axis < kMaxRank + 1 ;++ axis ) 164 { 165level .strides [axis ]= level .strides [axis - 1 ]* level .extents [axis - 1 ]; 166 } 167 168int64_t levelDataSize = texelSize ; 169levelDataSize *=effectiveArrayElementCount ; 170for (int32_t axis = 0 ;axis < rank ;++ axis ) 171levelDataSize *=int64_t (level .extents [axis ]); 172 173level .offset = totalDataSize ; 174totalDataSize += levelDataSize ; 175 } 176 177void * textureData = malloc ((size_t )totalDataSize ); 178m_data = textureData ; 179 180if (initData ) 181 { 182int32_t subResourceCounter = 0 ; 183for (int32_t arrayElementIndex = 0 ;arrayElementIndex < effectiveArrayElementCount ; 184++ arrayElementIndex ) 185 { 186for (int32_t mipLevel = 0 ;mipLevel < m_desc .numMipLevels ;++ mipLevel ) 187 { 188int32_t subResourceIndex = subResourceCounter ++ ; 189 190auto dstRowStride = m_mipLevels [mipLevel ].strides [1 ]; 191auto dstLayerStride = m_mipLevels [mipLevel ].strides [2 ]; 192auto dstArrayStride = m_mipLevels [mipLevel ].strides [3 ]; 193 194auto textureRowSize = m_mipLevels [mipLevel ].extents [0 ]* texelSize ; 195 196auto rowCount = m_mipLevels [mipLevel ].extents [1 ]; 197auto depthLayerCount = m_mipLevels [mipLevel ].extents [2 ]; 198 199auto & srcImage = initData [subResourceIndex ]; 200ptrdiff_t srcRowStride = ptrdiff_t (srcImage .strideY ); 201ptrdiff_t srcLayerStride = ptrdiff_t (srcImage .strideZ ); 202 203char * dstLevel = (char * )textureData + m_mipLevels [mipLevel ].offset ; 204char * dstImage = dstLevel + dstArrayStride * arrayElementIndex ; 205 206const char * srcLayer = (const char * )srcImage .data ; 207char * dstLayer = dstImage ; 208 209for (int32_t depthLayer = 0 ;depthLayer < depthLayerCount ;++ depthLayer ) 210 { 211const char * srcRow = srcLayer ; 212char * dstRow = dstLayer ; 213 214for (int32_t row = 0 ;row < rowCount ;++ row ) 215 { 216memcpy (dstRow ,srcRow ,textureRowSize ); 217 218srcRow += srcRowStride ; 219dstRow += dstRowStride ; 220 } 221 222srcLayer += srcLayerStride ; 223dstLayer += dstLayerStride ; 224 } 225 } 226 } 227 } 228 229return SLANG_OK ; 230} 231 232}// namespace cpu 233}// namespace gfx