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