1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2014 The Android Open Source Project
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Texture test utilities.
24 *//*--------------------------------------------------------------------*/
25
26 #include "vktTextureTestUtil.hpp"
27
28 #include "deFilePath.hpp"
29 #include "deMath.h"
30 #include "tcuCompressedTexture.hpp"
31 #include "tcuImageIO.hpp"
32 #include "tcuStringTemplate.hpp"
33 #include "tcuTestLog.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkImageUtil.hpp"
36 #include "vkPrograms.hpp"
37 #include "vkQueryUtil.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include <map>
41 #include <string>
42 #include <vector>
43
44 using tcu::TestLog;
45
46 using namespace vk;
47 using namespace glu::TextureTestUtil;
48
49 namespace vkt
50 {
51 namespace texture
52 {
53 namespace util
54 {
55
56 struct ShaderParameters {
57 float bias; //!< User-supplied bias.
58 float ref; //!< Reference value for shadow lookups.
59 tcu::Vec2 padding; //!< Shader uniform padding.
60 tcu::Vec4 colorScale; //!< Scale for texture color values.
61 tcu::Vec4 colorBias; //!< Bias for texture color values.
62 };
63
getProgramName(Program program)64 const char* getProgramName(Program program)
65 {
66 switch (program)
67 {
68 case PROGRAM_2D_FLOAT: return "2D_FLOAT";
69 case PROGRAM_2D_INT: return "2D_INT";
70 case PROGRAM_2D_UINT: return "2D_UINT";
71 case PROGRAM_2D_SHADOW: return "2D_SHADOW";
72 case PROGRAM_2D_FLOAT_BIAS: return "2D_FLOAT_BIAS";
73 case PROGRAM_2D_INT_BIAS: return "2D_INT_BIAS";
74 case PROGRAM_2D_UINT_BIAS: return "2D_UINT_BIAS";
75 case PROGRAM_2D_SHADOW_BIAS: return "2D_SHADOW_BIAS";
76 case PROGRAM_1D_FLOAT: return "1D_FLOAT";
77 case PROGRAM_1D_INT: return "1D_INT";
78 case PROGRAM_1D_UINT: return "1D_UINT";
79 case PROGRAM_1D_SHADOW: return "1D_SHADOW";
80 case PROGRAM_1D_FLOAT_BIAS: return "1D_FLOAT_BIAS";
81 case PROGRAM_1D_INT_BIAS: return "1D_INT_BIAS";
82 case PROGRAM_1D_UINT_BIAS: return "1D_UINT_BIAS";
83 case PROGRAM_1D_SHADOW_BIAS: return "1D_SHADOW_BIAS";
84 case PROGRAM_CUBE_FLOAT: return "CUBE_FLOAT";
85 case PROGRAM_CUBE_INT: return "CUBE_INT";
86 case PROGRAM_CUBE_UINT: return "CUBE_UINT";
87 case PROGRAM_CUBE_SHADOW: return "CUBE_SHADOW";
88 case PROGRAM_CUBE_FLOAT_BIAS: return "CUBE_FLOAT_BIAS";
89 case PROGRAM_CUBE_INT_BIAS: return "CUBE_INT_BIAS";
90 case PROGRAM_CUBE_UINT_BIAS: return "CUBE_UINT_BIAS";
91 case PROGRAM_CUBE_SHADOW_BIAS: return "CUBE_SHADOW_BIAS";
92 case PROGRAM_2D_ARRAY_FLOAT: return "2D_ARRAY_FLOAT";
93 case PROGRAM_2D_ARRAY_INT: return "2D_ARRAY_INT";
94 case PROGRAM_2D_ARRAY_UINT: return "2D_ARRAY_UINT";
95 case PROGRAM_2D_ARRAY_SHADOW: return "2D_ARRAY_SHADOW";
96 case PROGRAM_3D_FLOAT: return "3D_FLOAT";
97 case PROGRAM_3D_INT: return "3D_INT";
98 case PROGRAM_3D_UINT: return "3D_UINT";
99 case PROGRAM_3D_FLOAT_BIAS: return "3D_FLOAT_BIAS";
100 case PROGRAM_3D_INT_BIAS: return "3D_INT_BIAS";
101 case PROGRAM_3D_UINT_BIAS: return "3D_UINT_BIAS";
102 case PROGRAM_CUBE_ARRAY_FLOAT: return "CUBE_ARRAY_FLOAT";
103 case PROGRAM_CUBE_ARRAY_INT: return "CUBE_ARRAY_INT";
104 case PROGRAM_CUBE_ARRAY_UINT: return "CUBE_ARRAY_UINT";
105 case PROGRAM_CUBE_ARRAY_SHADOW: return "CUBE_ARRAY_SHADOW";
106 case PROGRAM_1D_ARRAY_FLOAT: return "1D_ARRAY_FLOAT";
107 case PROGRAM_1D_ARRAY_INT: return "1D_ARRAY_INT";
108 case PROGRAM_1D_ARRAY_UINT: return "1D_ARRAY_UINT";
109 case PROGRAM_1D_ARRAY_SHADOW: return "1D_ARRAY_SHADOW";
110 case PROGRAM_BUFFER_FLOAT: return "BUFFER_FLOAT";
111 case PROGRAM_BUFFER_INT: return "BUFFER_INT";
112 case PROGRAM_BUFFER_UINT: return "BUFFER_UINT";
113 default:
114 DE_ASSERT(false);
115 }
116 return NULL;
117 }
118
textureTypeToImageViewType(TextureBinding::Type type)119 VkImageViewType textureTypeToImageViewType (TextureBinding::Type type)
120 {
121 switch (type)
122 {
123 case TextureBinding::TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D;
124 case TextureBinding::TYPE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
125 case TextureBinding::TYPE_CUBE_MAP: return VK_IMAGE_VIEW_TYPE_CUBE;
126 case TextureBinding::TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D;
127 default:
128 DE_ASSERT(false);
129 }
130
131 return VK_IMAGE_VIEW_TYPE_2D;
132 }
133
imageViewTypeToImageType(VkImageViewType type)134 VkImageType imageViewTypeToImageType (VkImageViewType type)
135 {
136 switch (type)
137 {
138 case VK_IMAGE_VIEW_TYPE_2D:
139 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
140 case VK_IMAGE_VIEW_TYPE_CUBE: return VK_IMAGE_TYPE_2D;
141 case VK_IMAGE_VIEW_TYPE_3D: return VK_IMAGE_TYPE_3D;
142 default:
143 DE_ASSERT(false);
144 }
145
146 return VK_IMAGE_TYPE_2D;
147 }
148
initializePrograms(vk::SourceCollections & programCollection,glu::Precision texCoordPrecision,const std::vector<Program> & programs)149 void initializePrograms(vk::SourceCollections& programCollection, glu::Precision texCoordPrecision, const std::vector<Program>& programs)
150 {
151 static const char* vertShaderTemplate =
152 "${VTX_HEADER}"
153 "layout(location = 0) ${VTX_IN} highp vec4 a_position;\n"
154 "layout(location = 1) ${VTX_IN} ${PRECISION} ${TEXCOORD_TYPE} a_texCoord;\n"
155 "layout(location = 0) ${VTX_OUT} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n"
156 "${VTX_OUT} gl_PerVertex { vec4 gl_Position; };\n"
157 "\n"
158 "void main (void)\n"
159 "{\n"
160 " gl_Position = a_position;\n"
161 " v_texCoord = a_texCoord;\n"
162 "}\n";
163
164 static const char* fragShaderTemplate =
165 "${FRAG_HEADER}"
166 "layout(location = 0) ${FRAG_IN} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n"
167 "layout(location = 0) out mediump vec4 ${FRAG_COLOR};\n"
168 "layout (set=0, binding=0, std140) uniform Block \n"
169 "{\n"
170 " ${PRECISION} float u_bias;\n"
171 " ${PRECISION} float u_ref;\n"
172 " ${PRECISION} vec4 u_colorScale;\n"
173 " ${PRECISION} vec4 u_colorBias;\n"
174 "};\n\n"
175 "layout (set=1, binding=0) uniform ${PRECISION} ${SAMPLER_TYPE} u_sampler;\n"
176 "void main (void)\n"
177 "{\n"
178 " ${FRAG_COLOR} = ${LOOKUP} * u_colorScale + u_colorBias;\n"
179 "}\n";
180
181 tcu::StringTemplate vertexSource (vertShaderTemplate);
182 tcu::StringTemplate fragmentSource (fragShaderTemplate);
183
184 for (std::vector<Program>::const_iterator programIt = programs.begin(); programIt != programs.end(); ++programIt)
185 {
186 Program program = *programIt;
187 std::map<std::string, std::string> params;
188
189 bool isCube = de::inRange<int>(program, PROGRAM_CUBE_FLOAT, PROGRAM_CUBE_SHADOW_BIAS);
190 bool isArray = de::inRange<int>(program, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_2D_ARRAY_SHADOW)
191 || de::inRange<int>(program, PROGRAM_1D_ARRAY_FLOAT, PROGRAM_1D_ARRAY_SHADOW);
192
193 bool is1D = de::inRange<int>(program, PROGRAM_1D_FLOAT, PROGRAM_1D_SHADOW_BIAS)
194 || de::inRange<int>(program, PROGRAM_1D_ARRAY_FLOAT, PROGRAM_1D_ARRAY_SHADOW)
195 || de::inRange<int>(program, PROGRAM_BUFFER_FLOAT, PROGRAM_BUFFER_UINT);
196
197 bool is2D = de::inRange<int>(program, PROGRAM_2D_FLOAT, PROGRAM_2D_SHADOW_BIAS)
198 || de::inRange<int>(program, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_2D_ARRAY_SHADOW);
199
200 bool is3D = de::inRange<int>(program, PROGRAM_3D_FLOAT, PROGRAM_3D_UINT_BIAS);
201 bool isCubeArray = de::inRange<int>(program, PROGRAM_CUBE_ARRAY_FLOAT, PROGRAM_CUBE_ARRAY_SHADOW);
202
203 const std::string version = glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450);
204
205 params["FRAG_HEADER"] = version + "\n";
206 params["VTX_HEADER"] = version + "\n";
207 params["VTX_IN"] = "in";
208 params["VTX_OUT"] = "out";
209 params["FRAG_IN"] = "in";
210 params["FRAG_COLOR"] = "dEQP_FragColor";
211
212 params["PRECISION"] = glu::getPrecisionName(texCoordPrecision);
213
214 if (isCubeArray)
215 params["TEXCOORD_TYPE"] = "vec4";
216 else if (isCube || (is2D && isArray) || is3D)
217 params["TEXCOORD_TYPE"] = "vec3";
218 else if ((is1D && isArray) || is2D)
219 params["TEXCOORD_TYPE"] = "vec2";
220 else if (is1D)
221 params["TEXCOORD_TYPE"] = "float";
222 else
223 DE_ASSERT(DE_FALSE);
224
225 const char* sampler = DE_NULL;
226 const char* lookup = DE_NULL;
227
228 switch (program)
229 {
230 case PROGRAM_2D_FLOAT: sampler = "sampler2D"; lookup = "texture(u_sampler, v_texCoord)"; break;
231 case PROGRAM_2D_INT: sampler = "isampler2D"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break;
232 case PROGRAM_2D_UINT: sampler = "usampler2D"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break;
233 case PROGRAM_2D_SHADOW: sampler = "sampler2DShadow"; lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)"; break;
234 case PROGRAM_2D_FLOAT_BIAS: sampler = "sampler2D"; lookup = "texture(u_sampler, v_texCoord, u_bias)"; break;
235 case PROGRAM_2D_INT_BIAS: sampler = "isampler2D"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break;
236 case PROGRAM_2D_UINT_BIAS: sampler = "usampler2D"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break;
237 case PROGRAM_2D_SHADOW_BIAS: sampler = "sampler2DShadow"; lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)"; break;
238 case PROGRAM_1D_FLOAT: sampler = "sampler1D"; lookup = "texture(u_sampler, v_texCoord)"; break;
239 case PROGRAM_1D_INT: sampler = "isampler1D"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break;
240 case PROGRAM_1D_UINT: sampler = "usampler1D"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break;
241 case PROGRAM_1D_SHADOW: sampler = "sampler1DShadow"; lookup = "vec4(texture(u_sampler, vec3(v_texCoord, 0.0, u_ref)), 0.0, 0.0, 1.0)"; break;
242 case PROGRAM_1D_FLOAT_BIAS: sampler = "sampler1D"; lookup = "texture(u_sampler, v_texCoord, u_bias)"; break;
243 case PROGRAM_1D_INT_BIAS: sampler = "isampler1D"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break;
244 case PROGRAM_1D_UINT_BIAS: sampler = "usampler1D"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break;
245 case PROGRAM_1D_SHADOW_BIAS: sampler = "sampler1DShadow"; lookup = "vec4(texture(u_sampler, vec3(v_texCoord, 0.0, u_ref), u_bias), 0.0, 0.0, 1.0)"; break;
246 case PROGRAM_CUBE_FLOAT: sampler = "samplerCube"; lookup = "texture(u_sampler, v_texCoord)"; break;
247 case PROGRAM_CUBE_INT: sampler = "isamplerCube"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break;
248 case PROGRAM_CUBE_UINT: sampler = "usamplerCube"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break;
249 case PROGRAM_CUBE_SHADOW: sampler = "samplerCubeShadow"; lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)"; break;
250 case PROGRAM_CUBE_FLOAT_BIAS: sampler = "samplerCube"; lookup = "texture(u_sampler, v_texCoord, u_bias)"; break;
251 case PROGRAM_CUBE_INT_BIAS: sampler = "isamplerCube"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break;
252 case PROGRAM_CUBE_UINT_BIAS: sampler = "usamplerCube"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break;
253 case PROGRAM_CUBE_SHADOW_BIAS: sampler = "samplerCubeShadow"; lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)"; break;
254 case PROGRAM_2D_ARRAY_FLOAT: sampler = "sampler2DArray"; lookup = "texture(u_sampler, v_texCoord)"; break;
255 case PROGRAM_2D_ARRAY_INT: sampler = "isampler2DArray"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break;
256 case PROGRAM_2D_ARRAY_UINT: sampler = "usampler2DArray"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break;
257 case PROGRAM_2D_ARRAY_SHADOW: sampler = "sampler2DArrayShadow"; lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)"; break;
258 case PROGRAM_3D_FLOAT: sampler = "sampler3D"; lookup = "texture(u_sampler, v_texCoord)"; break;
259 case PROGRAM_3D_INT: sampler = "isampler3D"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break;
260 case PROGRAM_3D_UINT: sampler = "usampler3D"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break;
261 case PROGRAM_3D_FLOAT_BIAS: sampler = "sampler3D"; lookup = "texture(u_sampler, v_texCoord, u_bias)"; break;
262 case PROGRAM_3D_INT_BIAS: sampler = "isampler3D"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break;
263 case PROGRAM_3D_UINT_BIAS: sampler = "usampler3D"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break;
264 case PROGRAM_CUBE_ARRAY_FLOAT: sampler = "samplerCubeArray"; lookup = "texture(u_sampler, v_texCoord)"; break;
265 case PROGRAM_CUBE_ARRAY_INT: sampler = "isamplerCubeArray"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break;
266 case PROGRAM_CUBE_ARRAY_UINT: sampler = "usamplerCubeArray"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break;
267 case PROGRAM_CUBE_ARRAY_SHADOW: sampler = "samplerCubeArrayShadow"; lookup = "vec4(texture(u_sampler, v_texCoord, u_ref), 0.0, 0.0, 1.0)"; break;
268 case PROGRAM_1D_ARRAY_FLOAT: sampler = "sampler1DArray"; lookup = "texture(u_sampler, v_texCoord)"; break;
269 case PROGRAM_1D_ARRAY_INT: sampler = "isampler1DArray"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break;
270 case PROGRAM_1D_ARRAY_UINT: sampler = "usampler1DArray"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break;
271 case PROGRAM_1D_ARRAY_SHADOW: sampler = "sampler1DArrayShadow"; lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)"; break;
272 case PROGRAM_BUFFER_FLOAT: sampler = "samplerBuffer"; lookup = "texelFetch(u_sampler, int(v_texCoord))"; break;
273 case PROGRAM_BUFFER_INT: sampler = "isamplerBuffer"; lookup = "vec4(texelFetch(u_sampler, int(v_texCoord)))"; break;
274 case PROGRAM_BUFFER_UINT: sampler = "usamplerBuffer"; lookup = "vec4(texelFetch(u_sampler, int(v_texCoord)))"; break;
275 default:
276 DE_ASSERT(false);
277 }
278
279 params["SAMPLER_TYPE"] = sampler;
280 params["LOOKUP"] = lookup;
281
282 programCollection.glslSources.add("vertext_" + std::string(getProgramName(program))) << glu::VertexSource(vertexSource.specialize(params));
283 programCollection.glslSources.add("fragment_" + std::string(getProgramName(program))) << glu::FragmentSource(fragmentSource.specialize(params));
284 }
285 }
286
TextureBinding(Context & context)287 TextureBinding::TextureBinding (Context& context)
288 : m_context (context)
289 {
290 }
291
TextureBinding(Context & context,const TestTextureSp & textureData,const TextureBinding::Type type)292 TextureBinding::TextureBinding (Context& context, const TestTextureSp& textureData, const TextureBinding::Type type)
293 : m_context (context)
294 , m_type (type)
295 , m_textureData (textureData)
296 {
297 updateTextureData(m_textureData, m_type);
298 }
299
updateTextureData(const TestTextureSp & textureData,const TextureBinding::Type textureType)300 void TextureBinding::updateTextureData (const TestTextureSp& textureData, const TextureBinding::Type textureType)
301 {
302 const DeviceInterface& vkd = m_context.getDeviceInterface();
303 const VkDevice vkDevice = m_context.getDevice();
304 const VkQueue queue = m_context.getUniversalQueue();
305 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
306 Allocator& allocator = m_context.getDefaultAllocator();
307
308 m_type = textureType;
309 m_textureData = textureData;
310
311 const bool isCube = m_type == TYPE_CUBE_MAP;
312 const VkImageCreateFlags imageCreateFlags = isCube ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
313 const VkImageViewType imageViewType = textureTypeToImageViewType(textureType);
314 const VkImageType imageType = imageViewTypeToImageType(imageViewType);
315 const VkImageTiling imageTiling = VK_IMAGE_TILING_OPTIMAL;
316 const VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
317 const VkFormat format = mapTextureFormat(textureData->getTextureFormat());
318 const tcu::UVec3 textureDimension = textureData->getTextureDimension();
319 const deUint32 mipLevels = textureData->getNumLevels();
320 const deUint32 arraySize = textureData->getArraySize();
321 vk::VkImageFormatProperties imageFormatProperties;
322 const VkResult imageFormatQueryResult = m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(), format, imageType, imageTiling, imageUsageFlags, imageCreateFlags, &imageFormatProperties);
323
324 if (imageFormatQueryResult == VK_ERROR_FORMAT_NOT_SUPPORTED)
325 {
326 TCU_THROW(NotSupportedError, (std::string("Format not supported: ") + vk::getFormatName(format)).c_str());
327 }
328 else
329 VK_CHECK(imageFormatQueryResult);
330
331 if (imageFormatProperties.maxArrayLayers < arraySize)
332 TCU_THROW(NotSupportedError, ("Maximum array layers number for this format is not enough for this test."));
333
334 if (imageFormatProperties.maxMipLevels < mipLevels)
335 TCU_THROW(NotSupportedError, ("Maximum mimap level number for this format is not enough for this test."));
336
337 if (imageFormatProperties.maxExtent.width < textureDimension.x() ||
338 imageFormatProperties.maxExtent.height < textureDimension.y() ||
339 imageFormatProperties.maxExtent.depth < textureDimension.z())
340 {
341 TCU_THROW(NotSupportedError, ("Maximum image dimension for this format is not enough for this test."));
342 }
343
344 // Create image
345 const VkImageCreateInfo imageParams =
346 {
347 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
348 DE_NULL, // const void* pNext;
349 imageCreateFlags, // VkImageCreateFlags flags;
350 imageType, // VkImageType imageType;
351 format, // VkFormat format;
352 { // VkExtent3D extent;
353 (deUint32)textureDimension.x(),
354 (deUint32)textureDimension.y(),
355 (deUint32)textureDimension.z()
356 },
357 mipLevels, // deUint32 mipLevels;
358 arraySize, // deUint32 arrayLayers;
359 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
360 imageTiling, // VkImageTiling tiling;
361 imageUsageFlags, // VkImageUsageFlags usage;
362 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
363 1u, // deUint32 queueFamilyIndexCount;
364 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
365 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
366 };
367
368 m_textureImage = createImage(vkd, vkDevice, &imageParams);
369 m_textureImageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_textureImage), MemoryRequirement::Any);
370 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_textureImage, m_textureImageMemory->getMemory(), m_textureImageMemory->getOffset()));
371
372 updateTextureViewMipLevels(0, mipLevels - 1);
373
374 pipeline::uploadTestTexture(vkd, vkDevice, queue, queueFamilyIndex, allocator, *m_textureData, *m_textureImage);
375 }
376
updateTextureViewMipLevels(deUint32 baseLevel,deUint32 maxLevel)377 void TextureBinding::updateTextureViewMipLevels (deUint32 baseLevel, deUint32 maxLevel)
378 {
379 const DeviceInterface& vkd = m_context.getDeviceInterface();
380 const VkDevice vkDevice = m_context.getDevice();
381 const vk::VkImageViewType imageViewType = textureTypeToImageViewType(m_type);
382 const vk::VkFormat format = mapTextureFormat(m_textureData->getTextureFormat());
383 const bool isShadowTexture = tcu::hasDepthComponent(m_textureData->getTextureFormat().order);
384 const VkImageAspectFlags aspectMask = isShadowTexture ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
385 const deUint32 layerCount = m_textureData->getArraySize();
386 const vk::VkImageViewCreateInfo viewParams =
387 {
388 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
389 NULL, // const voide* pNext;
390 0u, // VkImageViewCreateFlags flags;
391 *m_textureImage, // VkImage image;
392 imageViewType, // VkImageViewType viewType;
393 format, // VkFormat format;
394 makeComponentMappingRGBA(), // VkComponentMapping components;
395 {
396 aspectMask, // VkImageAspectFlags aspectMask;
397 baseLevel, // deUint32 baseMipLevel;
398 maxLevel-baseLevel+1, // deUint32 levelCount;
399 0, // deUint32 baseArrayLayer;
400 layerCount // deUint32 layerCount;
401 }, // VkImageSubresourceRange subresourceRange;
402 };
403
404 m_textureImageView = createImageView(vkd, vkDevice, &viewParams);
405 }
406
407 const deUint16 TextureRenderer::s_vertexIndices[6] = { 0, 1, 2, 2, 1, 3 };
408 const VkDeviceSize TextureRenderer::s_vertexIndexBufferSize = sizeof(TextureRenderer::s_vertexIndices);
409
TextureRenderer(Context & context,VkSampleCountFlagBits sampleCount,deUint32 renderWidth,deUint32 renderHeight)410 TextureRenderer::TextureRenderer (Context& context, VkSampleCountFlagBits sampleCount, deUint32 renderWidth, deUint32 renderHeight)
411 : m_context (context)
412 , m_log (context.getTestContext().getLog())
413 , m_renderWidth (renderWidth)
414 , m_renderHeight (renderHeight)
415 , m_sampleCount (sampleCount)
416 , m_multisampling (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
417 , m_imageFormat (VK_FORMAT_R8G8B8A8_UNORM)
418 , m_textureFormat (vk::mapVkFormat(m_imageFormat))
419 , m_uniformBufferSize (sizeof(ShaderParameters))
420 , m_resultBufferSize (renderWidth * renderHeight * m_textureFormat.getPixelSize())
421 , m_viewportOffsetX (0.0f)
422 , m_viewportOffsetY (0.0f)
423 , m_viewportWidth ((float)renderWidth)
424 , m_viewportHeight ((float)renderHeight)
425 {
426 const DeviceInterface& vkd = m_context.getDeviceInterface();
427 const VkDevice vkDevice = m_context.getDevice();
428 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
429 Allocator& allocator = m_context.getDefaultAllocator();
430
431 // Command Pool
432 {
433 const VkCommandPoolCreateInfo cmdPoolCreateInfo =
434 {
435 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
436 DE_NULL, // const void* pNext;
437 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags;
438 queueFamilyIndex // deUint32 queueFamilyIndex;
439 };
440
441 m_commandPool = createCommandPool(vkd, vkDevice, &cmdPoolCreateInfo, DE_NULL);
442 }
443
444 // Image
445 {
446 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
447 VkImageFormatProperties properties;
448
449 if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
450 m_imageFormat,
451 VK_IMAGE_TYPE_2D,
452 VK_IMAGE_TILING_OPTIMAL,
453 imageUsage,
454 0,
455 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
456 {
457 TCU_THROW(NotSupportedError, "Format not supported");
458 }
459
460 if ((properties.sampleCounts & m_sampleCount) != m_sampleCount)
461 {
462 TCU_THROW(NotSupportedError, "Format not supported");
463 }
464
465 const VkImageCreateInfo imageCreateInfo =
466 {
467 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
468 DE_NULL, // const void* pNext;
469 0u, // VkImageCreateFlags flags;
470 VK_IMAGE_TYPE_2D, // VkImageType imageType;
471 m_imageFormat, // VkFormat format;
472 { m_renderWidth, m_renderHeight, 1u }, // VkExtent3D extent;
473 1u, // deUint32 mipLevels;
474 1u, // deUint32 arrayLayers;
475 m_sampleCount, // VkSampleCountFlagBits samples;
476 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
477 imageUsage, // VkImageUsageFlags usage;
478 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
479 1u, // deUint32 queueFamilyIndexCount;
480 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
481 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
482 };
483
484 m_image = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
485
486 m_imageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_image), MemoryRequirement::Any);
487 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_image, m_imageMemory->getMemory(), m_imageMemory->getOffset()));
488 }
489
490 // Image View
491 {
492 const VkImageViewCreateInfo imageViewCreateInfo =
493 {
494 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
495 DE_NULL, // const void* pNext;
496 0u, // VkImageViewCreateFlags flags;
497 *m_image, // VkImage image;
498 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
499 m_imageFormat, // VkFormat format;
500 makeComponentMappingRGBA(), // VkComponentMapping components;
501 {
502 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
503 0u, // deUint32 baseMipLevel;
504 1u, // deUint32 mipLevels;
505 0u, // deUint32 baseArrayLayer;
506 1u, // deUint32 arraySize;
507 }, // VkImageSubresourceRange subresourceRange;
508 };
509
510 m_imageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
511 }
512
513 if (m_multisampling)
514 {
515 {
516 // Resolved Image
517 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
518 VkImageFormatProperties properties;
519
520 if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
521 m_imageFormat,
522 VK_IMAGE_TYPE_2D,
523 VK_IMAGE_TILING_OPTIMAL,
524 imageUsage,
525 0,
526 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
527 {
528 TCU_THROW(NotSupportedError, "Format not supported");
529 }
530
531 const VkImageCreateInfo imageCreateInfo =
532 {
533 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
534 DE_NULL, // const void* pNext;
535 0u, // VkImageCreateFlags flags;
536 VK_IMAGE_TYPE_2D, // VkImageType imageType;
537 m_imageFormat, // VkFormat format;
538 { m_renderWidth, m_renderHeight, 1u }, // VkExtent3D extent;
539 1u, // deUint32 mipLevels;
540 1u, // deUint32 arrayLayers;
541 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
542 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
543 imageUsage, // VkImageUsageFlags usage;
544 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
545 1u, // deUint32 queueFamilyIndexCount;
546 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
547 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
548 };
549
550 m_resolvedImage = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
551 m_resolvedImageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_resolvedImage), MemoryRequirement::Any);
552 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_resolvedImage, m_resolvedImageMemory->getMemory(), m_resolvedImageMemory->getOffset()));
553 }
554
555 // Resolved Image View
556 {
557 const VkImageViewCreateInfo imageViewCreateInfo =
558 {
559 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
560 DE_NULL, // const void* pNext;
561 0u, // VkImageViewCreateFlags flags;
562 *m_resolvedImage, // VkImage image;
563 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
564 m_imageFormat, // VkFormat format;
565 makeComponentMappingRGBA(), // VkComponentMapping components;
566 {
567 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
568 0u, // deUint32 baseMipLevel;
569 1u, // deUint32 mipLevels;
570 0u, // deUint32 baseArrayLayer;
571 1u, // deUint32 arraySize;
572 }, // VkImageSubresourceRange subresourceRange;
573 };
574
575 m_resolvedImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
576 }
577 }
578
579 // Render Pass
580 {
581 const VkImageLayout imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
582 const VkAttachmentDescription attachmentDesc[] =
583 {
584 {
585 0u, // VkAttachmentDescriptionFlags flags;
586 m_imageFormat, // VkFormat format;
587 m_sampleCount, // VkSampleCountFlagBits samples;
588 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
589 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
590 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
591 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
592 imageLayout, // VkImageLayout initialLayout;
593 imageLayout, // VkImageLayout finalLayout;
594 },
595 {
596 0u, // VkAttachmentDescriptionFlags flags;
597 m_imageFormat, // VkFormat format;
598 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
599 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
600 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
601 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
602 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
603 imageLayout, // VkImageLayout initialLayout;
604 imageLayout, // VkImageLayout finalLayout;
605 }
606 };
607
608 const VkAttachmentReference attachmentRef =
609 {
610 0u, // deUint32 attachment;
611 imageLayout, // VkImageLayout layout;
612 };
613
614 const VkAttachmentReference resolveAttachmentRef =
615 {
616 1u, // deUint32 attachment;
617 imageLayout, // VkImageLayout layout;
618 };
619
620 const VkSubpassDescription subpassDesc =
621 {
622 0u, // VkSubpassDescriptionFlags flags;
623 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
624 0u, // deUint32 inputAttachmentCount;
625 DE_NULL, // const VkAttachmentReference* pInputAttachments;
626 1u, // deUint32 colorAttachmentCount;
627 &attachmentRef, // const VkAttachmentReference* pColorAttachments;
628 m_multisampling ? &resolveAttachmentRef : DE_NULL, // const VkAttachmentReference* pResolveAttachments;
629 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
630 0u, // deUint32 preserveAttachmentCount;
631 DE_NULL, // const VkAttachmentReference* pPreserveAttachments;
632 };
633
634 const VkRenderPassCreateInfo renderPassCreateInfo =
635 {
636 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
637 DE_NULL, // const void* pNext;
638 0u, // VkRenderPassCreateFlags flags;
639 m_multisampling ? 2u : 1u, // deUint32 attachmentCount;
640 attachmentDesc, // const VkAttachmentDescription* pAttachments;
641 1u, // deUint32 subpassCount;
642 &subpassDesc, // const VkSubpassDescription* pSubpasses;
643 0u, // deUint32 dependencyCount;
644 DE_NULL, // const VkSubpassDependency* pDependencies;
645 };
646
647 m_renderPass = createRenderPass(vkd, vkDevice, &renderPassCreateInfo, DE_NULL);
648 }
649
650 // Vertex index buffer
651 {
652 const VkBufferCreateInfo indexBufferParams =
653 {
654 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
655 DE_NULL, // const void* pNext;
656 0u, // VkBufferCreateFlags flags;
657 s_vertexIndexBufferSize, // VkDeviceSize size;
658 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage;
659 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
660 1u, // deUint32 queueFamilyCount;
661 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
662 };
663
664 m_vertexIndexBuffer = createBuffer(vkd, vkDevice, &indexBufferParams);
665 m_vertexIndexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_vertexIndexBuffer), MemoryRequirement::HostVisible);
666
667 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_vertexIndexBuffer, m_vertexIndexBufferMemory->getMemory(), m_vertexIndexBufferMemory->getOffset()));
668
669 // Load vertices into vertex buffer
670 deMemcpy(m_vertexIndexBufferMemory->getHostPtr(), s_vertexIndices, s_vertexIndexBufferSize);
671 flushMappedMemoryRange(vkd, vkDevice, m_vertexIndexBufferMemory->getMemory(), m_vertexIndexBufferMemory->getOffset(), VK_WHOLE_SIZE);
672 }
673
674 // FrameBuffer
675 {
676 const VkImageView attachments[] =
677 {
678 *m_imageView,
679 *m_resolvedImageView,
680 };
681
682 const VkFramebufferCreateInfo framebufferCreateInfo =
683 {
684 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
685 DE_NULL, // const void* pNext;
686 0u, // VkFramebufferCreateFlags flags;
687 *m_renderPass, // VkRenderPass renderPass;
688 m_multisampling ? 2u : 1u, // deUint32 attachmentCount;
689 attachments, // const VkImageView* pAttachments;
690 m_renderWidth, // deUint32 width;
691 m_renderHeight, // deUint32 height;
692 1u, // deUint32 layers;
693 };
694
695 m_frameBuffer = createFramebuffer(vkd, vkDevice, &framebufferCreateInfo, DE_NULL);
696 }
697
698 // Uniform Buffer
699 {
700 const VkBufferCreateInfo bufferCreateInfo =
701 {
702 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
703 DE_NULL, // const void* pNext;
704 0u, // VkBufferCreateFlags flags;
705 m_uniformBufferSize, // VkDeviceSize size;
706 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage;
707 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
708 1u, // deUint32 queueFamilyIndexCount;
709 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
710 };
711
712 m_uniformBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo);
713 m_uniformBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_uniformBuffer), MemoryRequirement::HostVisible);
714
715 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_uniformBuffer, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset()));
716 }
717
718 // DescriptorPool
719 {
720 DescriptorPoolBuilder descriptorPoolBuilder;
721
722 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
723 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
724 m_descriptorPool = descriptorPoolBuilder.build(vkd, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u);
725 }
726
727 // Fence
728 {
729 const VkFenceCreateInfo fenceParams =
730 {
731 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
732 DE_NULL, // const void* pNext;
733 VK_FENCE_CREATE_SIGNALED_BIT // VkFenceCreateFlags flags;
734 };
735
736 m_fence = createFence(vkd, vkDevice, &fenceParams);
737 }
738
739 // Result Buffer
740 {
741 const VkBufferCreateInfo bufferCreateInfo =
742 {
743 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
744 DE_NULL, // const void* pNext;
745 0u, // VkBufferCreateFlags flags;
746 m_resultBufferSize, // VkDeviceSize size;
747 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
748 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
749 1u, // deUint32 queueFamilyIndexCount;
750 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
751 };
752
753 m_resultBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo);
754 m_resultBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_resultBuffer), MemoryRequirement::HostVisible);
755
756 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset()));
757 }
758
759 clearImage(*m_image);
760 if(m_multisampling)
761 clearImage(*m_resolvedImage);
762 }
763
~TextureRenderer(void)764 TextureRenderer::~TextureRenderer (void)
765 {
766 }
767
clearImage(VkImage image)768 void TextureRenderer::clearImage(VkImage image)
769 {
770 const DeviceInterface& vkd = m_context.getDeviceInterface();
771 const VkDevice vkDevice = m_context.getDevice();
772 Move<VkCommandBuffer> commandBuffer;
773 const VkQueue queue = m_context.getUniversalQueue();
774
775 const VkImageSubresourceRange subResourcerange =
776 {
777 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
778 0, // deUint32 baseMipLevel;
779 1, // deUint32 levelCount;
780 0, // deUint32 baseArrayLayer;
781 1 // deUint32 layerCount;
782 };
783
784 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
785 {
786 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
787 DE_NULL, // const void* pNext;
788 *m_commandPool, // VkCommandPool commandPool;
789 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
790 1 // deUint32 commandBufferCount;
791 };
792
793 commandBuffer = allocateCommandBuffer(vkd, vkDevice, &cmdBufferAllocateInfo);
794
795 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
796 {
797 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
798 DE_NULL, // const void* pNext;
799 0u, // VkCmdBufferOptimizeFlags flags;
800 DE_NULL // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
801 };
802
803 VK_CHECK(vkd.beginCommandBuffer(*commandBuffer, &cmdBufferBeginInfo));
804
805 addImageTransitionBarrier(*commandBuffer, image,
806 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
807 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
808 0, // VkAccessFlags srcAccessMask
809 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
810 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
811 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout;
812
813 VkClearColorValue color = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f).color;
814 vkd.cmdClearColorImage(*commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &color, 1, &subResourcerange);
815
816 addImageTransitionBarrier(*commandBuffer, image,
817 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
818 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
819 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
820 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
821 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
822 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
823
824 VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
825
826 const VkSubmitInfo submitInfo =
827 {
828 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
829 DE_NULL, // const void* pNext;
830 0u, // deUint32 waitSemaphoreCount;
831 DE_NULL, // const VkSemaphore* pWaitSemaphores;
832 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
833 1u, // deUint32 commandBufferCount;
834 &commandBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
835 0u, // deUint32 signalSemaphoreCount;
836 DE_NULL, // const VkSemaphore* pSignalSemaphores;
837 };
838
839 VK_CHECK(vkd.resetFences(vkDevice, 1, &m_fence.get()));
840 VK_CHECK(vkd.queueSubmit(queue, 1, &submitInfo, *m_fence));
841 VK_CHECK(vkd.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
842 }
843
add2DTexture(const TestTexture2DSp & texture)844 void TextureRenderer::add2DTexture (const TestTexture2DSp& texture)
845 {
846 m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_2D)));
847 }
848
addCubeTexture(const TestTextureCubeSp & texture)849 void TextureRenderer::addCubeTexture (const TestTextureCubeSp& texture)
850 {
851 m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_CUBE_MAP)));
852 }
853
add2DArrayTexture(const TestTexture2DArraySp & texture)854 void TextureRenderer::add2DArrayTexture (const TestTexture2DArraySp& texture)
855 {
856 m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_2D_ARRAY)));
857 }
858
add3DTexture(const TestTexture3DSp & texture)859 void TextureRenderer::add3DTexture (const TestTexture3DSp& texture)
860 {
861 m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_3D)));
862 }
863
get2DTexture(int textureIndex) const864 const pipeline::TestTexture2D& TextureRenderer::get2DTexture (int textureIndex) const
865 {
866 DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
867 DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_2D);
868
869 return dynamic_cast<const pipeline::TestTexture2D&>(m_textureBindings[textureIndex]->getTestTexture());
870 }
871
getCubeTexture(int textureIndex) const872 const pipeline::TestTextureCube& TextureRenderer::getCubeTexture (int textureIndex) const
873 {
874 DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
875 DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_CUBE_MAP);
876
877 return dynamic_cast<const pipeline::TestTextureCube&>(m_textureBindings[textureIndex]->getTestTexture());
878 }
879
get2DArrayTexture(int textureIndex) const880 const pipeline::TestTexture2DArray& TextureRenderer::get2DArrayTexture (int textureIndex) const
881 {
882 DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
883 DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_2D_ARRAY);
884
885 return dynamic_cast<const pipeline::TestTexture2DArray&>(m_textureBindings[textureIndex]->getTestTexture());
886 }
887
get3DTexture(int textureIndex) const888 const pipeline::TestTexture3D& TextureRenderer::get3DTexture (int textureIndex) const
889 {
890 DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
891 DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_3D);
892
893 return dynamic_cast<const pipeline::TestTexture3D&>(m_textureBindings[textureIndex]->getTestTexture());
894 }
895
setViewport(float viewportX,float viewportY,float viewportW,float viewportH)896 void TextureRenderer::setViewport (float viewportX, float viewportY, float viewportW, float viewportH)
897 {
898 m_viewportHeight = viewportH;
899 m_viewportWidth = viewportW;
900 m_viewportOffsetX = viewportX;
901 m_viewportOffsetY = viewportY;
902 }
903
getTextureBinding(int textureIndex) const904 TextureBinding* TextureRenderer::getTextureBinding (int textureIndex) const
905 {
906 DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
907 return m_textureBindings[textureIndex].get();
908 }
909
getRenderWidth(void) const910 deUint32 TextureRenderer::getRenderWidth (void) const
911 {
912 return m_renderWidth;
913 }
914
getRenderHeight(void) const915 deUint32 TextureRenderer::getRenderHeight (void) const
916 {
917 return m_renderHeight;
918 }
919
makeDescriptorSet(const VkDescriptorPool descriptorPool,const VkDescriptorSetLayout setLayout) const920 Move<VkDescriptorSet> TextureRenderer::makeDescriptorSet (const VkDescriptorPool descriptorPool, const VkDescriptorSetLayout setLayout) const
921 {
922 const DeviceInterface& vkd = m_context.getDeviceInterface();
923 const VkDevice vkDevice = m_context.getDevice();
924
925 const VkDescriptorSetAllocateInfo allocateParams =
926 {
927 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType
928 DE_NULL, // const void* pNext
929 descriptorPool, // VkDescriptorPool descriptorPool
930 1u, // deUint32 descriptorSetCount
931 &setLayout, // const VkDescriptorSetLayout* pSetLayouts
932 };
933 return allocateDescriptorSet(vkd, vkDevice, &allocateParams);
934 }
935
addImageTransitionBarrier(VkCommandBuffer commandBuffer,VkImage image,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkAccessFlags srcAccessMask,VkAccessFlags dstAccessMask,VkImageLayout oldLayout,VkImageLayout newLayout) const936 void TextureRenderer::addImageTransitionBarrier(VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const
937 {
938 const DeviceInterface& vkd = m_context.getDeviceInterface();
939
940 const VkImageSubresourceRange subResourcerange =
941 {
942 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
943 0, // deUint32 baseMipLevel;
944 1, // deUint32 levelCount;
945 0, // deUint32 baseArrayLayer;
946 1 // deUint32 layerCount;
947 };
948
949 const VkImageMemoryBarrier imageBarrier =
950 {
951 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
952 DE_NULL, // const void* pNext;
953 srcAccessMask, // VkAccessFlags srcAccessMask;
954 dstAccessMask, // VkAccessFlags dstAccessMask;
955 oldLayout, // VkImageLayout oldLayout;
956 newLayout, // VkImageLayout newLayout;
957 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
958 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
959 image, // VkImage image;
960 subResourcerange // VkImageSubresourceRange subresourceRange;
961 };
962
963 vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageBarrier);
964 }
965
966
renderQuad(tcu::Surface & result,int texUnit,const float * texCoord,TextureType texType)967 void TextureRenderer::renderQuad (tcu::Surface& result, int texUnit, const float* texCoord, TextureType texType)
968 {
969 renderQuad(result, texUnit, texCoord, ReferenceParams(texType));
970 }
971
renderQuad(tcu::Surface & result,int texUnit,const float * texCoord,const ReferenceParams & params)972 void TextureRenderer::renderQuad (tcu::Surface& result, int texUnit, const float* texCoord, const ReferenceParams& params)
973 {
974 const float maxAnisotropy = 1.0f;
975 float positions[] =
976 {
977 -1.0, -1.0f, 0.0f, 1.0f,
978 -1.0f, +1.0f, 0.0f, 1.0f,
979 +1.0f, -1.0f, 0.0f, 1.0f,
980 +1.0f, +1.0f, 0.0f, 1.0f
981 };
982 renderQuad(result, positions, texUnit, texCoord, params, maxAnisotropy);
983 }
984
renderQuad(tcu::Surface & result,const float * positions,int texUnit,const float * texCoord,const glu::TextureTestUtil::ReferenceParams & params,const float maxAnisotropy)985 void TextureRenderer::renderQuad (tcu::Surface& result,
986 const float* positions,
987 int texUnit,
988 const float* texCoord,
989 const glu::TextureTestUtil::ReferenceParams& params,
990 const float maxAnisotropy)
991 {
992 const DeviceInterface& vkd = m_context.getDeviceInterface();
993 const VkDevice vkDevice = m_context.getDevice();
994 const VkQueue queue = m_context.getUniversalQueue();
995 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
996 Allocator& allocator = m_context.getDefaultAllocator();
997
998 tcu::Vec4 wCoord = params.flags & RenderParams::PROJECTED ? params.w : tcu::Vec4(1.0f);
999 bool useBias = !!(params.flags & RenderParams::USE_BIAS);
1000 bool logUniforms = !!(params.flags & RenderParams::LOG_UNIFORMS);
1001
1002 // Render quad with texture.
1003 float position[] =
1004 {
1005 positions[0]*wCoord.x(), positions[1]*wCoord.x(), positions[2], positions[3]*wCoord.x(),
1006 positions[4]*wCoord.y(), positions[5]*wCoord.y(), positions[6], positions[7]*wCoord.y(),
1007 positions[8]*wCoord.z(), positions[9]*wCoord.z(), positions[10], positions[11]*wCoord.z(),
1008 positions[12]*wCoord.w(), positions[13]*wCoord.w(), positions[14], positions[15]*wCoord.w()
1009 };
1010
1011 Program progSpec = PROGRAM_LAST;
1012 int numComps = 0;
1013
1014 if (params.texType == TEXTURETYPE_2D)
1015 {
1016 numComps = 2;
1017
1018 switch (params.samplerType)
1019 {
1020 case SAMPLERTYPE_FLOAT: progSpec = useBias ? PROGRAM_2D_FLOAT_BIAS : PROGRAM_2D_FLOAT; break;
1021 case SAMPLERTYPE_INT: progSpec = useBias ? PROGRAM_2D_INT_BIAS : PROGRAM_2D_INT; break;
1022 case SAMPLERTYPE_UINT: progSpec = useBias ? PROGRAM_2D_UINT_BIAS : PROGRAM_2D_UINT; break;
1023 case SAMPLERTYPE_SHADOW: progSpec = useBias ? PROGRAM_2D_SHADOW_BIAS : PROGRAM_2D_SHADOW; break;
1024 default: DE_ASSERT(false);
1025 }
1026 }
1027 else if (params.texType == TEXTURETYPE_1D)
1028 {
1029 numComps = 1;
1030
1031 switch (params.samplerType)
1032 {
1033 case SAMPLERTYPE_FLOAT: progSpec = useBias ? PROGRAM_1D_FLOAT_BIAS : PROGRAM_1D_FLOAT; break;
1034 case SAMPLERTYPE_INT: progSpec = useBias ? PROGRAM_1D_INT_BIAS : PROGRAM_1D_INT; break;
1035 case SAMPLERTYPE_UINT: progSpec = useBias ? PROGRAM_1D_UINT_BIAS : PROGRAM_1D_UINT; break;
1036 case SAMPLERTYPE_SHADOW: progSpec = useBias ? PROGRAM_1D_SHADOW_BIAS : PROGRAM_1D_SHADOW; break;
1037 default: DE_ASSERT(false);
1038 }
1039 }
1040 else if (params.texType == TEXTURETYPE_CUBE)
1041 {
1042 numComps = 3;
1043
1044 switch (params.samplerType)
1045 {
1046 case SAMPLERTYPE_FLOAT: progSpec = useBias ? PROGRAM_CUBE_FLOAT_BIAS : PROGRAM_CUBE_FLOAT; break;
1047 case SAMPLERTYPE_INT: progSpec = useBias ? PROGRAM_CUBE_INT_BIAS : PROGRAM_CUBE_INT; break;
1048 case SAMPLERTYPE_UINT: progSpec = useBias ? PROGRAM_CUBE_UINT_BIAS : PROGRAM_CUBE_UINT; break;
1049 case SAMPLERTYPE_SHADOW: progSpec = useBias ? PROGRAM_CUBE_SHADOW_BIAS : PROGRAM_CUBE_SHADOW; break;
1050 default: DE_ASSERT(false);
1051 }
1052 }
1053 else if (params.texType == TEXTURETYPE_3D)
1054 {
1055 numComps = 3;
1056
1057 switch (params.samplerType)
1058 {
1059 case SAMPLERTYPE_FLOAT: progSpec = useBias ? PROGRAM_3D_FLOAT_BIAS : PROGRAM_3D_FLOAT; break;
1060 case SAMPLERTYPE_INT: progSpec = useBias ? PROGRAM_3D_INT_BIAS : PROGRAM_3D_INT; break;
1061 case SAMPLERTYPE_UINT: progSpec = useBias ? PROGRAM_3D_UINT_BIAS : PROGRAM_3D_UINT; break;
1062 default: DE_ASSERT(false);
1063 }
1064 }
1065 else if (params.texType == TEXTURETYPE_2D_ARRAY)
1066 {
1067 DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
1068
1069 numComps = 3;
1070
1071 switch (params.samplerType)
1072 {
1073 case SAMPLERTYPE_FLOAT: progSpec = PROGRAM_2D_ARRAY_FLOAT; break;
1074 case SAMPLERTYPE_INT: progSpec = PROGRAM_2D_ARRAY_INT; break;
1075 case SAMPLERTYPE_UINT: progSpec = PROGRAM_2D_ARRAY_UINT; break;
1076 case SAMPLERTYPE_SHADOW: progSpec = PROGRAM_2D_ARRAY_SHADOW; break;
1077 default: DE_ASSERT(false);
1078 }
1079 }
1080 else if (params.texType == TEXTURETYPE_CUBE_ARRAY)
1081 {
1082 DE_ASSERT(!useBias);
1083
1084 numComps = 4;
1085
1086 switch (params.samplerType)
1087 {
1088 case SAMPLERTYPE_FLOAT: progSpec = PROGRAM_CUBE_ARRAY_FLOAT; break;
1089 case SAMPLERTYPE_INT: progSpec = PROGRAM_CUBE_ARRAY_INT; break;
1090 case SAMPLERTYPE_UINT: progSpec = PROGRAM_CUBE_ARRAY_UINT; break;
1091 case SAMPLERTYPE_SHADOW: progSpec = PROGRAM_CUBE_ARRAY_SHADOW; break;
1092 default: DE_ASSERT(false);
1093 }
1094 }
1095 else if (params.texType == TEXTURETYPE_1D_ARRAY)
1096 {
1097 DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
1098
1099 numComps = 2;
1100
1101 switch (params.samplerType)
1102 {
1103 case SAMPLERTYPE_FLOAT: progSpec = PROGRAM_1D_ARRAY_FLOAT; break;
1104 case SAMPLERTYPE_INT: progSpec = PROGRAM_1D_ARRAY_INT; break;
1105 case SAMPLERTYPE_UINT: progSpec = PROGRAM_1D_ARRAY_UINT; break;
1106 case SAMPLERTYPE_SHADOW: progSpec = PROGRAM_1D_ARRAY_SHADOW; break;
1107 default: DE_ASSERT(false);
1108 }
1109 }
1110 else if (params.texType == TEXTURETYPE_BUFFER)
1111 {
1112 numComps = 1;
1113
1114 switch (params.samplerType)
1115 {
1116 case SAMPLERTYPE_FETCH_FLOAT: progSpec = PROGRAM_BUFFER_FLOAT; break;
1117 case SAMPLERTYPE_FETCH_INT: progSpec = PROGRAM_BUFFER_INT; break;
1118 case SAMPLERTYPE_FETCH_UINT: progSpec = PROGRAM_BUFFER_UINT; break;
1119 default: DE_ASSERT(false);
1120 }
1121 }
1122 else
1123 DE_ASSERT(DE_FALSE);
1124
1125 Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("vertext_" + std::string(getProgramName(progSpec))), 0));
1126 Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("fragment_" + std::string(getProgramName(progSpec))), 0));
1127
1128 Move<VkSampler> sampler;
1129 Move<VkDescriptorSet> descriptorSet[2];
1130 Move<VkDescriptorSetLayout> descriptorSetLayout[2];
1131 Move<VkPipelineLayout> pipelineLayout;
1132
1133 Move<VkCommandBuffer> commandBuffer;
1134 Move<VkPipeline> graphicsPipeline;
1135 Move<VkBuffer> vertexBuffer;
1136 de::MovePtr<Allocation> vertexBufferMemory;
1137 const deUint32 positionDataSize = deUint32(sizeof(float) * 4 * 4);
1138 const deUint32 textureCoordDataSize = deUint32(sizeof(float) * numComps * 4);
1139
1140 const VkPhysicalDeviceProperties properties = m_context.getDeviceProperties();
1141
1142 if (positionDataSize > properties.limits.maxVertexInputAttributeOffset)
1143 {
1144 std::stringstream message;
1145 message << "Larger vertex input attribute offset is needed (" << positionDataSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ").";
1146 TCU_THROW(NotSupportedError, message.str().c_str());
1147 }
1148
1149 // Create Graphics Pipeline
1150 {
1151 const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
1152 {
1153 {
1154 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1155 DE_NULL, // const void* pNext;
1156 0, // VkPipelineShaderStageCreateFlags flags;
1157 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStage stage;
1158 *vertexShaderModule, // VkShaderModule shader;
1159 "main", // const char* pName;
1160 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1161 },
1162 {
1163 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1164 DE_NULL, // const void* pNext;
1165 0, // VkPipelineShaderStageCreateFlags flags;
1166 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStage stage;
1167 *fragmentShaderModule, // VkShaderModule shader;
1168 "main", // const char* pName;
1169 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1170 }
1171 };
1172
1173 const deUint32 vertexPositionStrideSize = deUint32(sizeof(tcu::Vec4));
1174 const deUint32 vertexTextureStrideSize = deUint32(numComps * sizeof(float));
1175
1176 const VkVertexInputBindingDescription vertexInputBindingDescription[2] =
1177 {
1178 {
1179 0u, // deUint32 binding;
1180 vertexPositionStrideSize, // deUint32 strideInBytes;
1181 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
1182 },
1183 {
1184 1u, // deUint32 binding;
1185 vertexTextureStrideSize, // deUint32 strideInBytes;
1186 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
1187 }
1188 };
1189
1190 VkFormat textureCoordinateFormat = VK_FORMAT_R32G32B32A32_SFLOAT;
1191
1192 switch (numComps) {
1193 case 1: textureCoordinateFormat = VK_FORMAT_R32_SFLOAT; break;
1194 case 2: textureCoordinateFormat = VK_FORMAT_R32G32_SFLOAT; break;
1195 case 3: textureCoordinateFormat = VK_FORMAT_R32G32B32_SFLOAT; break;
1196 case 4: textureCoordinateFormat = VK_FORMAT_R32G32B32A32_SFLOAT; break;
1197 default:
1198 DE_ASSERT(false);
1199 }
1200
1201 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
1202 {
1203 {
1204 0u, // deUint32 location;
1205 0u, // deUint32 binding;
1206 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1207 0u // deUint32 offsetInBytes;
1208 },
1209 {
1210 1u, // deUint32 location;
1211 1u, // deUint32 binding;
1212 textureCoordinateFormat, // VkFormat format;
1213 positionDataSize // deUint32 offsetInBytes;
1214 }
1215 };
1216
1217 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1218 {
1219 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1220 DE_NULL, // const void* pNext;
1221 0, // VkPipelineVertexInputStateCreateFlags flags;
1222 2u, // deUint32 bindingCount;
1223 vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1224 2u, // deUint32 attributeCount;
1225 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1226 };
1227
1228 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1229 {
1230 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1231 DE_NULL, // const void* pNext;
1232 0, // VkPipelineInputAssemblyStateCreateFlags flags;
1233 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
1234 VK_FALSE // VkBool32 primitiveRestartEnable;
1235 };
1236
1237 const VkViewport viewport =
1238 {
1239 m_viewportOffsetX, // float originX;
1240 m_viewportOffsetY, // float originY;
1241 m_viewportWidth, // float width;
1242 m_viewportHeight, // float height;
1243 0.0f, // float minDepth;
1244 1.0f // float maxDepth;
1245 };
1246
1247 const VkRect2D scissor =
1248 {
1249 { 0, 0 }, // VkOffset2D offset;
1250 { m_renderWidth, m_renderHeight } // VkExtent2D extent;
1251 };
1252
1253 const VkPipelineViewportStateCreateInfo viewportStateParams =
1254 {
1255 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1256 DE_NULL, // const void* pNext;
1257 0, // VkPipelineViewportStateCreateFlags flags;
1258 1u, // deUint32 viewportCount;
1259 &viewport, // const VkViewport* pViewports;
1260 1u, // deUint32 scissorCount;
1261 &scissor // const VkRect2D* pScissors;
1262 };
1263
1264 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1265 {
1266 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1267 DE_NULL, // const void* pNext;
1268 0u, // VkPipelineMultisampleStateCreateFlags flags;
1269 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
1270 VK_FALSE, // VkBool32 sampleShadingEnable;
1271 0.0f, // float minSampleShading;
1272 DE_NULL, // const VkSampleMask* pSampleMask;
1273 VK_FALSE, // VkBool32 alphaToCoverageEnable;
1274 VK_FALSE // VkBool32 alphaToOneEnable;
1275 };
1276
1277 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
1278 {
1279 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1280 DE_NULL, // const void* pNext;
1281 0, // VkPipelineRasterizationStateCreateFlags flags;
1282 VK_FALSE, // VkBool32 depthClipEnable;
1283 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
1284 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
1285 VK_CULL_MODE_NONE, // VkCullMode cullMode;
1286 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
1287 VK_FALSE, // VkBool32 depthBiasEnable;
1288 0.0f, // float depthBias;
1289 0.0f, // float depthBiasClamp;
1290 0.0f, // float slopeScaledDepthBias;
1291 1.0f, // float lineWidth;
1292 };
1293
1294 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1295 {
1296 VK_FALSE, // VkBool32 blendEnable;
1297 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
1298 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor;
1299 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
1300 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
1301 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha;
1302 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
1303 (VK_COLOR_COMPONENT_R_BIT |
1304 VK_COLOR_COMPONENT_G_BIT |
1305 VK_COLOR_COMPONENT_B_BIT |
1306 VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask;
1307 };
1308
1309 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1310 {
1311 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1312 DE_NULL, // const void* pNext;
1313 0, // VkPipelineColorBlendStateCreateFlags flags;
1314 VK_FALSE, // VkBool32 logicOpEnable;
1315 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1316 1u, // deUint32 attachmentCount;
1317 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1318 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
1319 };
1320
1321 VkSamplerCreateInfo samplerCreateInfo = mapSampler(params.sampler, m_textureBindings[texUnit]->getTestTexture().getTextureFormat(), params.minLod, params.maxLod);
1322
1323 if (maxAnisotropy > 1.0f)
1324 {
1325 samplerCreateInfo.anisotropyEnable = VK_TRUE;
1326 samplerCreateInfo.maxAnisotropy = maxAnisotropy;
1327 }
1328
1329 if (samplerCreateInfo.magFilter == VK_FILTER_LINEAR || samplerCreateInfo.minFilter == VK_FILTER_LINEAR || samplerCreateInfo.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR)
1330 {
1331 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), mapTextureFormat(m_textureBindings[texUnit]->getTestTexture().getTextureFormat()));
1332 if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
1333 TCU_THROW(NotSupportedError, "Linear filtering for this image format is not supported");
1334 }
1335
1336 sampler = createSampler(vkd, vkDevice, &samplerCreateInfo);
1337
1338 descriptorSetLayout[0] = DescriptorSetLayoutBuilder()
1339 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
1340 .build(vkd, vkDevice);
1341
1342 descriptorSetLayout[1] = DescriptorSetLayoutBuilder()
1343 .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &sampler.get())
1344 .build(vkd, vkDevice);
1345
1346
1347 descriptorSet[0] = makeDescriptorSet(*m_descriptorPool, *descriptorSetLayout[0]);
1348 descriptorSet[1] = makeDescriptorSet(*m_descriptorPool, *descriptorSetLayout[1]);
1349
1350 {
1351 const VkDescriptorBufferInfo descriptorBufferInfo =
1352 {
1353 *m_uniformBuffer, // VkBuffer buffer;
1354 0u, // VkDeviceSize offset;
1355 VK_WHOLE_SIZE // VkDeviceSize range;
1356 };
1357
1358 DescriptorSetUpdateBuilder()
1359 .writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &descriptorBufferInfo)
1360 .update(vkd, vkDevice);
1361 }
1362
1363 {
1364 VkDescriptorImageInfo descriptorImageInfo =
1365 {
1366 *sampler, // VkSampler sampler;
1367 m_textureBindings[texUnit]->getImageView(), // VkImageView imageView;
1368 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout;
1369 };
1370
1371 DescriptorSetUpdateBuilder()
1372 .writeSingle(*descriptorSet[1], DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfo)
1373 .update(vkd, vkDevice);
1374 }
1375
1376 // Pipeline Layout
1377 {
1378 VkDescriptorSetLayout descriptorSetLayouts[2] =
1379 {
1380 *descriptorSetLayout[0],
1381 *descriptorSetLayout[1]
1382 };
1383
1384 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1385 {
1386 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1387 DE_NULL, // const void* pNext;
1388 0u, // VkPipelineLayoutCreateFlags flags;
1389 2u, // deUint32 descriptorSetCount;
1390 descriptorSetLayouts, // const VkDescriptorSetLayout* pSetLayouts;
1391 0u, // deUint32 pushConstantRangeCount;
1392 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1393 };
1394
1395 pipelineLayout = createPipelineLayout(vkd, vkDevice, &pipelineLayoutCreateInfo);
1396 }
1397
1398 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1399 {
1400 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1401 DE_NULL, // const void* pNext;
1402 0u, // VkPipelineCreateFlags flags;
1403 2u, // deUint32 stageCount;
1404 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
1405 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1406 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1407 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1408 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
1409 &rasterizationStateCreateInfo, // const VkPipelineRasterStateCreateInfo* pRasterizationState;
1410 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1411 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1412 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1413 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1414 *pipelineLayout, // VkPipelineLayout layout;
1415 *m_renderPass, // VkRenderPass renderPass;
1416 0u, // deUint32 subpass;
1417 0u, // VkPipeline basePipelineHandle;
1418 0u // deInt32 basePipelineIndex;
1419 };
1420
1421 graphicsPipeline = createGraphicsPipeline(vkd, vkDevice, DE_NULL, &graphicsPipelineParams);
1422 }
1423
1424 // Create Vertex Buffer
1425 {
1426 const VkBufferCreateInfo vertexBufferParams =
1427 {
1428 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1429 DE_NULL, // const void* pNext;
1430 0u, // VkBufferCreateFlags flags;
1431 positionDataSize + textureCoordDataSize, // VkDeviceSize size;
1432 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1433 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1434 1u, // deUint32 queueFamilyCount;
1435 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1436 };
1437
1438 vertexBuffer = createBuffer(vkd, vkDevice, &vertexBufferParams);
1439 vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
1440
1441 VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
1442
1443 // Load vertices into vertex buffer
1444 deMemcpy(vertexBufferMemory->getHostPtr(), position, positionDataSize);
1445 deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) + positionDataSize, texCoord, textureCoordDataSize);
1446 flushMappedMemoryRange(vkd, vkDevice, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset(), VK_WHOLE_SIZE);
1447 }
1448
1449 // Create Command Buffer
1450 {
1451 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
1452 {
1453 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1454 DE_NULL, // const void* pNext;
1455 *m_commandPool, // VkCommandPool commandPool;
1456 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
1457 1 // deUint32 commandBufferCount;
1458 };
1459
1460 commandBuffer = allocateCommandBuffer(vkd, vkDevice, &cmdBufferAllocateInfo);
1461 }
1462
1463 // Begin Command Buffer
1464 {
1465 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1466 {
1467 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1468 DE_NULL, // const void* pNext;
1469 0u, // VkCmdBufferOptimizeFlags flags;
1470 DE_NULL // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
1471 };
1472
1473 VK_CHECK(vkd.beginCommandBuffer(*commandBuffer, &cmdBufferBeginInfo));
1474 }
1475
1476 // Begin Render Pass
1477 {
1478 const VkRenderPassBeginInfo renderPassBeginInfo =
1479 {
1480 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1481 DE_NULL, // const void* pNext;
1482 *m_renderPass, // VkRenderPass renderPass;
1483 *m_frameBuffer, // VkFramebuffer framebuffer;
1484 {
1485 { 0, 0 },
1486 { m_renderWidth, m_renderHeight }
1487 }, // VkRect2D renderArea;
1488 0u, // deUint32 clearValueCount;
1489 DE_NULL // const VkClearValue* pClearValues;
1490 };
1491
1492 vkd.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1493 }
1494
1495 const VkDeviceSize vertexBufferOffset = 0;
1496
1497 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
1498 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &descriptorSet[0].get(), 0u, DE_NULL);
1499 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 1u, 1, &descriptorSet[1].get(), 0u, DE_NULL);
1500 vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
1501 vkd.cmdBindVertexBuffers(*commandBuffer, 1, 1, &vertexBuffer.get(), &vertexBufferOffset);
1502 vkd.cmdBindIndexBuffer(*commandBuffer, *m_vertexIndexBuffer, 0, VK_INDEX_TYPE_UINT16);
1503 vkd.cmdDrawIndexed(*commandBuffer, 6, 1, 0, 0, 0);
1504 vkd.cmdEndRenderPass(*commandBuffer);
1505
1506 // Copy Image
1507 {
1508 const VkBufferMemoryBarrier bufferBarrier =
1509 {
1510 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1511 DE_NULL, // const void* pNext;
1512 VK_ACCESS_TRANSFER_WRITE_BIT, // VkMemoryOutputFlags outputMask;
1513 VK_ACCESS_HOST_READ_BIT, // VkMemoryInputFlags inputMask;
1514 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1515 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1516 *m_resultBuffer, // VkBuffer buffer;
1517 0u, // VkDeviceSize offset;
1518 m_resultBufferSize // VkDeviceSize size;
1519 };
1520
1521 const VkBufferImageCopy copyRegion =
1522 {
1523 0u, // VkDeviceSize bufferOffset;
1524 m_renderWidth, // deUint32 bufferRowLength;
1525 m_renderHeight, // deUint32 bufferImageHeight;
1526 {
1527 VK_IMAGE_ASPECT_COLOR_BIT,
1528 0u,
1529 0u,
1530 1u
1531 }, // VkImageSubresourceCopy imageSubresource;
1532 { 0, 0, 0 }, // VkOffset3D imageOffset;
1533 { m_renderWidth, m_renderHeight, 1u } // VkExtent3D imageExtent;
1534 };
1535
1536 addImageTransitionBarrier(*commandBuffer,
1537 m_multisampling ? *m_resolvedImage : *m_image,
1538 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
1539 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
1540 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
1541 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
1542 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
1543 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); // VkImageLayout newLayout;
1544
1545 if (m_multisampling)
1546 vkd.cmdCopyImageToBuffer(*commandBuffer, *m_resolvedImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, ©Region);
1547 else
1548 vkd.cmdCopyImageToBuffer(*commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, ©Region);
1549
1550 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1551
1552 addImageTransitionBarrier(*commandBuffer,
1553 m_multisampling ? *m_resolvedImage : *m_image,
1554 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask
1555 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags dstStageMask
1556 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask
1557 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
1558 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout oldLayout;
1559 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
1560 }
1561
1562 VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
1563
1564 // Upload uniform buffer data
1565 {
1566 const ShaderParameters shaderParameters =
1567 {
1568 params.bias, // float bias; //!< User-supplied bias.
1569 params.ref, // float ref; //!< Reference value for shadow lookups.
1570 tcu::Vec2(), // tcu::Vec2 padding; //!< Shader uniform padding.
1571 params.colorScale, // tcu::Vec4 colorScale; //!< Scale for texture color values.
1572 params.colorBias // tcu::Vec4 colorBias; //!< Bias for texture color values.
1573 };
1574 deMemcpy(m_uniformBufferMemory->getHostPtr(), &shaderParameters, sizeof(shaderParameters));
1575 flushMappedMemoryRange(vkd, vkDevice, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset(), VK_WHOLE_SIZE);
1576
1577 if (logUniforms)
1578 m_log << TestLog::Message << "u_sampler = " << texUnit << TestLog::EndMessage;
1579
1580 if (useBias)
1581 {
1582 if (logUniforms)
1583 m_log << TestLog::Message << "u_bias = " << shaderParameters.bias << TestLog::EndMessage;
1584 }
1585
1586 if (params.samplerType == SAMPLERTYPE_SHADOW)
1587 {
1588 if (logUniforms)
1589 m_log << TestLog::Message << "u_ref = " << shaderParameters.ref << TestLog::EndMessage;
1590 }
1591
1592 if (logUniforms)
1593 {
1594 m_log << TestLog::Message << "u_colorScale = " << shaderParameters.colorScale << TestLog::EndMessage;
1595 m_log << TestLog::Message << "u_colorBias = " << shaderParameters.colorBias << TestLog::EndMessage;
1596 }
1597 }
1598
1599 // Submit
1600 {
1601 const VkSubmitInfo submitInfo =
1602 {
1603 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
1604 DE_NULL, // const void* pNext;
1605 0u, // deUint32 waitSemaphoreCount;
1606 DE_NULL, // const VkSemaphore* pWaitSemaphores;
1607 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
1608 1u, // deUint32 commandBufferCount;
1609 &commandBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
1610 0u, // deUint32 signalSemaphoreCount;
1611 DE_NULL, // const VkSemaphore* pSignalSemaphores;
1612 };
1613
1614 VK_CHECK(vkd.resetFences(vkDevice, 1, &m_fence.get()));
1615 VK_CHECK(vkd.queueSubmit(queue, 1, &submitInfo, *m_fence));
1616 VK_CHECK(vkd.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1617 }
1618
1619 invalidateMappedMemoryRange(vkd, vkDevice, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset(), VK_WHOLE_SIZE);
1620
1621 tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderWidth, m_renderHeight, 1u), m_resultBufferMemory->getHostPtr()));
1622 }
1623
1624 /*--------------------------------------------------------------------*//*!
1625 * \brief Map Vulkan sampler parameters to tcu::Sampler.
1626 *
1627 * If no mapping is found, throws tcu::InternalError.
1628 *
1629 * \param wrapU U-component wrap mode
1630 * \param wrapV V-component wrap mode
1631 * \param wrapW W-component wrap mode
1632 * \param minFilterMode Minification filter mode
1633 * \param magFilterMode Magnification filter mode
1634 * \return Sampler description.
1635 *//*--------------------------------------------------------------------*/
createSampler(tcu::Sampler::WrapMode wrapU,tcu::Sampler::WrapMode wrapV,tcu::Sampler::WrapMode wrapW,tcu::Sampler::FilterMode minFilterMode,tcu::Sampler::FilterMode magFilterMode)1636 tcu::Sampler createSampler (tcu::Sampler::WrapMode wrapU, tcu::Sampler::WrapMode wrapV, tcu::Sampler::WrapMode wrapW, tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode)
1637 {
1638 return tcu::Sampler(wrapU, wrapV, wrapW,
1639 minFilterMode, magFilterMode,
1640 0.0f /* lod threshold */,
1641 true /* normalized coords */,
1642 tcu::Sampler::COMPAREMODE_NONE /* no compare */,
1643 0 /* compare channel */,
1644 tcu::Vec4(0.0f) /* border color, not used */);
1645 }
1646
1647 /*--------------------------------------------------------------------*//*!
1648 * \brief Map Vulkan sampler parameters to tcu::Sampler.
1649 *
1650 * If no mapping is found, throws tcu::InternalError.
1651 *
1652 * \param wrapU U-component wrap mode
1653 * \param wrapV V-component wrap mode
1654 * \param minFilterMode Minification filter mode
1655 * \param minFilterMode Magnification filter mode
1656 * \return Sampler description.
1657 *//*--------------------------------------------------------------------*/
createSampler(tcu::Sampler::WrapMode wrapU,tcu::Sampler::WrapMode wrapV,tcu::Sampler::FilterMode minFilterMode,tcu::Sampler::FilterMode magFilterMode)1658 tcu::Sampler createSampler (tcu::Sampler::WrapMode wrapU, tcu::Sampler::WrapMode wrapV, tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode)
1659 {
1660 return createSampler(wrapU, wrapV, wrapU, minFilterMode, magFilterMode);
1661 }
1662
1663 /*--------------------------------------------------------------------*//*!
1664 * \brief Map Vulkan sampler parameters to tcu::Sampler.
1665 *
1666 * If no mapping is found, throws tcu::InternalError.
1667 *
1668 * \param wrapU U-component wrap mode
1669 * \param minFilterMode Minification filter mode
1670 * \return Sampler description.
1671 *//*--------------------------------------------------------------------*/
createSampler(tcu::Sampler::WrapMode wrapU,tcu::Sampler::FilterMode minFilterMode,tcu::Sampler::FilterMode magFilterMode)1672 tcu::Sampler createSampler (tcu::Sampler::WrapMode wrapU, tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode)
1673 {
1674 return createSampler(wrapU, wrapU, wrapU, minFilterMode, magFilterMode);
1675 }
1676
loadTexture2D(const tcu::Archive & archive,const std::vector<std::string> & filenames)1677 TestTexture2DSp loadTexture2D (const tcu::Archive& archive, const std::vector<std::string>& filenames)
1678 {
1679 DE_ASSERT(filenames.size() > 0);
1680
1681 TestTexture2DSp texture;
1682
1683 std::string ext = de::FilePath(filenames[0]).getFileExtension();
1684
1685 if (ext == "png")
1686 {
1687
1688 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
1689 {
1690 tcu::TextureLevel level;
1691
1692 tcu::ImageIO::loadImage(level, archive, filenames[fileIndex].c_str());
1693
1694 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
1695 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
1696
1697 if (fileIndex == 0)
1698 texture = TestTexture2DSp(new pipeline::TestTexture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight()));
1699
1700 tcu::copy(texture->getLevel((int)fileIndex, 0), level.getAccess());
1701 }
1702 }
1703 else if (ext == "pkm")
1704 {
1705
1706 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
1707 {
1708 // Compressed texture.
1709 tcu::CompressedTexture level;
1710
1711 tcu::ImageIO::loadPKM(level, archive, filenames[fileIndex].c_str());
1712
1713 tcu::TextureFormat uncompressedFormat = tcu::getUncompressedFormat(level.getFormat());
1714 std::vector<deUint8> uncompressedData (uncompressedFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0);
1715 tcu::PixelBufferAccess decompressedBuffer (uncompressedFormat, level.getWidth(), level.getHeight(), 1, uncompressedData.data());
1716
1717 tcu::TextureFormat commonFormat = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
1718 std::vector<deUint8> commonFromatData (commonFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0);
1719 tcu::PixelBufferAccess commonFormatBuffer (commonFormat, level.getWidth(), level.getHeight(), 1, commonFromatData.data());
1720
1721 if (fileIndex == 0)
1722 texture = TestTexture2DSp(new pipeline::TestTexture2D(commonFormat, level.getWidth(), level.getHeight()));
1723
1724 level.decompress(decompressedBuffer, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
1725
1726 tcu::copy(commonFormatBuffer, decompressedBuffer);
1727 tcu::copy(texture->getLevel((int)fileIndex, 0), commonFormatBuffer);
1728 }
1729 }
1730 else
1731 TCU_FAIL("Unsupported file format");
1732
1733 return texture;
1734 }
1735
loadTextureCube(const tcu::Archive & archive,const std::vector<std::string> & filenames)1736 TestTextureCubeSp loadTextureCube (const tcu::Archive& archive, const std::vector<std::string>& filenames)
1737 {
1738 DE_ASSERT(filenames.size() > 0);
1739 DE_STATIC_ASSERT(tcu::CUBEFACE_LAST == 6);
1740 TCU_CHECK((int)filenames.size() % tcu::CUBEFACE_LAST == 0);
1741
1742 TestTextureCubeSp texture;
1743
1744 std::string ext = de::FilePath(filenames[0]).getFileExtension();
1745
1746 if (ext == "png")
1747 {
1748
1749 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
1750 {
1751 tcu::TextureLevel level;
1752
1753 tcu::ImageIO::loadImage(level, archive, filenames[fileIndex].c_str());
1754
1755 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
1756 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
1757
1758 TCU_CHECK( level.getWidth() == level.getHeight());
1759
1760 if (fileIndex == 0)
1761 texture = TestTextureCubeSp(new pipeline::TestTextureCube(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth()));
1762
1763 tcu::copy(texture->getLevel((int)fileIndex / 6, (int)fileIndex % 6), level.getAccess());
1764 }
1765 }
1766 else if (ext == "pkm")
1767 {
1768 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
1769 {
1770 // Compressed texture.
1771 tcu::CompressedTexture level;
1772
1773 tcu::ImageIO::loadPKM(level, archive, filenames[fileIndex].c_str());
1774
1775 TCU_CHECK( level.getWidth() == level.getHeight());
1776
1777 tcu::TextureFormat uncompressedFormat = tcu::getUncompressedFormat(level.getFormat());
1778 std::vector<deUint8> uncompressedData (uncompressedFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0);
1779 tcu::PixelBufferAccess decompressedBuffer (uncompressedFormat, level.getWidth(), level.getHeight(), 1, uncompressedData.data());
1780
1781 tcu::TextureFormat commonFormat = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
1782 std::vector<deUint8> commonFromatData (commonFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0);
1783 tcu::PixelBufferAccess commonFormatBuffer (commonFormat, level.getWidth(), level.getHeight(), 1, commonFromatData.data());
1784
1785 if (fileIndex == 0)
1786 texture = TestTextureCubeSp(new pipeline::TestTextureCube(commonFormat, level.getWidth()));
1787
1788 level.decompress(decompressedBuffer, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
1789
1790 tcu::copy(commonFormatBuffer, decompressedBuffer);
1791 tcu::copy(texture->getLevel((int)fileIndex / 6, (int)fileIndex % 6), commonFormatBuffer);
1792 }
1793 }
1794 else
1795 TCU_FAIL("Unsupported file format");
1796
1797 return texture;
1798 }
1799
TextureCommonTestCaseParameters(void)1800 TextureCommonTestCaseParameters::TextureCommonTestCaseParameters (void)
1801 : sampleCount (VK_SAMPLE_COUNT_1_BIT)
1802 , texCoordPrecision (glu::PRECISION_HIGHP)
1803 , minFilter (tcu::Sampler::LINEAR)
1804 , magFilter (tcu::Sampler::LINEAR)
1805 , wrapS (tcu::Sampler::REPEAT_GL)
1806 , wrapT (tcu::Sampler::REPEAT_GL)
1807 , format (VK_FORMAT_R8G8B8A8_UNORM)
1808 {
1809 }
1810
Texture2DTestCaseParameters(void)1811 Texture2DTestCaseParameters::Texture2DTestCaseParameters (void)
1812 : width (64)
1813 , height (64)
1814 {
1815 }
1816
TextureCubeTestCaseParameters(void)1817 TextureCubeTestCaseParameters::TextureCubeTestCaseParameters (void)
1818 : size (64)
1819 {
1820 }
1821
Texture2DArrayTestCaseParameters(void)1822 Texture2DArrayTestCaseParameters::Texture2DArrayTestCaseParameters (void)
1823 : numLayers (8)
1824 {
1825 }
1826
Texture3DTestCaseParameters(void)1827 Texture3DTestCaseParameters::Texture3DTestCaseParameters (void)
1828 : wrapR (tcu::Sampler::REPEAT_GL)
1829 , depth (64)
1830 {
1831 }
1832
1833 } // util
1834 } // texture
1835 } // vkt
1836