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
5.6 KiB236 linesraw
1#pragma once
2
3#include "core/slang-basic.h"
4#include "slang-rhi.h"
5#include "unit-test/slang-unit-test.h"
6
7using namespace rhi;
8using Slang::RefObject;
9using Slang::RefPtr;
10
11namespace gfx_test
12{
13struct Strides
14{
15    Size x;
16    Size y;
17    Size z;
18};
19
20struct ValidationTextureFormatBase : RefObject
21{
22    virtual void validateBlocksEqual(const void* actual, const void* expected) = 0;
23
24    virtual void initializeTexel(
25        void* texel,
26        uint32_t x,
27        uint32_t y,
28        uint32_t z,
29        uint32_t mip,
30        uint32_t layer) = 0;
31};
32
33template<typename T>
34struct ValidationTextureFormat : ValidationTextureFormatBase
35{
36    uint32_t componentCount;
37
38    ValidationTextureFormat(uint32_t componentCount)
39        : componentCount(componentCount){};
40
41    virtual void validateBlocksEqual(const void* actual, const void* expected) override
42    {
43        auto a = (const T*)actual;
44        auto e = (const T*)expected;
45
46        for (uint32_t i = 0; i < componentCount; ++i)
47        {
48            SLANG_CHECK(a[i] == e[i]);
49        }
50    }
51
52    virtual void initializeTexel(
53        void* texel,
54        uint32_t x,
55        uint32_t y,
56        uint32_t z,
57        uint32_t mip,
58        uint32_t layer) override
59    {
60        auto temp = (T*)texel;
61
62        switch (componentCount)
63        {
64        case 1:
65            temp[0] = T(x + y + z + mip + layer);
66            break;
67        case 2:
68            temp[0] = T(x + z + layer);
69            temp[1] = T(y + mip);
70            break;
71        case 3:
72            temp[0] = T(x + mip);
73            temp[1] = T(y + layer);
74            temp[2] = T(z);
75            break;
76        case 4:
77            temp[0] = T(x + layer);
78            temp[1] = (T)y;
79            temp[2] = (T)z;
80            temp[3] = (T)mip;
81            break;
82        default:
83            assert("component count should be no greater than 4");
84            SLANG_CHECK_ABORT(false);
85        }
86    }
87};
88
89template<typename T>
90struct PackedValidationTextureFormat : ValidationTextureFormatBase
91{
92    int rBits;
93    int gBits;
94    int bBits;
95    int aBits;
96
97    PackedValidationTextureFormat(int rBits, int gBits, int bBits, int aBits)
98        : rBits(rBits), gBits(gBits), bBits(bBits), aBits(aBits){};
99
100    virtual void validateBlocksEqual(const void* actual, const void* expected) override
101    {
102        T a[4];
103        T e[4];
104        unpackTexel(*(const T*)actual, a);
105        unpackTexel(*(const T*)expected, e);
106
107        for (uint32_t i = 0; i < 4; ++i)
108        {
109            SLANG_CHECK(a[i] == e[i]);
110        }
111    }
112
113    virtual void initializeTexel(
114        void* texel,
115        uint32_t x,
116        uint32_t y,
117        uint32_t z,
118        uint32_t mip,
119        uint32_t layer) override
120    {
121        T temp = 0;
122
123        // The only formats which currently use this have either 3 or 4 channels. TODO: BC formats?
124        if (aBits == 0)
125        {
126            temp |= z;
127            temp <<= gBits;
128            temp |= (y + layer);
129            temp <<= rBits;
130            temp |= (x + mip);
131        }
132        else
133        {
134            temp |= mip;
135            temp <<= bBits;
136            temp |= z;
137            temp <<= gBits;
138            temp |= y;
139            temp <<= rBits;
140            temp |= (x + layer);
141        }
142
143        *(T*)texel = temp;
144    }
145
146    void unpackTexel(T texel, T* outComponents)
147    {
148        outComponents[0] = texel & ((1 << rBits) - 1);
149        texel >>= rBits;
150
151        outComponents[1] = texel & ((1 << gBits) - 1);
152        texel >>= gBits;
153
154        outComponents[2] = texel & ((1 << bBits) - 1);
155        texel >>= bBits;
156
157        outComponents[3] = texel & ((1 << aBits) - 1);
158        texel >>= aBits;
159    }
160};
161
162// Struct containing texture data and information for a specific subresource.
163struct ValidationTextureData : RefObject
164{
165    const void* textureData;
166    Extent3D extent;
167    Strides pitches;
168
169    void* getBlockAt(uint32_t x, uint32_t y, uint32_t z)
170    {
171        assert(x < extent.width);
172        assert(y < extent.height);
173        assert(z < extent.depth);
174
175        char* layerData = (char*)textureData + z * pitches.z;
176        char* rowData = layerData + y * pitches.y;
177        return rowData + x * pitches.x;
178    }
179};
180
181// Struct containing relevant information for a texture, including a list of its subresources
182// and all relevant information for each subresource.
183struct TextureInfo : RefObject
184{
185    Format format;
186    TextureType textureType;
187
188    Extent3D extent;
189    uint32_t mipCount;
190    uint32_t arrayLength;
191
192    std::vector<RefPtr<ValidationTextureData>> subresourceObjects;
193    std::vector<SubresourceData> subresourceDatas;
194
195    ~TextureInfo();
196};
197
198inline TextureType toArrayType(TextureType type)
199{
200    switch (type)
201    {
202    case TextureType::Texture1D:
203        return TextureType::Texture1DArray;
204    case TextureType::Texture2D:
205        return TextureType::Texture2DArray;
206    case TextureType::Texture2DMS:
207        return TextureType::Texture2DMSArray;
208    case TextureType::TextureCube:
209        return TextureType::TextureCubeArray;
210    default:
211        return type;
212    }
213}
214
215Size getTexelSize(Format format);
216RefPtr<ValidationTextureFormatBase> getValidationTextureFormat(Format format);
217void generateTextureData(
218    RefPtr<TextureInfo> texture,
219    ValidationTextureFormatBase* validationFormat);
220
221std::vector<uint8_t> removePadding(
222    ISlangBlob* pixels,
223    uint32_t width,
224    uint32_t height,
225    Size rowPitch,
226    Size pixelSize);
227Result writeImage(const char* filename, ISlangBlob* pixels, uint32_t width, uint32_t height);
228Result writeImage(
229    const char* filename,
230    ISlangBlob* pixels,
231    uint32_t width,
232    uint32_t height,
233    uint32_t rowPitch,
234    uint32_t pixelSize);
235
236} // namespace gfx_test