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