yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Gangzheng TongConvert gfx unit tests and examples to use slang-rhi (#7577)43d0c2100

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