yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
43d0c2100
master
1#include "gfx-test-texture-util.h" 2 3#include <slang-com-ptr.h> 4#include <stdio.h> 5#include <stdlib.h> 6 7#ifdef _MSC_VER 8#pragma warning(push) 9#pragma warning(disable : 4996) 10#endif 11#define STB_IMAGE_WRITE_IMPLEMENTATION 12#include "stb_image_write.h" 13#ifdef _MSC_VER 14#pragma warning(pop) 15#endif 16 17namespace gfx_test 18{ 19 20TextureInfo ::~TextureInfo () 21{ 22for (SubresourceData subresourceData :subresourceDatas ) 23 { 24 ::free ((void * )subresourceData .data ); 25 } 26} 27 28Size getTexelSize (Format format ) 29{ 30const FormatInfo & info = getFormatInfo (format ); 31return info .blockSizeInBytes /info .pixelsPerBlock ; 32} 33 34RefPtr < ValidationTextureFormatBase > getValidationTextureFormat (Format format ) 35{ 36switch (format ) 37 { 38case Format ::RGBA32Float : 39return new ValidationTextureFormat < float > (4 ); 40case Format ::RGB32Float : 41return new ValidationTextureFormat < float > (3 ); 42case Format ::RG32Float : 43return new ValidationTextureFormat < float > (2 ); 44case Format ::R32Float : 45return new ValidationTextureFormat < float > (1 ); 46 47case Format ::RGBA16Float : 48return new ValidationTextureFormat < uint16_t > (4 ); 49case Format ::RG16Float : 50return new ValidationTextureFormat < uint16_t > (2 ); 51case Format ::R16Float : 52return new ValidationTextureFormat < uint16_t > (1 ); 53 54case Format ::R64Uint : 55return new ValidationTextureFormat < uint64_t > (1 ); 56 57case Format ::RGBA32Uint : 58return new ValidationTextureFormat < uint32_t > (4 ); 59case Format ::RGB32Uint : 60return new ValidationTextureFormat < uint32_t > (3 ); 61case Format ::RG32Uint : 62return new ValidationTextureFormat < uint32_t > (2 ); 63case Format ::R32Uint : 64return new ValidationTextureFormat < uint32_t > (1 ); 65 66case Format ::RGBA16Uint : 67return new ValidationTextureFormat < uint16_t > (4 ); 68case Format ::RG16Uint : 69return new ValidationTextureFormat < uint16_t > (2 ); 70case Format ::R16Uint : 71return new ValidationTextureFormat < uint16_t > (1 ); 72 73case Format ::RGBA8Uint : 74return new ValidationTextureFormat < uint8_t > (4 ); 75case Format ::RG8Uint : 76return new ValidationTextureFormat < uint8_t > (2 ); 77case Format ::R8Uint : 78return new ValidationTextureFormat < uint8_t > (1 ); 79 80case Format ::R64Sint : 81return new ValidationTextureFormat < int64_t > (1 ); 82 83case Format ::RGBA32Sint : 84return new ValidationTextureFormat < int32_t > (4 ); 85case Format ::RGB32Sint : 86return new ValidationTextureFormat < int32_t > (3 ); 87case Format ::RG32Sint : 88return new ValidationTextureFormat < int32_t > (2 ); 89case Format ::R32Sint : 90return new ValidationTextureFormat < int32_t > (1 ); 91 92case Format ::RGBA16Sint : 93return new ValidationTextureFormat < int16_t > (4 ); 94case Format ::RG16Sint : 95return new ValidationTextureFormat < int16_t > (2 ); 96case Format ::R16Sint : 97return new ValidationTextureFormat < int16_t > (1 ); 98 99case Format ::RGBA8Sint : 100return new ValidationTextureFormat < int8_t > (4 ); 101case Format ::RG8Sint : 102return new ValidationTextureFormat < int8_t > (2 ); 103case Format ::R8Sint : 104return new ValidationTextureFormat < int8_t > (1 ); 105 106case Format ::RGBA16Unorm : 107return new ValidationTextureFormat < uint16_t > (4 ); 108case Format ::RG16Unorm : 109return new ValidationTextureFormat < uint16_t > (2 ); 110case Format ::R16Unorm : 111return new ValidationTextureFormat < uint16_t > (1 ); 112 113case Format ::RGBA8Unorm : 114return new ValidationTextureFormat < uint8_t > (4 ); 115case Format ::RGBA8UnormSrgb : 116return new ValidationTextureFormat < uint8_t > (4 ); 117case Format ::RG8Unorm : 118return new ValidationTextureFormat < uint8_t > (2 ); 119case Format ::R8Unorm : 120return new ValidationTextureFormat < uint8_t > (1 ); 121case Format ::BGRA8Unorm : 122return new ValidationTextureFormat < uint8_t > (4 ); 123case Format ::BGRA8UnormSrgb : 124return new ValidationTextureFormat < uint8_t > (4 ); 125case Format ::BGRX8Unorm : 126return new ValidationTextureFormat < uint8_t > (3 ); 127case Format ::BGRX8UnormSrgb : 128return new ValidationTextureFormat < uint8_t > (3 ); 129 130case Format ::RGBA16Snorm : 131return new ValidationTextureFormat < int16_t > (4 ); 132case Format ::RG16Snorm : 133return new ValidationTextureFormat < int16_t > (2 ); 134case Format ::R16Snorm : 135return new ValidationTextureFormat < int16_t > (1 ); 136 137case Format ::RGBA8Snorm : 138return new ValidationTextureFormat < int8_t > (4 ); 139case Format ::RG8Snorm : 140return new ValidationTextureFormat < int8_t > (2 ); 141case Format ::R8Snorm : 142return new ValidationTextureFormat < int8_t > (1 ); 143 144case Format ::D32Float : 145return new ValidationTextureFormat < float > (1 ); 146case Format ::D16Unorm : 147return new ValidationTextureFormat < uint16_t > (1 ); 148 149case Format ::BGRA4Unorm : 150return new PackedValidationTextureFormat < uint16_t > (4 ,4 ,4 ,4 ); 151case Format ::B5G6R5Unorm : 152return new PackedValidationTextureFormat < uint16_t > (5 ,6 ,5 ,0 ); 153case Format ::BGR5A1Unorm : 154return new PackedValidationTextureFormat < uint16_t > (5 ,5 ,5 ,1 ); 155 156case Format ::RGB9E5Ufloat : 157return new ValidationTextureFormat < uint32_t > (1 ); 158case Format ::RGB10A2Unorm : 159return new PackedValidationTextureFormat < uint32_t > (10 ,10 ,10 ,2 ); 160case Format ::RGB10A2Uint : 161return new PackedValidationTextureFormat < uint32_t > (10 ,10 ,10 ,2 ); 162case Format ::R11G11B10Float : 163return new PackedValidationTextureFormat < uint32_t > (11 ,11 ,10 ,0 ); 164 165// TODO: Add testing support for BC formats 166// BC1Unorm, 167// BC1UnormSrgb, 168// BC2Unorm, 169// BC2UnormSrgb, 170// BC3Unorm, 171// BC3UnormSrgb, 172// BC4Unorm, 173// BC4Snorm, 174// BC5Unorm, 175// BC5Snorm, 176// BC6HUfloat, 177// BC6HSfloat, 178// BC7Unorm, 179// BC7UnormSrgb, 180default : 181return nullptr ; 182 } 183} 184 185void generateTextureData (RefPtr < TextureInfo > texture ,ValidationTextureFormatBase * validationFormat ) 186{ 187Extent3D extent = texture -> extent ; 188uint32_t layerCount = texture -> arrayLength ; 189if (texture -> textureType == TextureType ::TextureCube ) 190layerCount *=6 ; 191uint32_t mipLevels = texture -> mipCount ; 192Size texelSize = getTexelSize (texture -> format ); 193 194for (uint32_t layer = 0 ;layer < layerCount ;++ layer ) 195 { 196for (uint32_t mip = 0 ;mip < mipLevels ;++ mip ) 197 { 198RefPtr < ValidationTextureData > subresource = new ValidationTextureData (); 199 200uint32_t mipWidth = std::max (extent .width >>mip ,1u ); 201uint32_t mipHeight = std::max (extent .height >>mip ,1u ); 202uint32_t mipDepth = std::max (extent .depth >>mip ,1u ); 203uint32_t mipSize = mipWidth * mipHeight * mipDepth * texelSize ; 204subresource -> textureData = ::malloc (mipSize ); 205assert (subresource -> textureData != nullptr ); 206 207subresource -> extent .width = mipWidth ; 208subresource -> extent .height = mipHeight ; 209subresource -> extent .depth = mipDepth ; 210subresource -> pitches .x = texelSize ; 211subresource -> pitches .y = mipWidth * texelSize ; 212subresource -> pitches .z = mipHeight * subresource -> pitches .y ; 213texture -> subresourceObjects .push_back (subresource ); 214 215for (int z = 0 ;z < mipDepth ;++ z ) 216 { 217for (int y = 0 ;y < mipHeight ;++ y ) 218 { 219for (int x = 0 ;x < mipWidth ;++ x ) 220 { 221auto texel = subresource -> getBlockAt (x ,y ,z ); 222validationFormat -> initializeTexel (texel ,x ,y ,z ,mip ,layer ); 223 } 224 } 225 } 226 227SubresourceData subData = {}; 228subData .data = subresource -> textureData ; 229subData .rowPitch = subresource -> pitches .y ; 230subData .slicePitch = subresource -> pitches .z ; 231texture -> subresourceDatas .push_back (subData ); 232 } 233 } 234} 235 236std::vector < uint8_t > removePadding ( 237ISlangBlob * pixels , 238uint32_t width , 239uint32_t height , 240Size rowPitch , 241Size pixelSize ) 242{ 243 std::vector < uint8_t > buffer ; 244buffer .resize (height * rowPitch ); 245for (uint32_t i = 0 ;i < height ;++ i ) 246 { 247Offset srcOffset = i * rowPitch ; 248Offset dstOffset = i * width * pixelSize ; 249memcpy ( 250buffer .data ()+ dstOffset , 251 (char * )pixels -> getBufferPointer ()+ srcOffset , 252width * pixelSize ); 253 } 254 255return buffer ; 256} 257 258Result writeImage (const char * filename ,ISlangBlob * pixels ,uint32_t width ,uint32_t height ) 259{ 260int stbResult = stbi_write_hdr (filename ,width ,height ,4 , (float * )pixels -> getBufferPointer ()); 261 262return stbResult ?SLANG_OK :SLANG_FAIL ; 263} 264 265Result writeImage ( 266const char * filename , 267ISlangBlob * pixels , 268uint32_t width , 269uint32_t height , 270uint32_t rowPitch , 271uint32_t pixelSize ) 272{ 273if (rowPitch == width * pixelSize ) 274return writeImage (filename ,pixels ,width ,height ); 275 276 std::vector < uint8_t > buffer = removePadding (pixels ,width ,height ,rowPitch ,pixelSize ); 277 278int stbResult = stbi_write_hdr (filename ,width ,height ,4 , (float * )buffer .data ()); 279 280return stbResult ?SLANG_OK :SLANG_FAIL ; 281} 282 283}// namespace gfx_test