git.s-ol.nu ~forks/DiligentCore / 5a166f3
Added sampler correctness test assiduous 6 months ago
3 changed file(s) with 540 addition(s) and 235 deletion(s). Raw diff Collapse all Expand all
0 Texture2D g_Tex2DClamp;
1 Texture2D g_Tex2DWrap;
2 Texture2D g_Tex2DMirror;
3
4 SamplerState g_Tex2DClamp_sampler;
5 SamplerState g_Tex2DWrap_sampler;
6 SamplerState g_Tex2DMirror_sampler;
7
8 float4 CheckValue(float4 Val, float4 Expected)
9 {
10 return float4(Val.x == Expected.x ? 1.0 : 0.0,
11 Val.y == Expected.y ? 1.0 : 0.0,
12 Val.z == Expected.z ? 1.0 : 0.0,
13 Val.w == Expected.w ? 1.0 : 0.0);
14 }
15
16 float4 GetRefClampValue(float2 UV, float4 Colors[2][2])
17 {
18 UV = saturate(UV);
19 int2 ij = min(int2(UV * 2.0), int2(1,1));
20 return Colors[ij.x][ij.y];
21 }
22
23 float4 GetRefWrapValue(float2 UV, float4 Colors[2][2])
24 {
25 UV = frac(UV);
26 int2 ij = int2(UV * 2.0);
27 return Colors[ij.x][ij.y];
28 }
29
30 float4 GetRefMirrorValue(float2 UV, float4 Colors[2][2])
31 {
32 UV = frac(UV * 0.5) * 2.0;
33 if (UV.x > 1.0) UV.x = 2.0 - UV.x;
34 if (UV.y > 1.0) UV.y = 2.0 - UV.y;
35 int2 ij = int2(UV * 2.0);
36 return Colors[ij.x][ij.y];
37 }
38
39 float4 VerifyResources()
40 {
41 float4 Colors[2][2];
42 Colors[0][0] = float4(1.0, 0.0, 0.0, 0.0);
43 Colors[1][0] = float4(0.0, 1.0, 0.0, 0.0);
44 Colors[0][1] = float4(0.0, 0.0, 1.0, 0.0);
45 Colors[1][1] = float4(0.0, 0.0, 0.0, 1.0);
46
47 float4 AllCorrect = float4(1.0, 1.0, 1.0, 1.0);
48
49 for(int x = 0; x < 10; ++x)
50 {
51 for(int y = 0; y < 10; ++y)
52 {
53 float2 UV = float2(x, y) * 0.5 + float2(0.25, 0.25);
54 AllCorrect *= CheckValue(g_Tex2DClamp.SampleLevel(g_Tex2DClamp_sampler, UV.xy, 0.0), GetRefClampValue(UV, Colors));
55 AllCorrect *= CheckValue(g_Tex2DWrap.SampleLevel(g_Tex2DWrap_sampler, UV.xy, 0.0), GetRefWrapValue(UV, Colors));
56 AllCorrect *= CheckValue(g_Tex2DMirror.SampleLevel(g_Tex2DMirror_sampler, UV.xy, 0.0), GetRefMirrorValue(UV, Colors));
57 }
58 }
59
60 return AllCorrect;
61 }
62
63 void VSMain(in uint VertId : SV_VertexID,
64 out float4 f4Color : COLOR,
65 out float4 f4Position : SV_Position)
66 {
67 float4 Pos[6];
68 Pos[0] = float4(-1.0, -0.5, 0.0, 1.0);
69 Pos[1] = float4(-0.5, +0.5, 0.0, 1.0);
70 Pos[2] = float4( 0.0, -0.5, 0.0, 1.0);
71
72 Pos[3] = float4(+0.0, -0.5, 0.0, 1.0);
73 Pos[4] = float4(+0.5, +0.5, 0.0, 1.0);
74 Pos[5] = float4(+1.0, -0.5, 0.0, 1.0);
75
76 f4Color = float4(VertId % 3 == 0 ? 1.0 : 0.0,
77 VertId % 3 == 1 ? 1.0 : 0.0,
78 VertId % 3 == 2 ? 1.0 : 0.0,
79 1.0) * VerifyResources();
80
81 f4Position = Pos[VertId];
82 }
83
84 float4 PSMain(in float4 in_f4Color : COLOR,
85 in float4 f4Position : SV_Position) : SV_Target
86 {
87 return in_f4Color * VerifyResources();
88 }
+0
-235
Tests/DiligentCoreAPITest/src/SamplerCreationTest.cpp less more
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #include <algorithm>
28 #include <cctype>
29
30 #include "TestingEnvironment.hpp"
31 #include "Sampler.h"
32 #include "GraphicsAccessories.hpp"
33
34 #include "gtest/gtest.h"
35
36 using namespace Diligent;
37 using namespace Diligent::Testing;
38
39 extern "C"
40 {
41 int TestSamplerCInterface(void* pSampler);
42 }
43
44 namespace
45 {
46
47 class FilterTypeTest : public testing::TestWithParam<std::tuple<FILTER_TYPE, FILTER_TYPE, FILTER_TYPE>>
48 {
49 protected:
50 static void TearDownTestSuite()
51 {
52 TestingEnvironment::GetInstance()->ReleaseResources();
53 }
54 };
55
56 TEST_P(FilterTypeTest, CreateSampler)
57 {
58 auto* pEnv = TestingEnvironment::GetInstance();
59 auto* pDevice = pEnv->GetDevice();
60
61 TestingEnvironment::ScopedReleaseResources AutoreleaseResources;
62
63 SamplerDesc SamplerDesc;
64 const auto& Param = GetParam();
65 SamplerDesc.MinFilter = std::get<0>(Param);
66 SamplerDesc.MagFilter = std::get<1>(Param);
67 SamplerDesc.MipFilter = std::get<2>(Param);
68 RefCntAutoPtr<ISampler> pSampler;
69 pDevice->CreateSampler(SamplerDesc, &pSampler);
70 ASSERT_TRUE(pSampler);
71 EXPECT_EQ(pSampler->GetDesc(), SamplerDesc);
72
73 TestSamplerCInterface(pSampler);
74 }
75
76 std::string GetSamplerFilterTestName(const testing::TestParamInfo<std::tuple<FILTER_TYPE, FILTER_TYPE, FILTER_TYPE>>& info) //
77 {
78 std::string name =
79 std::string{GetFilterTypeLiteralName(std::get<0>(info.param), false)} + std::string{"__"} +
80 std::string{GetFilterTypeLiteralName(std::get<1>(info.param), false)} + std::string{"__"} +
81 std::string{GetFilterTypeLiteralName(std::get<2>(info.param), false)};
82 for (size_t i = 0; i < name.length(); ++i)
83 {
84 if (!std::isalnum(name[i]))
85 name[i] = '_';
86 }
87 return name;
88 }
89
90
91 INSTANTIATE_TEST_SUITE_P(RegularFitlers,
92 FilterTypeTest,
93 testing::Combine(
94 testing::Values(FILTER_TYPE_POINT, FILTER_TYPE_LINEAR),
95 testing::Values(FILTER_TYPE_POINT, FILTER_TYPE_LINEAR),
96 testing::Values(FILTER_TYPE_POINT, FILTER_TYPE_LINEAR)),
97 GetSamplerFilterTestName);
98
99 INSTANTIATE_TEST_SUITE_P(ComparisonFilters,
100 FilterTypeTest,
101 testing::Combine(
102 testing::Values(FILTER_TYPE_COMPARISON_POINT, FILTER_TYPE_COMPARISON_LINEAR),
103 testing::Values(FILTER_TYPE_COMPARISON_POINT, FILTER_TYPE_COMPARISON_LINEAR),
104 testing::Values(FILTER_TYPE_COMPARISON_POINT, FILTER_TYPE_COMPARISON_LINEAR)),
105 GetSamplerFilterTestName);
106
107 TEST(FilterTypeTest, AnisotropicFilter)
108 {
109 auto* pEnv = TestingEnvironment::GetInstance();
110 auto* pDevice = pEnv->GetDevice();
111
112 TestingEnvironment::ScopedReleaseResources AutoreleaseResources;
113
114 {
115 SamplerDesc SamplerDesc;
116 SamplerDesc.MinFilter = FILTER_TYPE_ANISOTROPIC;
117 SamplerDesc.MagFilter = FILTER_TYPE_ANISOTROPIC;
118 SamplerDesc.MipFilter = FILTER_TYPE_ANISOTROPIC;
119
120 SamplerDesc.MaxAnisotropy = 4;
121 RefCntAutoPtr<ISampler> pSampler;
122 pDevice->CreateSampler(SamplerDesc, &pSampler);
123 ASSERT_TRUE(pSampler);
124 ASSERT_TRUE(pSampler);
125 EXPECT_EQ(pSampler->GetDesc(), SamplerDesc);
126 }
127
128 {
129 SamplerDesc SamplerDesc;
130 SamplerDesc.MinFilter = FILTER_TYPE_COMPARISON_ANISOTROPIC;
131 SamplerDesc.MagFilter = FILTER_TYPE_COMPARISON_ANISOTROPIC;
132 SamplerDesc.MipFilter = FILTER_TYPE_COMPARISON_ANISOTROPIC;
133
134 SamplerDesc.MaxAnisotropy = 4;
135 RefCntAutoPtr<ISampler> pSampler;
136 pDevice->CreateSampler(SamplerDesc, &pSampler);
137 ASSERT_TRUE(pSampler);
138 ASSERT_TRUE(pSampler);
139 EXPECT_EQ(pSampler->GetDesc(), SamplerDesc);
140 }
141 }
142
143
144 class AddressModeTest : public testing::TestWithParam<TEXTURE_ADDRESS_MODE>
145 {
146 protected:
147 static void TearDownTestSuite()
148 {
149 TestingEnvironment::GetInstance()->ReleaseResources();
150 }
151 };
152
153 TEST_P(AddressModeTest, CreateSampler)
154 {
155 auto* pEnv = TestingEnvironment::GetInstance();
156 auto* pDevice = pEnv->GetDevice();
157
158 TestingEnvironment::ScopedReleaseResources AutoreleaseResources;
159
160 SamplerDesc SamplerDesc;
161 SamplerDesc.MinFilter = FILTER_TYPE_LINEAR;
162 SamplerDesc.MagFilter = FILTER_TYPE_LINEAR;
163 SamplerDesc.MipFilter = FILTER_TYPE_LINEAR;
164 SamplerDesc.AddressU = SamplerDesc.AddressV = SamplerDesc.AddressW = GetParam();
165 RefCntAutoPtr<ISampler> pSampler;
166 pDevice->CreateSampler(SamplerDesc, &pSampler);
167 ASSERT_TRUE(pSampler);
168 EXPECT_EQ(pSampler->GetDesc(), SamplerDesc);
169 }
170
171 INSTANTIATE_TEST_SUITE_P(AddressModes,
172 AddressModeTest,
173 testing::Values(
174 TEXTURE_ADDRESS_WRAP,
175 TEXTURE_ADDRESS_MIRROR,
176 TEXTURE_ADDRESS_CLAMP,
177 TEXTURE_ADDRESS_BORDER),
178 [](const testing::TestParamInfo<TEXTURE_ADDRESS_MODE>& info) //
179 {
180 return std::string{GetTextureAddressModeLiteralName(info.param, true)};
181 } //
182 );
183
184
185 class ComparisonFuncTest : public testing::TestWithParam<COMPARISON_FUNCTION>
186 {
187 protected:
188 static void TearDownTestSuite()
189 {
190 TestingEnvironment::GetInstance()->ReleaseResources();
191 }
192 };
193
194 TEST_P(ComparisonFuncTest, CreateSampler)
195 {
196 auto* pEnv = TestingEnvironment::GetInstance();
197 auto* pDevice = pEnv->GetDevice();
198
199 TestingEnvironment::ScopedReleaseResources AutoreleaseResources;
200
201 SamplerDesc SamplerDesc;
202 SamplerDesc.MinFilter = FILTER_TYPE_LINEAR;
203 SamplerDesc.MagFilter = FILTER_TYPE_LINEAR;
204 SamplerDesc.MipFilter = FILTER_TYPE_LINEAR;
205 SamplerDesc.ComparisonFunc = GetParam();
206 RefCntAutoPtr<ISampler> pSampler1, pSampler2;
207 SamplerDesc.Name = "Sam1";
208 pDevice->CreateSampler(SamplerDesc, &pSampler1);
209 SamplerDesc.Name = "Sam2";
210 pDevice->CreateSampler(SamplerDesc, &pSampler2);
211 ASSERT_TRUE(pSampler1);
212 ASSERT_TRUE(pSampler2);
213 EXPECT_EQ(pSampler1, pSampler2);
214 EXPECT_EQ(pSampler1->GetDesc(), SamplerDesc);
215 }
216
217 INSTANTIATE_TEST_SUITE_P(ComparisonFunctions,
218 ComparisonFuncTest,
219 testing::Values(
220 COMPARISON_FUNC_NEVER,
221 COMPARISON_FUNC_LESS,
222 COMPARISON_FUNC_EQUAL,
223 COMPARISON_FUNC_LESS_EQUAL,
224 COMPARISON_FUNC_GREATER,
225 COMPARISON_FUNC_NOT_EQUAL,
226 COMPARISON_FUNC_GREATER_EQUAL,
227 COMPARISON_FUNC_ALWAYS),
228 [](const testing::TestParamInfo<COMPARISON_FUNCTION>& info) //
229 {
230 return std::string{GetComparisonFunctionLiteralName(info.param, true)};
231 } //
232 );
233
234 } // namespace
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #include <algorithm>
28 #include <cctype>
29
30 #include "TestingEnvironment.hpp"
31 #include "Sampler.h"
32 #include "GraphicsAccessories.hpp"
33
34 #include "ResourceLayoutTestCommon.hpp"
35 #include "FastRand.hpp"
36
37 #include "gtest/gtest.h"
38
39 using namespace Diligent;
40 using namespace Diligent::Testing;
41
42 extern "C"
43 {
44 int TestSamplerCInterface(void* pSampler);
45 }
46
47 namespace
48 {
49
50 class FilterTypeTest : public testing::TestWithParam<std::tuple<FILTER_TYPE, FILTER_TYPE, FILTER_TYPE>>
51 {
52 protected:
53 static void TearDownTestSuite()
54 {
55 TestingEnvironment::GetInstance()->ReleaseResources();
56 }
57 };
58
59 TEST_P(FilterTypeTest, CreateSampler)
60 {
61 auto* pEnv = TestingEnvironment::GetInstance();
62 auto* pDevice = pEnv->GetDevice();
63
64 TestingEnvironment::ScopedReleaseResources AutoreleaseResources;
65
66 SamplerDesc SamplerDesc;
67 const auto& Param = GetParam();
68 SamplerDesc.MinFilter = std::get<0>(Param);
69 SamplerDesc.MagFilter = std::get<1>(Param);
70 SamplerDesc.MipFilter = std::get<2>(Param);
71 RefCntAutoPtr<ISampler> pSampler;
72 pDevice->CreateSampler(SamplerDesc, &pSampler);
73 ASSERT_TRUE(pSampler);
74 EXPECT_EQ(pSampler->GetDesc(), SamplerDesc);
75
76 TestSamplerCInterface(pSampler);
77 }
78
79 std::string GetSamplerFilterTestName(const testing::TestParamInfo<std::tuple<FILTER_TYPE, FILTER_TYPE, FILTER_TYPE>>& info) //
80 {
81 std::string name =
82 std::string{GetFilterTypeLiteralName(std::get<0>(info.param), false)} + std::string{"__"} +
83 std::string{GetFilterTypeLiteralName(std::get<1>(info.param), false)} + std::string{"__"} +
84 std::string{GetFilterTypeLiteralName(std::get<2>(info.param), false)};
85 for (size_t i = 0; i < name.length(); ++i)
86 {
87 if (!std::isalnum(name[i]))
88 name[i] = '_';
89 }
90 return name;
91 }
92
93
94 INSTANTIATE_TEST_SUITE_P(RegularFitlers,
95 FilterTypeTest,
96 testing::Combine(
97 testing::Values(FILTER_TYPE_POINT, FILTER_TYPE_LINEAR),
98 testing::Values(FILTER_TYPE_POINT, FILTER_TYPE_LINEAR),
99 testing::Values(FILTER_TYPE_POINT, FILTER_TYPE_LINEAR)),
100 GetSamplerFilterTestName);
101
102 INSTANTIATE_TEST_SUITE_P(ComparisonFilters,
103 FilterTypeTest,
104 testing::Combine(
105 testing::Values(FILTER_TYPE_COMPARISON_POINT, FILTER_TYPE_COMPARISON_LINEAR),
106 testing::Values(FILTER_TYPE_COMPARISON_POINT, FILTER_TYPE_COMPARISON_LINEAR),
107 testing::Values(FILTER_TYPE_COMPARISON_POINT, FILTER_TYPE_COMPARISON_LINEAR)),
108 GetSamplerFilterTestName);
109
110 TEST(FilterTypeTest, AnisotropicFilter)
111 {
112 auto* pEnv = TestingEnvironment::GetInstance();
113 auto* pDevice = pEnv->GetDevice();
114
115 TestingEnvironment::ScopedReleaseResources AutoreleaseResources;
116
117 {
118 SamplerDesc SamplerDesc;
119 SamplerDesc.MinFilter = FILTER_TYPE_ANISOTROPIC;
120 SamplerDesc.MagFilter = FILTER_TYPE_ANISOTROPIC;
121 SamplerDesc.MipFilter = FILTER_TYPE_ANISOTROPIC;
122
123 SamplerDesc.MaxAnisotropy = 4;
124 RefCntAutoPtr<ISampler> pSampler;
125 pDevice->CreateSampler(SamplerDesc, &pSampler);
126 ASSERT_TRUE(pSampler);
127 ASSERT_TRUE(pSampler);
128 EXPECT_EQ(pSampler->GetDesc(), SamplerDesc);
129 }
130
131 {
132 SamplerDesc SamplerDesc;
133 SamplerDesc.MinFilter = FILTER_TYPE_COMPARISON_ANISOTROPIC;
134 SamplerDesc.MagFilter = FILTER_TYPE_COMPARISON_ANISOTROPIC;
135 SamplerDesc.MipFilter = FILTER_TYPE_COMPARISON_ANISOTROPIC;
136
137 SamplerDesc.MaxAnisotropy = 4;
138 RefCntAutoPtr<ISampler> pSampler;
139 pDevice->CreateSampler(SamplerDesc, &pSampler);
140 ASSERT_TRUE(pSampler);
141 ASSERT_TRUE(pSampler);
142 EXPECT_EQ(pSampler->GetDesc(), SamplerDesc);
143 }
144 }
145
146
147 class AddressModeTest : public testing::TestWithParam<TEXTURE_ADDRESS_MODE>
148 {
149 protected:
150 static void TearDownTestSuite()
151 {
152 TestingEnvironment::GetInstance()->ReleaseResources();
153 }
154 };
155
156 TEST_P(AddressModeTest, CreateSampler)
157 {
158 auto* pEnv = TestingEnvironment::GetInstance();
159 auto* pDevice = pEnv->GetDevice();
160
161 TestingEnvironment::ScopedReleaseResources AutoreleaseResources;
162
163 SamplerDesc SamplerDesc;
164 SamplerDesc.MinFilter = FILTER_TYPE_LINEAR;
165 SamplerDesc.MagFilter = FILTER_TYPE_LINEAR;
166 SamplerDesc.MipFilter = FILTER_TYPE_LINEAR;
167 SamplerDesc.AddressU = SamplerDesc.AddressV = SamplerDesc.AddressW = GetParam();
168 RefCntAutoPtr<ISampler> pSampler;
169 pDevice->CreateSampler(SamplerDesc, &pSampler);
170 ASSERT_TRUE(pSampler);
171 EXPECT_EQ(pSampler->GetDesc(), SamplerDesc);
172 }
173
174 INSTANTIATE_TEST_SUITE_P(AddressModes,
175 AddressModeTest,
176 testing::Values(
177 TEXTURE_ADDRESS_WRAP,
178 TEXTURE_ADDRESS_MIRROR,
179 TEXTURE_ADDRESS_CLAMP,
180 TEXTURE_ADDRESS_BORDER),
181 [](const testing::TestParamInfo<TEXTURE_ADDRESS_MODE>& info) //
182 {
183 return std::string{GetTextureAddressModeLiteralName(info.param, true)};
184 } //
185 );
186
187
188 class ComparisonFuncTest : public testing::TestWithParam<COMPARISON_FUNCTION>
189 {
190 protected:
191 static void TearDownTestSuite()
192 {
193 TestingEnvironment::GetInstance()->ReleaseResources();
194 }
195 };
196
197 TEST_P(ComparisonFuncTest, CreateSampler)
198 {
199 auto* pEnv = TestingEnvironment::GetInstance();
200 auto* pDevice = pEnv->GetDevice();
201
202 TestingEnvironment::ScopedReleaseResources AutoreleaseResources;
203
204 SamplerDesc SamplerDesc;
205 SamplerDesc.MinFilter = FILTER_TYPE_LINEAR;
206 SamplerDesc.MagFilter = FILTER_TYPE_LINEAR;
207 SamplerDesc.MipFilter = FILTER_TYPE_LINEAR;
208 SamplerDesc.ComparisonFunc = GetParam();
209 RefCntAutoPtr<ISampler> pSampler1, pSampler2;
210 SamplerDesc.Name = "Sam1";
211 pDevice->CreateSampler(SamplerDesc, &pSampler1);
212 SamplerDesc.Name = "Sam2";
213 pDevice->CreateSampler(SamplerDesc, &pSampler2);
214 ASSERT_TRUE(pSampler1);
215 ASSERT_TRUE(pSampler2);
216 EXPECT_EQ(pSampler1, pSampler2);
217 EXPECT_EQ(pSampler1->GetDesc(), SamplerDesc);
218 }
219
220 INSTANTIATE_TEST_SUITE_P(ComparisonFunctions,
221 ComparisonFuncTest,
222 testing::Values(
223 COMPARISON_FUNC_NEVER,
224 COMPARISON_FUNC_LESS,
225 COMPARISON_FUNC_EQUAL,
226 COMPARISON_FUNC_LESS_EQUAL,
227 COMPARISON_FUNC_GREATER,
228 COMPARISON_FUNC_NOT_EQUAL,
229 COMPARISON_FUNC_GREATER_EQUAL,
230 COMPARISON_FUNC_ALWAYS),
231 [](const testing::TestParamInfo<COMPARISON_FUNCTION>& info) //
232 {
233 return std::string{GetComparisonFunctionLiteralName(info.param, true)};
234 } //
235 );
236
237
238 void TestSamplerCorrectness(IShader* pVS,
239 IShader* pPS,
240 ITextureView* pDefaultSRV,
241 ITextureView* pClampSRV,
242 ITextureView* pWrapSRV,
243 ITextureView* pMirrorSRV,
244 SHADER_RESOURCE_VARIABLE_TYPE VarType,
245 bool IsImmutable)
246 {
247 auto* pEnv = TestingEnvironment::GetInstance();
248 auto* pContext = pEnv->GetDeviceContext();
249 auto* pDevice = pEnv->GetDevice();
250 auto* pSwapChain = pEnv->GetSwapChain();
251
252 static FastRandFloat Rnd{0, 0, 1};
253
254 const float ClearColor[] = {Rnd(), Rnd(), Rnd(), Rnd()};
255 RenderDrawCommandReference(pSwapChain, ClearColor);
256
257 GraphicsPipelineStateCreateInfo PSOCreateInfo;
258
259 auto& PSODesc = PSOCreateInfo.PSODesc;
260 auto& GraphicsPipeline = PSOCreateInfo.GraphicsPipeline;
261
262 PSODesc.Name = "Sampler correctness test";
263
264 PSODesc.PipelineType = PIPELINE_TYPE_GRAPHICS;
265 GraphicsPipeline.NumRenderTargets = 1;
266 GraphicsPipeline.RTVFormats[0] = pSwapChain->GetDesc().ColorBufferFormat;
267 GraphicsPipeline.PrimitiveTopology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
268 GraphicsPipeline.RasterizerDesc.CullMode = CULL_MODE_NONE;
269 GraphicsPipeline.DepthStencilDesc.DepthEnable = False;
270
271
272 ShaderResourceVariableDesc Variables[] =
273 {
274 {SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Tex2DClamp", VarType},
275 {SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Tex2DWrap", VarType},
276 {SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Tex2DMirror", VarType} //
277 };
278 PSODesc.ResourceLayout.NumVariables = _countof(Variables);
279 PSODesc.ResourceLayout.Variables = Variables;
280
281 std::vector<ImmutableSamplerDesc> ImtblSamplers;
282 if (IsImmutable)
283 {
284 SamplerDesc ClampSamDesc;
285 ClampSamDesc.Name = "Clamp sampler";
286 ClampSamDesc.AddressU = TEXTURE_ADDRESS_CLAMP;
287 ClampSamDesc.AddressV = TEXTURE_ADDRESS_CLAMP;
288 ClampSamDesc.AddressW = TEXTURE_ADDRESS_CLAMP;
289
290 SamplerDesc WrapSamDesc;
291 WrapSamDesc.Name = "Wrap sampler";
292 WrapSamDesc.AddressU = TEXTURE_ADDRESS_WRAP;
293 WrapSamDesc.AddressV = TEXTURE_ADDRESS_WRAP;
294 WrapSamDesc.AddressW = TEXTURE_ADDRESS_WRAP;
295
296 SamplerDesc MirrorSamDesc;
297 MirrorSamDesc.Name = "Mirror sampler";
298 MirrorSamDesc.AddressU = TEXTURE_ADDRESS_MIRROR;
299 MirrorSamDesc.AddressV = TEXTURE_ADDRESS_MIRROR;
300 MirrorSamDesc.AddressW = TEXTURE_ADDRESS_MIRROR;
301
302 ImtblSamplers.emplace_back(SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Tex2DClamp", ClampSamDesc);
303 ImtblSamplers.emplace_back(SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Tex2DWrap", WrapSamDesc);
304 ImtblSamplers.emplace_back(SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Tex2DMirror", MirrorSamDesc);
305 PSODesc.ResourceLayout.ImmutableSamplers = ImtblSamplers.data();
306 PSODesc.ResourceLayout.NumImmutableSamplers = static_cast<Uint32>(ImtblSamplers.size());
307 }
308
309 PSOCreateInfo.pVS = pVS;
310 PSOCreateInfo.pPS = pPS;
311
312 RefCntAutoPtr<IPipelineState> pPSO;
313 pDevice->CreateGraphicsPipelineState(PSOCreateInfo, &pPSO);
314 ASSERT_TRUE(pPSO != nullptr);
315
316 RefCntAutoPtr<IShaderResourceBinding> pSRB;
317 pPSO->CreateShaderResourceBinding(&pSRB, false);
318 ASSERT_TRUE(pSRB != nullptr);
319
320 if (VarType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC)
321 {
322 pPSO->GetStaticVariableByName(SHADER_TYPE_VERTEX, "g_Tex2DClamp")->Set(IsImmutable ? pDefaultSRV : pClampSRV);
323 pPSO->GetStaticVariableByName(SHADER_TYPE_VERTEX, "g_Tex2DWrap")->Set(IsImmutable ? pDefaultSRV : pWrapSRV);
324 pPSO->GetStaticVariableByName(SHADER_TYPE_VERTEX, "g_Tex2DMirror")->Set(IsImmutable ? pDefaultSRV : pMirrorSRV);
325 }
326 else
327 {
328 pSRB->GetVariableByName(SHADER_TYPE_VERTEX, "g_Tex2DClamp")->Set(IsImmutable ? pDefaultSRV : pClampSRV);
329 pSRB->GetVariableByName(SHADER_TYPE_VERTEX, "g_Tex2DWrap")->Set(IsImmutable ? pDefaultSRV : pWrapSRV);
330 pSRB->GetVariableByName(SHADER_TYPE_VERTEX, "g_Tex2DMirror")->Set(IsImmutable ? pDefaultSRV : pMirrorSRV);
331 }
332 pPSO->InitializeStaticSRBResources(pSRB);
333
334 ITextureView* pRTVs[] = {pSwapChain->GetCurrentBackBufferRTV()};
335 pContext->SetRenderTargets(1, pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
336 pContext->ClearRenderTarget(pRTVs[0], ClearColor, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
337
338 pContext->SetPipelineState(pPSO);
339 pContext->CommitShaderResources(pSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
340
341 DrawAttribs drawAttrs{6, DRAW_FLAG_VERIFY_ALL};
342 pContext->Draw(drawAttrs);
343
344 pSwapChain->Present();
345 }
346
347 TEST(SamplerTest, Correctness)
348 {
349 auto* pEnv = TestingEnvironment::GetInstance();
350 auto* pDevice = pEnv->GetDevice();
351
352 RefCntAutoPtr<IShaderSourceInputStreamFactory> pShaderSourceFactory;
353 pDevice->GetEngineFactory()->CreateDefaultShaderSourceStreamFactory("shaders", &pShaderSourceFactory);
354
355 ShaderCreateInfo ShaderCI;
356 ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;
357 ShaderCI.ShaderCompiler = pEnv->GetDefaultCompiler(ShaderCI.SourceLanguage);
358 ShaderCI.UseCombinedTextureSamplers = true;
359 ShaderCI.pShaderSourceStreamFactory = pShaderSourceFactory;
360 ShaderCI.FilePath = "SamplerCorrectness.hlsl";
361
362 RefCntAutoPtr<IShader> pVS;
363 {
364 ShaderCI.Desc.ShaderType = SHADER_TYPE_VERTEX;
365 ShaderCI.EntryPoint = "VSMain";
366 ShaderCI.Desc.Name = "Sampler correctness test - VS";
367 pDevice->CreateShader(ShaderCI, &pVS);
368 ASSERT_NE(pVS, nullptr);
369 }
370
371 RefCntAutoPtr<IShader> pPS;
372 {
373 ShaderCI.Desc.ShaderType = SHADER_TYPE_PIXEL;
374 ShaderCI.EntryPoint = "PSMain";
375 ShaderCI.Desc.Name = "Sampler correctness test - PS";
376 pDevice->CreateShader(ShaderCI, &pPS);
377 ASSERT_NE(pPS, nullptr);
378 }
379
380 constexpr Uint32 TexDim = 128;
381
382 std::vector<Uint32> TexData(TexDim * TexDim);
383 for (Uint32 x = 0; x < TexDim; ++x)
384 {
385 for (Uint32 y = 0; y < TexDim; ++y)
386 {
387 // clang-format off
388 Uint32 r = (x < TexDim / 2 && y < TexDim / 2) ? 255 : 0;
389 Uint32 g = (x >= TexDim / 2 && y < TexDim / 2) ? 255 : 0;
390 Uint32 b = (x < TexDim / 2 && y >= TexDim / 2) ? 255 : 0;
391 Uint32 a = (x >= TexDim / 2 && y >= TexDim / 2) ? 255 : 0;
392 // clang-format on
393 TexData[x + y * TexDim] = r | (g << 8) | (b << 16) | (a << 24);
394 }
395 }
396 auto pTexture = pEnv->CreateTexture("Sampler correctness test", TEX_FORMAT_RGBA8_UNORM, BIND_SHADER_RESOURCE, TexDim, TexDim, TexData.data());
397 ASSERT_NE(pTexture, nullptr);
398
399
400 auto CreateSamplerView = [&](TEXTURE_ADDRESS_MODE AddressMode, const char* SamName, const char* ViewName) -> RefCntAutoPtr<ITextureView> //
401 {
402 SamplerDesc SamDesc;
403 SamDesc.Name = SamName;
404 SamDesc.AddressU = AddressMode;
405 SamDesc.AddressV = AddressMode;
406 SamDesc.AddressW = AddressMode;
407 RefCntAutoPtr<ISampler> pSampler;
408 pDevice->CreateSampler(SamDesc, &pSampler);
409 if (!pSampler)
410 return {};
411
412 TextureViewDesc ViewDesc;
413 ViewDesc.ViewType = TEXTURE_VIEW_SHADER_RESOURCE;
414 ViewDesc.Name = ViewName;
415
416 RefCntAutoPtr<ITextureView> pSRV;
417 pTexture->CreateView(ViewDesc, &pSRV);
418 if (pSRV)
419 {
420 pSRV->SetSampler(pSampler);
421 }
422
423 return pSRV;
424 };
425
426 auto pClampSRV = CreateSamplerView(TEXTURE_ADDRESS_CLAMP, "Clamp sampler", "Clamp view");
427 auto pWrapSRV = CreateSamplerView(TEXTURE_ADDRESS_WRAP, "Wrap sampler", "Wrap view");
428 auto pMirrorSRV = CreateSamplerView(TEXTURE_ADDRESS_MIRROR, "Mirror sampler", "Mirror view");
429
430 for (Uint32 IsImmutable = 0; IsImmutable < 2; ++IsImmutable)
431 {
432 for (Uint32 var_type = 0; var_type < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; ++var_type)
433 {
434 const auto VarType = static_cast<SHADER_RESOURCE_VARIABLE_TYPE>(var_type);
435 TestSamplerCorrectness(pVS,
436 pPS,
437 pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE),
438 pClampSRV,
439 pWrapSRV,
440 pMirrorSRV,
441 VarType,
442 IsImmutable != 0);
443 std::cout << TestingEnvironment::GetCurrentTestStatusString() << ' '
444 << " Var type: " << GetShaderVariableTypeLiteralName(VarType) << ','
445 << " Immutable: " << (IsImmutable ? "Yes" : "No") << std::endl;
446 }
447 }
448 }
449
450 } // namespace