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