1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2016 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 Vulkan ShaderRenderCase
24 *//*--------------------------------------------------------------------*/
25
26 #include "vktShaderRender.hpp"
27
28 #include "tcuImageCompare.hpp"
29 #include "tcuImageIO.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuTextureUtil.hpp"
32 #include "tcuSurface.hpp"
33 #include "tcuVector.hpp"
34
35 #include "deFilePath.hpp"
36 #include "deMath.h"
37 #include "deUniquePtr.hpp"
38
39 #include "vkDeviceUtil.hpp"
40 #include "vkImageUtil.hpp"
41 #include "vkPlatform.hpp"
42 #include "vkQueryUtil.hpp"
43 #include "vkRef.hpp"
44 #include "vkRefUtil.hpp"
45 #include "vkStrUtil.hpp"
46 #include "vkTypeUtil.hpp"
47 #include "vkCmdUtil.hpp"
48 #include "vkObjUtil.hpp"
49
50 #include <vector>
51 #include <string>
52
53 namespace vkt
54 {
55 namespace sr
56 {
57
58 using namespace vk;
59
60 namespace
61 {
62
63 static const deUint32 MAX_RENDER_WIDTH = 128;
64 static const deUint32 MAX_RENDER_HEIGHT = 128;
65 static const tcu::Vec4 DEFAULT_CLEAR_COLOR = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f);
66
textureTypeToImageViewType(TextureBinding::Type type)67 static VkImageViewType textureTypeToImageViewType (TextureBinding::Type type)
68 {
69 switch (type)
70 {
71 case TextureBinding::TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D;
72 case TextureBinding::TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D;
73 case TextureBinding::TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D;
74 case TextureBinding::TYPE_CUBE_MAP: return VK_IMAGE_VIEW_TYPE_CUBE;
75 case TextureBinding::TYPE_1D_ARRAY: return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
76 case TextureBinding::TYPE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
77 case TextureBinding::TYPE_CUBE_ARRAY: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
78
79 default:
80 DE_FATAL("Impossible");
81 return (VkImageViewType)0;
82 }
83 }
84
viewTypeToImageType(VkImageViewType type)85 static VkImageType viewTypeToImageType (VkImageViewType type)
86 {
87 switch (type)
88 {
89 case VK_IMAGE_VIEW_TYPE_1D:
90 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: return VK_IMAGE_TYPE_1D;
91 case VK_IMAGE_VIEW_TYPE_2D:
92 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: return VK_IMAGE_TYPE_2D;
93 case VK_IMAGE_VIEW_TYPE_3D: return VK_IMAGE_TYPE_3D;
94 case VK_IMAGE_VIEW_TYPE_CUBE:
95 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return VK_IMAGE_TYPE_2D;
96
97 default:
98 DE_FATAL("Impossible");
99 return (VkImageType)0;
100 }
101 }
102
103 /*! Gets the next multiple of a given divisor */
getNextMultiple(deUint32 divisor,deUint32 value)104 static deUint32 getNextMultiple (deUint32 divisor, deUint32 value)
105 {
106 if (value % divisor == 0)
107 {
108 return value;
109 }
110 return value + divisor - (value % divisor);
111 }
112
113 /*! Gets the next value that is multiple of all given divisors */
getNextMultiple(const std::vector<deUint32> & divisors,deUint32 value)114 static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value)
115 {
116 deUint32 nextMultiple = value;
117 bool nextMultipleFound = false;
118
119 while (true)
120 {
121 nextMultipleFound = true;
122
123 for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++)
124 nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0);
125
126 if (nextMultipleFound)
127 break;
128
129 DE_ASSERT(nextMultiple < ~((deUint32)0u));
130 nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1);
131 }
132
133 return nextMultiple;
134 }
135
136 } // anonymous
137
138 // QuadGrid.
139
140 class QuadGrid
141 {
142 public:
143 QuadGrid (int gridSize,
144 int screenWidth,
145 int screenHeight,
146 const tcu::Vec4& constCoords,
147 const std::vector<tcu::Mat4>& userAttribTransforms,
148 const std::vector<TextureBindingSp>& textures);
149 ~QuadGrid (void);
150
getGridSize(void) const151 int getGridSize (void) const { return m_gridSize; }
getNumVertices(void) const152 int getNumVertices (void) const { return m_numVertices; }
getNumTriangles(void) const153 int getNumTriangles (void) const { return m_numTriangles; }
getConstCoords(void) const154 const tcu::Vec4& getConstCoords (void) const { return m_constCoords; }
getUserAttribTransforms(void) const155 const std::vector<tcu::Mat4> getUserAttribTransforms (void) const { return m_userAttribTransforms; }
getTextures(void) const156 const std::vector<TextureBindingSp>& getTextures (void) const { return m_textures; }
157
getPositions(void) const158 const tcu::Vec4* getPositions (void) const { return &m_positions[0]; }
getAttribOne(void) const159 const float* getAttribOne (void) const { return &m_attribOne[0]; }
getCoords(void) const160 const tcu::Vec4* getCoords (void) const { return &m_coords[0]; }
getUnitCoords(void) const161 const tcu::Vec4* getUnitCoords (void) const { return &m_unitCoords[0]; }
162
getUserAttrib(int attribNdx) const163 const tcu::Vec4* getUserAttrib (int attribNdx) const { return &m_userAttribs[attribNdx][0]; }
getIndices(void) const164 const deUint16* getIndices (void) const { return &m_indices[0]; }
165
166 tcu::Vec4 getCoords (float sx, float sy) const;
167 tcu::Vec4 getUnitCoords (float sx, float sy) const;
168
getNumUserAttribs(void) const169 int getNumUserAttribs (void) const { return (int)m_userAttribTransforms.size(); }
170 tcu::Vec4 getUserAttrib (int attribNdx, float sx, float sy) const;
171
172 private:
173 const int m_gridSize;
174 const int m_numVertices;
175 const int m_numTriangles;
176 const tcu::Vec4 m_constCoords;
177 const std::vector<tcu::Mat4> m_userAttribTransforms;
178
179 const std::vector<TextureBindingSp>& m_textures;
180
181 std::vector<tcu::Vec4> m_screenPos;
182 std::vector<tcu::Vec4> m_positions;
183 std::vector<tcu::Vec4> m_coords; //!< Near-unit coordinates, roughly [-2.0 .. 2.0].
184 std::vector<tcu::Vec4> m_unitCoords; //!< Positive-only coordinates [0.0 .. 1.5].
185 std::vector<float> m_attribOne;
186 std::vector<tcu::Vec4> m_userAttribs[ShaderEvalContext::MAX_TEXTURES];
187 std::vector<deUint16> m_indices;
188 };
189
QuadGrid(int gridSize,int width,int height,const tcu::Vec4 & constCoords,const std::vector<tcu::Mat4> & userAttribTransforms,const std::vector<TextureBindingSp> & textures)190 QuadGrid::QuadGrid (int gridSize,
191 int width,
192 int height,
193 const tcu::Vec4& constCoords,
194 const std::vector<tcu::Mat4>& userAttribTransforms,
195 const std::vector<TextureBindingSp>& textures)
196 : m_gridSize (gridSize)
197 , m_numVertices ((gridSize + 1) * (gridSize + 1))
198 , m_numTriangles (gridSize * gridSize * 2)
199 , m_constCoords (constCoords)
200 , m_userAttribTransforms (userAttribTransforms)
201 , m_textures (textures)
202 {
203 const tcu::Vec4 viewportScale ((float)width, (float)height, 0.0f, 0.0f);
204
205 // Compute vertices.
206 m_screenPos.resize(m_numVertices);
207 m_positions.resize(m_numVertices);
208 m_coords.resize(m_numVertices);
209 m_unitCoords.resize(m_numVertices);
210 m_attribOne.resize(m_numVertices);
211
212 // User attributes.
213 for (int attrNdx = 0; attrNdx < DE_LENGTH_OF_ARRAY(m_userAttribs); attrNdx++)
214 m_userAttribs[attrNdx].resize(m_numVertices);
215
216 for (int y = 0; y < gridSize+1; y++)
217 for (int x = 0; x < gridSize+1; x++)
218 {
219 float sx = (float)x / (float)gridSize;
220 float sy = (float)y / (float)gridSize;
221 float fx = 2.0f * sx - 1.0f;
222 float fy = 2.0f * sy - 1.0f;
223 int vtxNdx = ((y * (gridSize+1)) + x);
224
225 m_positions[vtxNdx] = tcu::Vec4(fx, fy, 0.0f, 1.0f);
226 m_coords[vtxNdx] = getCoords(sx, sy);
227 m_unitCoords[vtxNdx] = getUnitCoords(sx, sy);
228 m_attribOne[vtxNdx] = 1.0f;
229
230 m_screenPos[vtxNdx] = tcu::Vec4(sx, sy, 0.0f, 1.0f) * viewportScale;
231
232 for (int attribNdx = 0; attribNdx < getNumUserAttribs(); attribNdx++)
233 m_userAttribs[attribNdx][vtxNdx] = getUserAttrib(attribNdx, sx, sy);
234 }
235
236 // Compute indices.
237 m_indices.resize(3 * m_numTriangles);
238 for (int y = 0; y < gridSize; y++)
239 for (int x = 0; x < gridSize; x++)
240 {
241 int stride = gridSize + 1;
242 int v00 = (y * stride) + x;
243 int v01 = (y * stride) + x + 1;
244 int v10 = ((y+1) * stride) + x;
245 int v11 = ((y+1) * stride) + x + 1;
246
247 int baseNdx = ((y * gridSize) + x) * 6;
248 m_indices[baseNdx + 0] = (deUint16)v10;
249 m_indices[baseNdx + 1] = (deUint16)v00;
250 m_indices[baseNdx + 2] = (deUint16)v01;
251
252 m_indices[baseNdx + 3] = (deUint16)v10;
253 m_indices[baseNdx + 4] = (deUint16)v01;
254 m_indices[baseNdx + 5] = (deUint16)v11;
255 }
256 }
257
~QuadGrid(void)258 QuadGrid::~QuadGrid (void)
259 {
260 }
261
getCoords(float sx,float sy) const262 inline tcu::Vec4 QuadGrid::getCoords (float sx, float sy) const
263 {
264 const float fx = 2.0f * sx - 1.0f;
265 const float fy = 2.0f * sy - 1.0f;
266 return tcu::Vec4(fx, fy, -fx + 0.33f*fy, -0.275f*fx - fy);
267 }
268
getUnitCoords(float sx,float sy) const269 inline tcu::Vec4 QuadGrid::getUnitCoords (float sx, float sy) const
270 {
271 return tcu::Vec4(sx, sy, 0.33f*sx + 0.5f*sy, 0.5f*sx + 0.25f*sy);
272 }
273
getUserAttrib(int attribNdx,float sx,float sy) const274 inline tcu::Vec4 QuadGrid::getUserAttrib (int attribNdx, float sx, float sy) const
275 {
276 // homogeneous normalized screen-space coordinates
277 return m_userAttribTransforms[attribNdx] * tcu::Vec4(sx, sy, 0.0f, 1.0f);
278 }
279
280 // TextureBinding
281
TextureBinding(const tcu::Archive & archive,const char * filename,const Type type,const tcu::Sampler & sampler)282 TextureBinding::TextureBinding (const tcu::Archive& archive,
283 const char* filename,
284 const Type type,
285 const tcu::Sampler& sampler)
286 : m_type (type)
287 , m_sampler (sampler)
288 {
289 switch(m_type)
290 {
291 case TYPE_2D: m_binding.tex2D = loadTexture2D(archive, filename).release(); break;
292 default:
293 DE_FATAL("Unsupported texture type");
294 }
295 }
296
TextureBinding(const tcu::Texture1D * tex1D,const tcu::Sampler & sampler)297 TextureBinding::TextureBinding (const tcu::Texture1D* tex1D, const tcu::Sampler& sampler)
298 : m_type (TYPE_1D)
299 , m_sampler (sampler)
300 {
301 m_binding.tex1D = tex1D;
302 }
303
TextureBinding(const tcu::Texture2D * tex2D,const tcu::Sampler & sampler)304 TextureBinding::TextureBinding (const tcu::Texture2D* tex2D, const tcu::Sampler& sampler)
305 : m_type (TYPE_2D)
306 , m_sampler (sampler)
307 {
308 m_binding.tex2D = tex2D;
309 }
310
TextureBinding(const tcu::Texture3D * tex3D,const tcu::Sampler & sampler)311 TextureBinding::TextureBinding (const tcu::Texture3D* tex3D, const tcu::Sampler& sampler)
312 : m_type (TYPE_3D)
313 , m_sampler (sampler)
314 {
315 m_binding.tex3D = tex3D;
316 }
317
TextureBinding(const tcu::TextureCube * texCube,const tcu::Sampler & sampler)318 TextureBinding::TextureBinding (const tcu::TextureCube* texCube, const tcu::Sampler& sampler)
319 : m_type (TYPE_CUBE_MAP)
320 , m_sampler (sampler)
321 {
322 m_binding.texCube = texCube;
323 }
324
TextureBinding(const tcu::Texture1DArray * tex1DArray,const tcu::Sampler & sampler)325 TextureBinding::TextureBinding (const tcu::Texture1DArray* tex1DArray, const tcu::Sampler& sampler)
326 : m_type (TYPE_1D_ARRAY)
327 , m_sampler (sampler)
328 {
329 m_binding.tex1DArray = tex1DArray;
330 }
331
TextureBinding(const tcu::Texture2DArray * tex2DArray,const tcu::Sampler & sampler)332 TextureBinding::TextureBinding (const tcu::Texture2DArray* tex2DArray, const tcu::Sampler& sampler)
333 : m_type (TYPE_2D_ARRAY)
334 , m_sampler (sampler)
335 {
336 m_binding.tex2DArray = tex2DArray;
337 }
338
TextureBinding(const tcu::TextureCubeArray * texCubeArray,const tcu::Sampler & sampler)339 TextureBinding::TextureBinding (const tcu::TextureCubeArray* texCubeArray, const tcu::Sampler& sampler)
340 : m_type (TYPE_CUBE_ARRAY)
341 , m_sampler (sampler)
342 {
343 m_binding.texCubeArray = texCubeArray;
344 }
345
~TextureBinding(void)346 TextureBinding::~TextureBinding (void)
347 {
348 switch(m_type)
349 {
350 case TYPE_1D: delete m_binding.tex1D; break;
351 case TYPE_2D: delete m_binding.tex2D; break;
352 case TYPE_3D: delete m_binding.tex3D; break;
353 case TYPE_CUBE_MAP: delete m_binding.texCube; break;
354 case TYPE_1D_ARRAY: delete m_binding.tex1DArray; break;
355 case TYPE_2D_ARRAY: delete m_binding.tex2DArray; break;
356 case TYPE_CUBE_ARRAY: delete m_binding.texCubeArray; break;
357 default: break;
358 }
359 }
360
loadTexture2D(const tcu::Archive & archive,const char * filename)361 de::MovePtr<tcu::Texture2D> TextureBinding::loadTexture2D (const tcu::Archive& archive, const char* filename)
362 {
363 tcu::TextureLevel level;
364 tcu::ImageIO::loadImage(level, archive, filename);
365
366 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
367 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
368
369 // \todo [2015-10-08 elecro] for some reason we get better when using RGBA texture even in RGB case, this needs to be investigated
370 de::MovePtr<tcu::Texture2D> texture(new tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight()));
371
372 // Fill level 0.
373 texture->allocLevel(0);
374 tcu::copy(texture->getLevel(0), level.getAccess());
375
376 return texture;
377 }
378
379 // ShaderEvalContext.
380
ShaderEvalContext(const QuadGrid & quadGrid)381 ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid)
382 : constCoords (quadGrid.getConstCoords())
383 , isDiscarded (false)
384 , m_quadGrid (quadGrid)
385 {
386 const std::vector<TextureBindingSp>& bindings = m_quadGrid.getTextures();
387 DE_ASSERT((int)bindings.size() <= MAX_TEXTURES);
388
389 // Fill in texture array.
390 for (int ndx = 0; ndx < (int)bindings.size(); ndx++)
391 {
392 const TextureBinding& binding = *bindings[ndx];
393
394 if (binding.getType() == TextureBinding::TYPE_NONE)
395 continue;
396
397 textures[ndx].sampler = binding.getSampler();
398
399 switch (binding.getType())
400 {
401 case TextureBinding::TYPE_1D: textures[ndx].tex1D = &binding.get1D(); break;
402 case TextureBinding::TYPE_2D: textures[ndx].tex2D = &binding.get2D(); break;
403 case TextureBinding::TYPE_3D: textures[ndx].tex3D = &binding.get3D(); break;
404 case TextureBinding::TYPE_CUBE_MAP: textures[ndx].texCube = &binding.getCube(); break;
405 case TextureBinding::TYPE_1D_ARRAY: textures[ndx].tex1DArray = &binding.get1DArray(); break;
406 case TextureBinding::TYPE_2D_ARRAY: textures[ndx].tex2DArray = &binding.get2DArray(); break;
407 case TextureBinding::TYPE_CUBE_ARRAY: textures[ndx].texCubeArray = &binding.getCubeArray(); break;
408 default:
409 TCU_THROW(InternalError, "Handling of texture binding type not implemented");
410 }
411 }
412 }
413
~ShaderEvalContext(void)414 ShaderEvalContext::~ShaderEvalContext (void)
415 {
416 }
417
reset(float sx,float sy)418 void ShaderEvalContext::reset (float sx, float sy)
419 {
420 // Clear old values
421 color = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
422 isDiscarded = false;
423
424 // Compute coords
425 coords = m_quadGrid.getCoords(sx, sy);
426 unitCoords = m_quadGrid.getUnitCoords(sx, sy);
427
428 // Compute user attributes.
429 const int numAttribs = m_quadGrid.getNumUserAttribs();
430 DE_ASSERT(numAttribs <= MAX_USER_ATTRIBS);
431 for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++)
432 in[attribNdx] = m_quadGrid.getUserAttrib(attribNdx, sx, sy);
433 }
434
texture2D(int unitNdx,const tcu::Vec2 & texCoords)435 tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords)
436 {
437 if (textures[unitNdx].tex2D)
438 return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f);
439 else
440 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
441 }
442
443 // ShaderEvaluator.
444
ShaderEvaluator(void)445 ShaderEvaluator::ShaderEvaluator (void)
446 : m_evalFunc(DE_NULL)
447 {
448 }
449
ShaderEvaluator(ShaderEvalFunc evalFunc)450 ShaderEvaluator::ShaderEvaluator (ShaderEvalFunc evalFunc)
451 : m_evalFunc(evalFunc)
452 {
453 }
454
~ShaderEvaluator(void)455 ShaderEvaluator::~ShaderEvaluator (void)
456 {
457 }
458
evaluate(ShaderEvalContext & ctx) const459 void ShaderEvaluator::evaluate (ShaderEvalContext& ctx) const
460 {
461 DE_ASSERT(m_evalFunc);
462 m_evalFunc(ctx);
463 }
464
465 // UniformSetup.
466
UniformSetup(void)467 UniformSetup::UniformSetup (void)
468 : m_setupFunc(DE_NULL)
469 {
470 }
471
UniformSetup(UniformSetupFunc setupFunc)472 UniformSetup::UniformSetup (UniformSetupFunc setupFunc)
473 : m_setupFunc(setupFunc)
474 {
475 }
476
~UniformSetup(void)477 UniformSetup::~UniformSetup (void)
478 {
479 }
480
setup(ShaderRenderCaseInstance & instance,const tcu::Vec4 & constCoords) const481 void UniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const
482 {
483 if (m_setupFunc)
484 m_setupFunc(instance, constCoords);
485 }
486
487 // ShaderRenderCase.
488
ShaderRenderCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const bool isVertexCase,const ShaderEvalFunc evalFunc,const UniformSetup * uniformSetup,const AttributeSetupFunc attribFunc)489 ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx,
490 const std::string& name,
491 const std::string& description,
492 const bool isVertexCase,
493 const ShaderEvalFunc evalFunc,
494 const UniformSetup* uniformSetup,
495 const AttributeSetupFunc attribFunc)
496 : vkt::TestCase (testCtx, name, description)
497 , m_isVertexCase (isVertexCase)
498 , m_evaluator (new ShaderEvaluator(evalFunc))
499 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup())
500 , m_attribFunc (attribFunc)
501 {}
502
ShaderRenderCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const bool isVertexCase,const ShaderEvaluator * evaluator,const UniformSetup * uniformSetup,const AttributeSetupFunc attribFunc)503 ShaderRenderCase::ShaderRenderCase (tcu::TestContext& testCtx,
504 const std::string& name,
505 const std::string& description,
506 const bool isVertexCase,
507 const ShaderEvaluator* evaluator,
508 const UniformSetup* uniformSetup,
509 const AttributeSetupFunc attribFunc)
510 : vkt::TestCase (testCtx, name, description)
511 , m_isVertexCase (isVertexCase)
512 , m_evaluator (evaluator)
513 , m_uniformSetup (uniformSetup ? uniformSetup : new UniformSetup())
514 , m_attribFunc (attribFunc)
515 {}
516
~ShaderRenderCase(void)517 ShaderRenderCase::~ShaderRenderCase (void)
518 {
519 }
520
initPrograms(vk::SourceCollections & programCollection) const521 void ShaderRenderCase::initPrograms (vk::SourceCollections& programCollection) const
522 {
523 programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource);
524 programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource);
525 }
526
createInstance(Context & context) const527 TestInstance* ShaderRenderCase::createInstance (Context& context) const
528 {
529 DE_ASSERT(m_evaluator != DE_NULL);
530 DE_ASSERT(m_uniformSetup != DE_NULL);
531 return new ShaderRenderCaseInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_attribFunc);
532 }
533
534 // ShaderRenderCaseInstance.
535
ShaderRenderCaseInstance(Context & context)536 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context)
537 : vkt::TestInstance (context)
538 , m_imageBackingMode (IMAGE_BACKING_MODE_REGULAR)
539 , m_quadGridSize (static_cast<deUint32>(GRID_SIZE_DEFAULT_FRAGMENT))
540 , m_memAlloc (getAllocator())
541 , m_clearColor (DEFAULT_CLEAR_COLOR)
542 , m_isVertexCase (false)
543 , m_vertexShaderName ("vert")
544 , m_fragmentShaderName ("frag")
545 , m_renderSize (MAX_RENDER_WIDTH, MAX_RENDER_HEIGHT)
546 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
547 , m_evaluator (DE_NULL)
548 , m_uniformSetup (DE_NULL)
549 , m_attribFunc (DE_NULL)
550 , m_sampleCount (VK_SAMPLE_COUNT_1_BIT)
551 {
552 }
553
554
ShaderRenderCaseInstance(Context & context,const bool isVertexCase,const ShaderEvaluator & evaluator,const UniformSetup & uniformSetup,const AttributeSetupFunc attribFunc,const ImageBackingMode imageBackingMode,const deUint32 gridSize)555 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context,
556 const bool isVertexCase,
557 const ShaderEvaluator& evaluator,
558 const UniformSetup& uniformSetup,
559 const AttributeSetupFunc attribFunc,
560 const ImageBackingMode imageBackingMode,
561 const deUint32 gridSize)
562 : vkt::TestInstance (context)
563 , m_imageBackingMode (imageBackingMode)
564 , m_quadGridSize (gridSize == static_cast<deUint32>(GRID_SIZE_DEFAULTS)
565 ? (isVertexCase
566 ? static_cast<deUint32>(GRID_SIZE_DEFAULT_VERTEX)
567 : static_cast<deUint32>(GRID_SIZE_DEFAULT_FRAGMENT))
568 : gridSize)
569 , m_memAlloc (getAllocator())
570 , m_clearColor (DEFAULT_CLEAR_COLOR)
571 , m_isVertexCase (isVertexCase)
572 , m_vertexShaderName ("vert")
573 , m_fragmentShaderName ("frag")
574 , m_renderSize (MAX_RENDER_WIDTH, MAX_RENDER_HEIGHT)
575 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
576 , m_evaluator (&evaluator)
577 , m_uniformSetup (&uniformSetup)
578 , m_attribFunc (attribFunc)
579 , m_sampleCount (VK_SAMPLE_COUNT_1_BIT)
580 {
581 }
582
ShaderRenderCaseInstance(Context & context,const bool isVertexCase,const ShaderEvaluator * evaluator,const UniformSetup * uniformSetup,const AttributeSetupFunc attribFunc,const ImageBackingMode imageBackingMode,const deUint32 gridSize)583 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context,
584 const bool isVertexCase,
585 const ShaderEvaluator* evaluator,
586 const UniformSetup* uniformSetup,
587 const AttributeSetupFunc attribFunc,
588 const ImageBackingMode imageBackingMode,
589 const deUint32 gridSize)
590 : vkt::TestInstance (context)
591 , m_imageBackingMode (imageBackingMode)
592 , m_quadGridSize (gridSize == static_cast<deUint32>(GRID_SIZE_DEFAULTS)
593 ? (isVertexCase
594 ? static_cast<deUint32>(GRID_SIZE_DEFAULT_VERTEX)
595 : static_cast<deUint32>(GRID_SIZE_DEFAULT_FRAGMENT))
596 : gridSize)
597 , m_memAlloc (getAllocator())
598 , m_clearColor (DEFAULT_CLEAR_COLOR)
599 , m_isVertexCase (isVertexCase)
600 , m_vertexShaderName ("vert")
601 , m_fragmentShaderName ("frag")
602 , m_renderSize (MAX_RENDER_WIDTH, MAX_RENDER_HEIGHT)
603 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
604 , m_evaluator (evaluator)
605 , m_uniformSetup (uniformSetup)
606 , m_attribFunc (attribFunc)
607 , m_sampleCount (VK_SAMPLE_COUNT_1_BIT)
608 {
609 }
610
getAllocator(void) const611 vk::Allocator& ShaderRenderCaseInstance::getAllocator (void) const
612 {
613 return m_context.getDefaultAllocator();
614 }
615
~ShaderRenderCaseInstance(void)616 ShaderRenderCaseInstance::~ShaderRenderCaseInstance (void)
617 {
618 }
619
getDevice(void) const620 VkDevice ShaderRenderCaseInstance::getDevice (void) const
621 {
622 return m_context.getDevice();
623 }
624
getUniversalQueueFamilyIndex(void) const625 deUint32 ShaderRenderCaseInstance::getUniversalQueueFamilyIndex (void) const
626 {
627 return m_context.getUniversalQueueFamilyIndex();
628 }
629
getSparseQueueFamilyIndex(void) const630 deUint32 ShaderRenderCaseInstance::getSparseQueueFamilyIndex (void) const
631 {
632 return m_context.getSparseQueueFamilyIndex();
633 }
634
getDeviceInterface(void) const635 const DeviceInterface& ShaderRenderCaseInstance::getDeviceInterface (void) const
636 {
637 return m_context.getDeviceInterface();
638 }
639
getUniversalQueue(void) const640 VkQueue ShaderRenderCaseInstance::getUniversalQueue (void) const
641 {
642 return m_context.getUniversalQueue();
643 }
644
getSparseQueue(void) const645 VkQueue ShaderRenderCaseInstance::getSparseQueue (void) const
646 {
647 return m_context.getSparseQueue();
648 }
649
getPhysicalDevice(void) const650 VkPhysicalDevice ShaderRenderCaseInstance::getPhysicalDevice (void) const
651 {
652 return m_context.getPhysicalDevice();
653 }
654
getInstanceInterface(void) const655 const InstanceInterface& ShaderRenderCaseInstance::getInstanceInterface (void) const
656 {
657 return m_context.getInstanceInterface();
658 }
659
iterate(void)660 tcu::TestStatus ShaderRenderCaseInstance::iterate (void)
661 {
662 setup();
663
664 // Create quad grid.
665 const tcu::UVec2 viewportSize = getViewportSize();
666 const int width = viewportSize.x();
667 const int height = viewportSize.y();
668
669 m_quadGrid = de::MovePtr<QuadGrid>(new QuadGrid(m_quadGridSize, width, height, getDefaultConstCoords(), m_userAttribTransforms, m_textures));
670
671 // Render result.
672 tcu::Surface resImage (width, height);
673
674 render(m_quadGrid->getNumVertices(), m_quadGrid->getNumTriangles(), m_quadGrid->getIndices(), m_quadGrid->getConstCoords());
675 tcu::copy(resImage.getAccess(), m_resultImage.getAccess());
676
677 // Compute reference.
678 tcu::Surface refImage (width, height);
679 if (m_isVertexCase)
680 computeVertexReference(refImage, *m_quadGrid);
681 else
682 computeFragmentReference(refImage, *m_quadGrid);
683
684 // Compare.
685 const bool compareOk = compareImages(resImage, refImage, 0.2f);
686
687 if (compareOk)
688 return tcu::TestStatus::pass("Result image matches reference");
689 else
690 return tcu::TestStatus::fail("Image mismatch");
691 }
692
setup(void)693 void ShaderRenderCaseInstance::setup (void)
694 {
695 m_resultImage = tcu::TextureLevel();
696 m_descriptorSetLayoutBuilder = de::MovePtr<DescriptorSetLayoutBuilder> (new DescriptorSetLayoutBuilder());
697 m_descriptorPoolBuilder = de::MovePtr<DescriptorPoolBuilder> (new DescriptorPoolBuilder());
698 m_descriptorSetUpdateBuilder = de::MovePtr<DescriptorSetUpdateBuilder> (new DescriptorSetUpdateBuilder());
699
700 m_uniformInfos.clear();
701 m_vertexBindingDescription.clear();
702 m_vertexAttributeDescription.clear();
703 m_vertexBuffers.clear();
704 m_vertexBufferAllocs.clear();
705 m_pushConstantRanges.clear();
706 }
707
setupUniformData(deUint32 bindingLocation,size_t size,const void * dataPtr)708 void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, size_t size, const void* dataPtr)
709 {
710 const VkDevice vkDevice = getDevice();
711 const DeviceInterface& vk = getDeviceInterface();
712 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex();
713
714 const VkBufferCreateInfo uniformBufferParams =
715 {
716 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
717 DE_NULL, // const void* pNext;
718 0u, // VkBufferCreateFlags flags;
719 size, // VkDeviceSize size;
720 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage;
721 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
722 1u, // deUint32 queueFamilyCount;
723 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
724 };
725
726 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams);
727 de::MovePtr<Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
728 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
729
730 deMemcpy(alloc->getHostPtr(), dataPtr, size);
731 flushAlloc(vk, vkDevice, *alloc);
732
733 de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
734 uniformInfo->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
735 uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size);
736 uniformInfo->location = bindingLocation;
737 uniformInfo->buffer = VkBufferSp(new vk::Unique<VkBuffer>(buffer));
738 uniformInfo->alloc = AllocationSp(alloc.release());
739
740 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo)));
741 }
742
addUniform(deUint32 bindingLocation,vk::VkDescriptorType descriptorType,size_t dataSize,const void * data)743 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, size_t dataSize, const void* data)
744 {
745 m_descriptorSetLayoutBuilder->addSingleBinding(descriptorType, vk::VK_SHADER_STAGE_ALL);
746 m_descriptorPoolBuilder->addType(descriptorType);
747
748 setupUniformData(bindingLocation, dataSize, data);
749 }
750
addAttribute(deUint32 bindingLocation,vk::VkFormat format,deUint32 sizePerElement,deUint32 count,const void * dataPtr)751 void ShaderRenderCaseInstance::addAttribute (deUint32 bindingLocation,
752 vk::VkFormat format,
753 deUint32 sizePerElement,
754 deUint32 count,
755 const void* dataPtr)
756 {
757 // Add binding specification
758 const deUint32 binding = (deUint32)m_vertexBindingDescription.size();
759 const VkVertexInputBindingDescription bindingDescription =
760 {
761 binding, // deUint32 binding;
762 sizePerElement, // deUint32 stride;
763 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate stepRate;
764 };
765
766 m_vertexBindingDescription.push_back(bindingDescription);
767
768 // Add location and format specification
769 const VkVertexInputAttributeDescription attributeDescription =
770 {
771 bindingLocation, // deUint32 location;
772 binding, // deUint32 binding;
773 format, // VkFormat format;
774 0u, // deUint32 offset;
775 };
776
777 m_vertexAttributeDescription.push_back(attributeDescription);
778
779 // Upload data to buffer
780 const VkDevice vkDevice = getDevice();
781 const DeviceInterface& vk = getDeviceInterface();
782 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex();
783
784 const VkDeviceSize inputSize = sizePerElement * count;
785 const VkBufferCreateInfo vertexBufferParams =
786 {
787 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
788 DE_NULL, // const void* pNext;
789 0u, // VkBufferCreateFlags flags;
790 inputSize, // VkDeviceSize size;
791 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
792 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
793 1u, // deUint32 queueFamilyCount;
794 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
795 };
796
797 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams);
798 de::MovePtr<vk::Allocation> alloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
799 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
800
801 deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize);
802 flushAlloc(vk, vkDevice, *alloc);
803
804 m_vertexBuffers.push_back(VkBufferSp(new vk::Unique<VkBuffer>(buffer)));
805 m_vertexBufferAllocs.push_back(AllocationSp(alloc.release()));
806 }
807
useAttribute(deUint32 bindingLocation,BaseAttributeType type)808 void ShaderRenderCaseInstance::useAttribute (deUint32 bindingLocation, BaseAttributeType type)
809 {
810 const EnabledBaseAttribute attribute =
811 {
812 bindingLocation, // deUint32 location;
813 type // BaseAttributeType type;
814 };
815 m_enabledBaseAttributes.push_back(attribute);
816 }
817
setupUniforms(const tcu::Vec4 & constCoords)818 void ShaderRenderCaseInstance::setupUniforms (const tcu::Vec4& constCoords)
819 {
820 if (m_uniformSetup)
821 m_uniformSetup->setup(*this, constCoords);
822 }
823
useUniform(deUint32 bindingLocation,BaseUniformType type)824 void ShaderRenderCaseInstance::useUniform (deUint32 bindingLocation, BaseUniformType type)
825 {
826 #define UNIFORM_CASE(type, value) case type: addUniform(bindingLocation, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, value); break
827
828 switch(type)
829 {
830 // Bool
831 UNIFORM_CASE(UB_FALSE, 0);
832 UNIFORM_CASE(UB_TRUE, 1);
833
834 // BVec4
835 UNIFORM_CASE(UB4_FALSE, tcu::Vec4(0));
836 UNIFORM_CASE(UB4_TRUE, tcu::Vec4(1));
837
838 // Integer
839 UNIFORM_CASE(UI_ZERO, 0);
840 UNIFORM_CASE(UI_ONE, 1);
841 UNIFORM_CASE(UI_TWO, 2);
842 UNIFORM_CASE(UI_THREE, 3);
843 UNIFORM_CASE(UI_FOUR, 4);
844 UNIFORM_CASE(UI_FIVE, 5);
845 UNIFORM_CASE(UI_SIX, 6);
846 UNIFORM_CASE(UI_SEVEN, 7);
847 UNIFORM_CASE(UI_EIGHT, 8);
848 UNIFORM_CASE(UI_ONEHUNDREDONE, 101);
849
850 // IVec2
851 UNIFORM_CASE(UI2_MINUS_ONE, tcu::IVec2(-1));
852 UNIFORM_CASE(UI2_ZERO, tcu::IVec2(0));
853 UNIFORM_CASE(UI2_ONE, tcu::IVec2(1));
854 UNIFORM_CASE(UI2_TWO, tcu::IVec2(2));
855 UNIFORM_CASE(UI2_THREE, tcu::IVec2(3));
856 UNIFORM_CASE(UI2_FOUR, tcu::IVec2(4));
857 UNIFORM_CASE(UI2_FIVE, tcu::IVec2(5));
858
859 // IVec3
860 UNIFORM_CASE(UI3_MINUS_ONE, tcu::IVec3(-1));
861 UNIFORM_CASE(UI3_ZERO, tcu::IVec3(0));
862 UNIFORM_CASE(UI3_ONE, tcu::IVec3(1));
863 UNIFORM_CASE(UI3_TWO, tcu::IVec3(2));
864 UNIFORM_CASE(UI3_THREE, tcu::IVec3(3));
865 UNIFORM_CASE(UI3_FOUR, tcu::IVec3(4));
866 UNIFORM_CASE(UI3_FIVE, tcu::IVec3(5));
867
868 // IVec4
869 UNIFORM_CASE(UI4_MINUS_ONE, tcu::IVec4(-1));
870 UNIFORM_CASE(UI4_ZERO, tcu::IVec4(0));
871 UNIFORM_CASE(UI4_ONE, tcu::IVec4(1));
872 UNIFORM_CASE(UI4_TWO, tcu::IVec4(2));
873 UNIFORM_CASE(UI4_THREE, tcu::IVec4(3));
874 UNIFORM_CASE(UI4_FOUR, tcu::IVec4(4));
875 UNIFORM_CASE(UI4_FIVE, tcu::IVec4(5));
876
877 // Float
878 UNIFORM_CASE(UF_ZERO, 0.0f);
879 UNIFORM_CASE(UF_ONE, 1.0f);
880 UNIFORM_CASE(UF_TWO, 2.0f);
881 UNIFORM_CASE(UF_THREE, 3.0f);
882 UNIFORM_CASE(UF_FOUR, 4.0f);
883 UNIFORM_CASE(UF_FIVE, 5.0f);
884 UNIFORM_CASE(UF_SIX, 6.0f);
885 UNIFORM_CASE(UF_SEVEN, 7.0f);
886 UNIFORM_CASE(UF_EIGHT, 8.0f);
887
888 UNIFORM_CASE(UF_HALF, 1.0f / 2.0f);
889 UNIFORM_CASE(UF_THIRD, 1.0f / 3.0f);
890 UNIFORM_CASE(UF_FOURTH, 1.0f / 4.0f);
891 UNIFORM_CASE(UF_FIFTH, 1.0f / 5.0f);
892 UNIFORM_CASE(UF_SIXTH, 1.0f / 6.0f);
893 UNIFORM_CASE(UF_SEVENTH, 1.0f / 7.0f);
894 UNIFORM_CASE(UF_EIGHTH, 1.0f / 8.0f);
895
896 // Vec2
897 UNIFORM_CASE(UV2_MINUS_ONE, tcu::Vec2(-1.0f));
898 UNIFORM_CASE(UV2_ZERO, tcu::Vec2(0.0f));
899 UNIFORM_CASE(UV2_ONE, tcu::Vec2(1.0f));
900 UNIFORM_CASE(UV2_TWO, tcu::Vec2(2.0f));
901 UNIFORM_CASE(UV2_THREE, tcu::Vec2(3.0f));
902
903 UNIFORM_CASE(UV2_HALF, tcu::Vec2(1.0f / 2.0f));
904
905 // Vec3
906 UNIFORM_CASE(UV3_MINUS_ONE, tcu::Vec3(-1.0f));
907 UNIFORM_CASE(UV3_ZERO, tcu::Vec3(0.0f));
908 UNIFORM_CASE(UV3_ONE, tcu::Vec3(1.0f));
909 UNIFORM_CASE(UV3_TWO, tcu::Vec3(2.0f));
910 UNIFORM_CASE(UV3_THREE, tcu::Vec3(3.0f));
911
912 UNIFORM_CASE(UV3_HALF, tcu::Vec3(1.0f / 2.0f));
913
914 // Vec4
915 UNIFORM_CASE(UV4_MINUS_ONE, tcu::Vec4(-1.0f));
916 UNIFORM_CASE(UV4_ZERO, tcu::Vec4(0.0f));
917 UNIFORM_CASE(UV4_ONE, tcu::Vec4(1.0f));
918 UNIFORM_CASE(UV4_TWO, tcu::Vec4(2.0f));
919 UNIFORM_CASE(UV4_THREE, tcu::Vec4(3.0f));
920
921 UNIFORM_CASE(UV4_HALF, tcu::Vec4(1.0f / 2.0f));
922
923 UNIFORM_CASE(UV4_BLACK, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
924 UNIFORM_CASE(UV4_GRAY, tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
925 UNIFORM_CASE(UV4_WHITE, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
926
927 default:
928 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unknown Uniform type: " << type << tcu::TestLog::EndMessage;
929 break;
930 }
931
932 #undef UNIFORM_CASE
933 }
934
getViewportSize(void) const935 const tcu::UVec2 ShaderRenderCaseInstance::getViewportSize (void) const
936 {
937 return tcu::UVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH),
938 de::min(m_renderSize.y(), MAX_RENDER_HEIGHT));
939 }
940
setSampleCount(VkSampleCountFlagBits sampleCount)941 void ShaderRenderCaseInstance::setSampleCount (VkSampleCountFlagBits sampleCount)
942 {
943 m_sampleCount = sampleCount;
944 }
945
isMultiSampling(void) const946 bool ShaderRenderCaseInstance::isMultiSampling (void) const
947 {
948 return m_sampleCount != VK_SAMPLE_COUNT_1_BIT;
949 }
950
uploadImage(const tcu::TextureFormat & texFormat,const TextureData & textureData,const tcu::Sampler & refSampler,deUint32 mipLevels,deUint32 arrayLayers,VkImage destImage)951 void ShaderRenderCaseInstance::uploadImage (const tcu::TextureFormat& texFormat,
952 const TextureData& textureData,
953 const tcu::Sampler& refSampler,
954 deUint32 mipLevels,
955 deUint32 arrayLayers,
956 VkImage destImage)
957 {
958 const VkDevice vkDevice = getDevice();
959 const DeviceInterface& vk = getDeviceInterface();
960 const VkQueue queue = getUniversalQueue();
961 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex();
962
963 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
964 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
965 deUint32 bufferSize = 0u;
966 Move<VkBuffer> buffer;
967 de::MovePtr<Allocation> bufferAlloc;
968 Move<VkCommandPool> cmdPool;
969 Move<VkCommandBuffer> cmdBuffer;
970 std::vector<VkBufferImageCopy> copyRegions;
971 std::vector<deUint32> offsetMultiples;
972
973 offsetMultiples.push_back(4u);
974 offsetMultiples.push_back(texFormat.getPixelSize());
975
976 // Calculate buffer size
977 for (TextureData::const_iterator mit = textureData.begin(); mit != textureData.end(); ++mit)
978 {
979 for (TextureLayerData::const_iterator lit = mit->begin(); lit != mit->end(); ++lit)
980 {
981 const tcu::ConstPixelBufferAccess& access = *lit;
982
983 bufferSize = getNextMultiple(offsetMultiples, bufferSize);
984 bufferSize += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
985 }
986 }
987
988 // Create source buffer
989 {
990 const VkBufferCreateInfo bufferParams =
991 {
992 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
993 DE_NULL, // const void* pNext;
994 0u, // VkBufferCreateFlags flags;
995 bufferSize, // VkDeviceSize size;
996 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
997 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
998 0u, // deUint32 queueFamilyIndexCount;
999 DE_NULL, // const deUint32* pQueueFamilyIndices;
1000 };
1001
1002 buffer = createBuffer(vk, vkDevice, &bufferParams);
1003 bufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
1004 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
1005 }
1006
1007 // Get copy regions and write buffer data
1008 {
1009 deUint32 layerDataOffset = 0;
1010 deUint8* destPtr = (deUint8*)bufferAlloc->getHostPtr();
1011
1012 for (size_t levelNdx = 0; levelNdx < textureData.size(); levelNdx++)
1013 {
1014 const TextureLayerData& layerData = textureData[levelNdx];
1015
1016 for (size_t layerNdx = 0; layerNdx < layerData.size(); layerNdx++)
1017 {
1018 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
1019
1020 const tcu::ConstPixelBufferAccess& access = layerData[layerNdx];
1021 const tcu::PixelBufferAccess destAccess (access.getFormat(), access.getSize(), destPtr + layerDataOffset);
1022
1023 const VkBufferImageCopy layerRegion =
1024 {
1025 layerDataOffset, // VkDeviceSize bufferOffset;
1026 (deUint32)access.getWidth(), // deUint32 bufferRowLength;
1027 (deUint32)access.getHeight(), // deUint32 bufferImageHeight;
1028 { // VkImageSubresourceLayers imageSubresource;
1029 aspectMask, // VkImageAspectFlags aspectMask;
1030 (deUint32)levelNdx, // uint32_t mipLevel;
1031 (deUint32)layerNdx, // uint32_t baseArrayLayer;
1032 1u // uint32_t layerCount;
1033 },
1034 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1035 { // VkExtent3D imageExtent;
1036 (deUint32)access.getWidth(),
1037 (deUint32)access.getHeight(),
1038 (deUint32)access.getDepth()
1039 }
1040 };
1041
1042 copyRegions.push_back(layerRegion);
1043 tcu::copy(destAccess, access);
1044
1045 layerDataOffset += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1046 }
1047 }
1048 }
1049
1050 flushAlloc(vk, vkDevice, *bufferAlloc);
1051
1052 copyBufferToImage(vk, vkDevice, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, DE_NULL, aspectMask, mipLevels, arrayLayers, destImage);
1053 }
1054
clearImage(const tcu::Sampler & refSampler,deUint32 mipLevels,deUint32 arrayLayers,VkImage destImage)1055 void ShaderRenderCaseInstance::clearImage (const tcu::Sampler& refSampler,
1056 deUint32 mipLevels,
1057 deUint32 arrayLayers,
1058 VkImage destImage)
1059 {
1060 const VkDevice vkDevice = m_context.getDevice();
1061 const DeviceInterface& vk = m_context.getDeviceInterface();
1062 const VkQueue queue = m_context.getUniversalQueue();
1063 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1064
1065 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1066 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1067 Move<VkCommandPool> cmdPool;
1068 Move<VkCommandBuffer> cmdBuffer;
1069
1070 VkClearValue clearValue;
1071 deMemset(&clearValue, 0, sizeof(clearValue));
1072
1073
1074 // Create command pool and buffer
1075 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1076 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1077
1078 const VkImageMemoryBarrier preImageBarrier =
1079 {
1080 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1081 DE_NULL, // const void* pNext;
1082 0u, // VkAccessFlags srcAccessMask;
1083 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1084 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1085 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1086 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1087 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1088 destImage, // VkImage image;
1089 { // VkImageSubresourceRange subresourceRange;
1090 aspectMask, // VkImageAspect aspect;
1091 0u, // deUint32 baseMipLevel;
1092 mipLevels, // deUint32 mipLevels;
1093 0u, // deUint32 baseArraySlice;
1094 arrayLayers // deUint32 arraySize;
1095 }
1096 };
1097
1098 const VkImageMemoryBarrier postImageBarrier =
1099 {
1100 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1101 DE_NULL, // const void* pNext;
1102 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1103 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
1104 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1105 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
1106 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1107 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1108 destImage, // VkImage image;
1109 { // VkImageSubresourceRange subresourceRange;
1110 aspectMask, // VkImageAspect aspect;
1111 0u, // deUint32 baseMipLevel;
1112 mipLevels, // deUint32 mipLevels;
1113 0u, // deUint32 baseArraySlice;
1114 arrayLayers // deUint32 arraySize;
1115 }
1116 };
1117
1118 const VkImageSubresourceRange clearRange =
1119 {
1120 aspectMask, // VkImageAspectFlags aspectMask;
1121 0u, // deUint32 baseMipLevel;
1122 mipLevels, // deUint32 levelCount;
1123 0u, // deUint32 baseArrayLayer;
1124 arrayLayers // deUint32 layerCount;
1125 };
1126
1127 // Copy buffer to image
1128 beginCommandBuffer(vk, *cmdBuffer);
1129 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
1130 if (aspectMask == VK_IMAGE_ASPECT_COLOR_BIT)
1131 {
1132 vk.cmdClearColorImage(*cmdBuffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &clearRange);
1133 }
1134 else
1135 {
1136 vk.cmdClearDepthStencilImage(*cmdBuffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.depthStencil, 1, &clearRange);
1137 }
1138 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
1139 endCommandBuffer(vk, *cmdBuffer);
1140
1141 submitCommandsAndWait(vk, vkDevice, queue, cmdBuffer.get());
1142 }
1143
mipLevelExtents(const VkExtent3D & baseExtents,const deUint32 mipLevel)1144 VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, const deUint32 mipLevel)
1145 {
1146 VkExtent3D result;
1147
1148 result.width = std::max(baseExtents.width >> mipLevel, 1u);
1149 result.height = std::max(baseExtents.height >> mipLevel, 1u);
1150 result.depth = std::max(baseExtents.depth >> mipLevel, 1u);
1151
1152 return result;
1153 }
1154
alignedDivide(const VkExtent3D & extent,const VkExtent3D & divisor)1155 tcu::UVec3 alignedDivide (const VkExtent3D& extent, const VkExtent3D& divisor)
1156 {
1157 tcu::UVec3 result;
1158
1159 result.x() = extent.width / divisor.width + ((extent.width % divisor.width != 0) ? 1u : 0u);
1160 result.y() = extent.height / divisor.height + ((extent.height % divisor.height != 0) ? 1u : 0u);
1161 result.z() = extent.depth / divisor.depth + ((extent.depth % divisor.depth != 0) ? 1u : 0u);
1162
1163 return result;
1164 }
1165
isImageSizeSupported(const VkImageType imageType,const tcu::UVec3 & imageSize,const vk::VkPhysicalDeviceLimits & limits)1166 bool isImageSizeSupported (const VkImageType imageType, const tcu::UVec3& imageSize, const vk::VkPhysicalDeviceLimits& limits)
1167 {
1168 switch (imageType)
1169 {
1170 case VK_IMAGE_TYPE_1D:
1171 return (imageSize.x() <= limits.maxImageDimension1D
1172 && imageSize.y() == 1
1173 && imageSize.z() == 1);
1174 case VK_IMAGE_TYPE_2D:
1175 return (imageSize.x() <= limits.maxImageDimension2D
1176 && imageSize.y() <= limits.maxImageDimension2D
1177 && imageSize.z() == 1);
1178 case VK_IMAGE_TYPE_3D:
1179 return (imageSize.x() <= limits.maxImageDimension3D
1180 && imageSize.y() <= limits.maxImageDimension3D
1181 && imageSize.z() <= limits.maxImageDimension3D);
1182 default:
1183 DE_FATAL("Unknown image type");
1184 return false;
1185 }
1186 }
1187
checkSparseSupport(const VkImageCreateInfo & imageInfo) const1188 void ShaderRenderCaseInstance::checkSparseSupport (const VkImageCreateInfo& imageInfo) const
1189 {
1190 const InstanceInterface& instance = getInstanceInterface();
1191 const VkPhysicalDevice physicalDevice = getPhysicalDevice();
1192 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice);
1193
1194 const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties(
1195 instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling);
1196
1197 if (!deviceFeatures.shaderResourceResidency)
1198 TCU_THROW(NotSupportedError, "Required feature: shaderResourceResidency.");
1199
1200 if (!deviceFeatures.sparseBinding)
1201 TCU_THROW(NotSupportedError, "Required feature: sparseBinding.");
1202
1203 if (imageInfo.imageType == VK_IMAGE_TYPE_2D && !deviceFeatures.sparseResidencyImage2D)
1204 TCU_THROW(NotSupportedError, "Required feature: sparseResidencyImage2D.");
1205
1206 if (imageInfo.imageType == VK_IMAGE_TYPE_3D && !deviceFeatures.sparseResidencyImage3D)
1207 TCU_THROW(NotSupportedError, "Required feature: sparseResidencyImage3D.");
1208
1209 if (sparseImageFormatPropVec.size() == 0)
1210 TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
1211 }
1212
uploadSparseImage(const tcu::TextureFormat & texFormat,const TextureData & textureData,const tcu::Sampler & refSampler,const deUint32 mipLevels,const deUint32 arrayLayers,const VkImage sparseImage,const VkImageCreateInfo & imageCreateInfo,const tcu::UVec3 texSize)1213 void ShaderRenderCaseInstance::uploadSparseImage (const tcu::TextureFormat& texFormat,
1214 const TextureData& textureData,
1215 const tcu::Sampler& refSampler,
1216 const deUint32 mipLevels,
1217 const deUint32 arrayLayers,
1218 const VkImage sparseImage,
1219 const VkImageCreateInfo& imageCreateInfo,
1220 const tcu::UVec3 texSize)
1221 {
1222 const VkDevice vkDevice = getDevice();
1223 const DeviceInterface& vk = getDeviceInterface();
1224 const VkPhysicalDevice physicalDevice = getPhysicalDevice();
1225 const VkQueue queue = getUniversalQueue();
1226 const VkQueue sparseQueue = getSparseQueue();
1227 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex();
1228 const InstanceInterface& instance = getInstanceInterface();
1229 const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
1230 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1231 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1232 const Unique<VkSemaphore> imageMemoryBindSemaphore(createSemaphore(vk, vkDevice));
1233 Move<VkBuffer> buffer;
1234 deUint32 bufferSize = 0u;
1235 de::MovePtr<Allocation> bufferAlloc;
1236 std::vector<VkBufferImageCopy> copyRegions;
1237 std::vector<deUint32> offsetMultiples;
1238
1239 offsetMultiples.push_back(4u);
1240 offsetMultiples.push_back(texFormat.getPixelSize());
1241
1242 if (isImageSizeSupported(imageCreateInfo.imageType, texSize, deviceProperties.limits) == false)
1243 TCU_THROW(NotSupportedError, "Image size not supported for device.");
1244
1245 allocateAndBindSparseImage(vk, vkDevice, physicalDevice, instance, imageCreateInfo, *imageMemoryBindSemaphore, sparseQueue, m_memAlloc, m_allocations, texFormat, sparseImage);
1246
1247 // Calculate buffer size
1248 for (TextureData::const_iterator mit = textureData.begin(); mit != textureData.end(); ++mit)
1249 {
1250 for (TextureLayerData::const_iterator lit = mit->begin(); lit != mit->end(); ++lit)
1251 {
1252 const tcu::ConstPixelBufferAccess& access = *lit;
1253
1254 bufferSize = getNextMultiple(offsetMultiples, bufferSize);
1255 bufferSize += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1256 }
1257 }
1258
1259 {
1260 // Create source buffer
1261 const VkBufferCreateInfo bufferParams =
1262 {
1263 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1264 DE_NULL, // const void* pNext;
1265 0u, // VkBufferCreateFlags flags;
1266 bufferSize, // VkDeviceSize size;
1267 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
1268 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1269 0u, // deUint32 queueFamilyIndexCount;
1270 DE_NULL, // const deUint32* pQueueFamilyIndices;
1271 };
1272
1273 buffer = createBuffer(vk, vkDevice, &bufferParams);
1274 bufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
1275
1276 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
1277 }
1278
1279 // Get copy regions and write buffer data
1280 {
1281 deUint32 layerDataOffset = 0;
1282 deUint8* destPtr = (deUint8*)bufferAlloc->getHostPtr();
1283
1284 for (size_t levelNdx = 0; levelNdx < textureData.size(); levelNdx++)
1285 {
1286 const TextureLayerData& layerData = textureData[levelNdx];
1287
1288 for (size_t layerNdx = 0; layerNdx < layerData.size(); layerNdx++)
1289 {
1290 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
1291
1292 const tcu::ConstPixelBufferAccess& access = layerData[layerNdx];
1293 const tcu::PixelBufferAccess destAccess (access.getFormat(), access.getSize(), destPtr + layerDataOffset);
1294
1295 const VkBufferImageCopy layerRegion =
1296 {
1297 layerDataOffset, // VkDeviceSize bufferOffset;
1298 (deUint32)access.getWidth(), // deUint32 bufferRowLength;
1299 (deUint32)access.getHeight(), // deUint32 bufferImageHeight;
1300 { // VkImageSubresourceLayers imageSubresource;
1301 aspectMask, // VkImageAspectFlags aspectMask;
1302 (deUint32)levelNdx, // uint32_t mipLevel;
1303 (deUint32)layerNdx, // uint32_t baseArrayLayer;
1304 1u // uint32_t layerCount;
1305 },
1306 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1307 { // VkExtent3D imageExtent;
1308 (deUint32)access.getWidth(),
1309 (deUint32)access.getHeight(),
1310 (deUint32)access.getDepth()
1311 }
1312 };
1313
1314 copyRegions.push_back(layerRegion);
1315 tcu::copy(destAccess, access);
1316
1317 layerDataOffset += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1318 }
1319 }
1320 }
1321 copyBufferToImage(vk, vkDevice, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, &(*imageMemoryBindSemaphore), aspectMask, mipLevels, arrayLayers, sparseImage);
1322 }
1323
useSampler(deUint32 bindingLocation,deUint32 textureId)1324 void ShaderRenderCaseInstance::useSampler (deUint32 bindingLocation, deUint32 textureId)
1325 {
1326 DE_ASSERT(textureId < m_textures.size());
1327
1328 const TextureBinding& textureBinding = *m_textures[textureId];
1329 const TextureBinding::Type textureType = textureBinding.getType();
1330 const tcu::Sampler& refSampler = textureBinding.getSampler();
1331 const TextureBinding::Parameters& textureParams = textureBinding.getParameters();
1332 const bool isMSTexture = textureParams.samples != vk::VK_SAMPLE_COUNT_1_BIT;
1333 deUint32 mipLevels = 1u;
1334 deUint32 arrayLayers = 1u;
1335 tcu::TextureFormat texFormat;
1336 tcu::UVec3 texSize;
1337 TextureData textureData;
1338
1339 if (textureType == TextureBinding::TYPE_2D)
1340 {
1341 const tcu::Texture2D& texture = textureBinding.get2D();
1342
1343 texFormat = texture.getFormat();
1344 texSize = tcu::UVec3(texture.getWidth(), texture.getHeight(), 1u);
1345 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1346 arrayLayers = 1u;
1347
1348 textureData.resize(mipLevels);
1349
1350 for (deUint32 level = 0; level < mipLevels; ++level)
1351 {
1352 if (texture.isLevelEmpty(level))
1353 continue;
1354
1355 textureData[level].push_back(texture.getLevel(level));
1356 }
1357 }
1358 else if (textureType == TextureBinding::TYPE_CUBE_MAP)
1359 {
1360 const tcu::TextureCube& texture = textureBinding.getCube();
1361
1362 texFormat = texture.getFormat();
1363 texSize = tcu::UVec3(texture.getSize(), texture.getSize(), 1u);
1364 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1365 arrayLayers = 6u;
1366
1367 static const tcu::CubeFace cubeFaceMapping[tcu::CUBEFACE_LAST] =
1368 {
1369 tcu::CUBEFACE_POSITIVE_X,
1370 tcu::CUBEFACE_NEGATIVE_X,
1371 tcu::CUBEFACE_POSITIVE_Y,
1372 tcu::CUBEFACE_NEGATIVE_Y,
1373 tcu::CUBEFACE_POSITIVE_Z,
1374 tcu::CUBEFACE_NEGATIVE_Z
1375 };
1376
1377 textureData.resize(mipLevels);
1378
1379 for (deUint32 level = 0; level < mipLevels; ++level)
1380 {
1381 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; ++faceNdx)
1382 {
1383 tcu::CubeFace face = cubeFaceMapping[faceNdx];
1384
1385 if (texture.isLevelEmpty(face, level))
1386 continue;
1387
1388 textureData[level].push_back(texture.getLevelFace(level, face));
1389 }
1390 }
1391 }
1392 else if (textureType == TextureBinding::TYPE_2D_ARRAY)
1393 {
1394 const tcu::Texture2DArray& texture = textureBinding.get2DArray();
1395
1396 texFormat = texture.getFormat();
1397 texSize = tcu::UVec3(texture.getWidth(), texture.getHeight(), 1u);
1398 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1399 arrayLayers = (deUint32)texture.getNumLayers();
1400
1401 textureData.resize(mipLevels);
1402
1403 for (deUint32 level = 0; level < mipLevels; ++level)
1404 {
1405 if (texture.isLevelEmpty(level))
1406 continue;
1407
1408 const tcu::ConstPixelBufferAccess& levelLayers = texture.getLevel(level);
1409 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1410
1411 for (deUint32 layer = 0; layer < arrayLayers; ++layer)
1412 {
1413 const deUint32 layerOffset = layerSize * layer;
1414 tcu::ConstPixelBufferAccess layerData (levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1415 textureData[level].push_back(layerData);
1416 }
1417 }
1418 }
1419 else if (textureType == TextureBinding::TYPE_3D)
1420 {
1421 const tcu::Texture3D& texture = textureBinding.get3D();
1422
1423 texFormat = texture.getFormat();
1424 texSize = tcu::UVec3(texture.getWidth(), texture.getHeight(), texture.getDepth());
1425 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1426 arrayLayers = 1u;
1427
1428 textureData.resize(mipLevels);
1429
1430 for (deUint32 level = 0; level < mipLevels; ++level)
1431 {
1432 if (texture.isLevelEmpty(level))
1433 continue;
1434
1435 textureData[level].push_back(texture.getLevel(level));
1436 }
1437 }
1438 else if (textureType == TextureBinding::TYPE_1D)
1439 {
1440 const tcu::Texture1D& texture = textureBinding.get1D();
1441
1442 texFormat = texture.getFormat();
1443 texSize = tcu::UVec3(texture.getWidth(), 1, 1);
1444 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1445 arrayLayers = 1u;
1446
1447 textureData.resize(mipLevels);
1448
1449 for (deUint32 level = 0; level < mipLevels; ++level)
1450 {
1451 if (texture.isLevelEmpty(level))
1452 continue;
1453
1454 textureData[level].push_back(texture.getLevel(level));
1455 }
1456 }
1457 else if (textureType == TextureBinding::TYPE_1D_ARRAY)
1458 {
1459 const tcu::Texture1DArray& texture = textureBinding.get1DArray();
1460
1461 texFormat = texture.getFormat();
1462 texSize = tcu::UVec3(texture.getWidth(), 1, 1);
1463 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1464 arrayLayers = (deUint32)texture.getNumLayers();
1465
1466 textureData.resize(mipLevels);
1467
1468 for (deUint32 level = 0; level < mipLevels; ++level)
1469 {
1470 if (texture.isLevelEmpty(level))
1471 continue;
1472
1473 const tcu::ConstPixelBufferAccess& levelLayers = texture.getLevel(level);
1474 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
1475
1476 for (deUint32 layer = 0; layer < arrayLayers; ++layer)
1477 {
1478 const deUint32 layerOffset = layerSize * layer;
1479 tcu::ConstPixelBufferAccess layerData (levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1480 textureData[level].push_back(layerData);
1481 }
1482 }
1483 }
1484 else if (textureType == TextureBinding::TYPE_CUBE_ARRAY)
1485 {
1486 const tcu::TextureCubeArray& texture = textureBinding.getCubeArray();
1487 texFormat = texture.getFormat();
1488 texSize = tcu::UVec3(texture.getSize(), texture.getSize(), 1);
1489 mipLevels = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1490 arrayLayers = texture.getDepth();
1491
1492 textureData.resize(mipLevels);
1493
1494 for (deUint32 level = 0; level < mipLevels; ++level)
1495 {
1496 if (texture.isLevelEmpty(level))
1497 continue;
1498
1499 const tcu::ConstPixelBufferAccess& levelLayers = texture.getLevel(level);
1500 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1501
1502 for (deUint32 layer = 0; layer < arrayLayers; ++layer)
1503 {
1504 const deUint32 layerOffset = layerSize * layer;
1505 tcu::ConstPixelBufferAccess layerData (levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1506 textureData[level].push_back(layerData);
1507 }
1508 }
1509 }
1510 else
1511 {
1512 TCU_THROW(InternalError, "Invalid texture type");
1513 }
1514
1515 createSamplerUniform(bindingLocation, textureType, textureBinding.getParameters().initialization, texFormat, texSize, textureData, refSampler, mipLevels, arrayLayers, textureParams);
1516 }
1517
setPushConstantRanges(const deUint32 rangeCount,const vk::VkPushConstantRange * const pcRanges)1518 void ShaderRenderCaseInstance::setPushConstantRanges (const deUint32 rangeCount, const vk::VkPushConstantRange* const pcRanges)
1519 {
1520 m_pushConstantRanges.clear();
1521 for (deUint32 i = 0; i < rangeCount; ++i)
1522 {
1523 m_pushConstantRanges.push_back(pcRanges[i]);
1524 }
1525 }
1526
updatePushConstants(vk::VkCommandBuffer,vk::VkPipelineLayout)1527 void ShaderRenderCaseInstance::updatePushConstants (vk::VkCommandBuffer, vk::VkPipelineLayout)
1528 {
1529 }
1530
createSamplerUniform(deUint32 bindingLocation,TextureBinding::Type textureType,TextureBinding::Init textureInit,const tcu::TextureFormat & texFormat,const tcu::UVec3 texSize,const TextureData & textureData,const tcu::Sampler & refSampler,deUint32 mipLevels,deUint32 arrayLayers,TextureBinding::Parameters textureParams)1531 void ShaderRenderCaseInstance::createSamplerUniform (deUint32 bindingLocation,
1532 TextureBinding::Type textureType,
1533 TextureBinding::Init textureInit,
1534 const tcu::TextureFormat& texFormat,
1535 const tcu::UVec3 texSize,
1536 const TextureData& textureData,
1537 const tcu::Sampler& refSampler,
1538 deUint32 mipLevels,
1539 deUint32 arrayLayers,
1540 TextureBinding::Parameters textureParams)
1541 {
1542 const VkDevice vkDevice = getDevice();
1543 const DeviceInterface& vk = getDeviceInterface();
1544 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex();
1545 const deUint32 sparseFamilyIndex = (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE) ? getSparseQueueFamilyIndex() : queueFamilyIndex;
1546
1547 const bool isShadowSampler = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1548 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1549 const VkImageViewType imageViewType = textureTypeToImageViewType(textureType);
1550 const VkImageType imageType = viewTypeToImageType(imageViewType);
1551 const VkSharingMode sharingMode = (queueFamilyIndex != sparseFamilyIndex) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;
1552 const VkFormat format = mapTextureFormat(texFormat);
1553 const bool isCube = imageViewType == VK_IMAGE_VIEW_TYPE_CUBE || imageViewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
1554
1555 const deUint32 queueIndexCount = (queueFamilyIndex != sparseFamilyIndex) ? 2 : 1;
1556 const deUint32 queueIndices[] =
1557 {
1558 queueFamilyIndex,
1559 sparseFamilyIndex
1560 };
1561
1562 VkImageCreateFlags imageCreateFlags = isCube ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlags)0;
1563 VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1564 Move<VkImage> vkTexture;
1565 de::MovePtr<Allocation> allocation;
1566
1567 if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
1568 {
1569 imageCreateFlags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;
1570 }
1571
1572 // Create image
1573 const VkImageCreateInfo imageParams =
1574 {
1575 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1576 DE_NULL, // const void* pNext;
1577 imageCreateFlags, // VkImageCreateFlags flags;
1578 imageType, // VkImageType imageType;
1579 format, // VkFormat format;
1580 { // VkExtent3D extent;
1581 texSize.x(),
1582 texSize.y(),
1583 texSize.z()
1584 },
1585 mipLevels, // deUint32 mipLevels;
1586 arrayLayers, // deUint32 arrayLayers;
1587 textureParams.samples, // VkSampleCountFlagBits samples;
1588 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1589 imageUsageFlags, // VkImageUsageFlags usage;
1590 sharingMode, // VkSharingMode sharingMode;
1591 queueIndexCount, // deUint32 queueFamilyIndexCount;
1592 queueIndices, // const deUint32* pQueueFamilyIndices;
1593 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1594 };
1595
1596 if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
1597 {
1598 checkSparseSupport(imageParams);
1599 }
1600
1601 vkTexture = createImage(vk, vkDevice, &imageParams);
1602 allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any);
1603
1604 if (m_imageBackingMode != IMAGE_BACKING_MODE_SPARSE)
1605 {
1606 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset()));
1607 }
1608
1609 switch (textureInit)
1610 {
1611 case TextureBinding::INIT_UPLOAD_DATA:
1612 {
1613 // upload*Image functions use cmdCopyBufferToImage, which is invalid for multisample images
1614 DE_ASSERT(textureParams.samples == VK_SAMPLE_COUNT_1_BIT);
1615
1616 if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
1617 {
1618 uploadSparseImage(texFormat, textureData, refSampler, mipLevels, arrayLayers, *vkTexture, imageParams, texSize);
1619 }
1620 else
1621 {
1622 // Upload texture data
1623 uploadImage(texFormat, textureData, refSampler, mipLevels, arrayLayers, *vkTexture);
1624 }
1625 break;
1626 }
1627 case TextureBinding::INIT_CLEAR:
1628 clearImage(refSampler, mipLevels, arrayLayers, *vkTexture);
1629 break;
1630 default:
1631 DE_FATAL("Impossible");
1632 }
1633
1634 // Create sampler
1635 const VkSamplerCreateInfo samplerParams = mapSampler(refSampler, texFormat);
1636 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams);
1637 const deUint32 baseMipLevel = textureParams.baseMipLevel;
1638 const vk::VkComponentMapping components = textureParams.componentMapping;
1639 const VkImageViewCreateInfo viewParams =
1640 {
1641 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1642 NULL, // const voide* pNext;
1643 0u, // VkImageViewCreateFlags flags;
1644 *vkTexture, // VkImage image;
1645 imageViewType, // VkImageViewType viewType;
1646 format, // VkFormat format;
1647 components, // VkChannelMapping channels;
1648 {
1649 aspectMask, // VkImageAspectFlags aspectMask;
1650 baseMipLevel, // deUint32 baseMipLevel;
1651 mipLevels - baseMipLevel, // deUint32 mipLevels;
1652 0, // deUint32 baseArraySlice;
1653 arrayLayers // deUint32 arraySize;
1654 }, // VkImageSubresourceRange subresourceRange;
1655 };
1656
1657 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams);
1658
1659 const vk::VkDescriptorImageInfo descriptor =
1660 {
1661 sampler.get(), // VkSampler sampler;
1662 imageView.get(), // VkImageView imageView;
1663 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout imageLayout;
1664 };
1665
1666 de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
1667 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1668 uniform->descriptor = descriptor;
1669 uniform->location = bindingLocation;
1670 uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture));
1671 uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView));
1672 uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler));
1673 uniform->alloc = AllocationSp(allocation.release());
1674
1675 m_descriptorSetLayoutBuilder->addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_ALL, DE_NULL);
1676 m_descriptorPoolBuilder->addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
1677
1678 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform)));
1679 }
1680
setupDefaultInputs(void)1681 void ShaderRenderCaseInstance::setupDefaultInputs (void)
1682 {
1683 /* Configuration of the vertex input attributes:
1684 a_position is at location 0
1685 a_coords is at location 1
1686 a_unitCoords is at location 2
1687 a_one is at location 3
1688
1689 User attributes starts from at the location 4.
1690 */
1691
1692 DE_ASSERT(m_quadGrid);
1693 const QuadGrid& quadGrid = *m_quadGrid;
1694
1695 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions());
1696 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords());
1697 addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords());
1698 addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne());
1699
1700 static const struct
1701 {
1702 BaseAttributeType type;
1703 int userNdx;
1704 } userAttributes[] =
1705 {
1706 { A_IN0, 0 },
1707 { A_IN1, 1 },
1708 { A_IN2, 2 },
1709 { A_IN3, 3 }
1710 };
1711
1712 static const struct
1713 {
1714 BaseAttributeType matrixType;
1715 int numCols;
1716 int numRows;
1717 } matrices[] =
1718 {
1719 { MAT2, 2, 2 },
1720 { MAT2x3, 2, 3 },
1721 { MAT2x4, 2, 4 },
1722 { MAT3x2, 3, 2 },
1723 { MAT3, 3, 3 },
1724 { MAT3x4, 3, 4 },
1725 { MAT4x2, 4, 2 },
1726 { MAT4x3, 4, 3 },
1727 { MAT4, 4, 4 }
1728 };
1729
1730 for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++)
1731 {
1732 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++)
1733 {
1734 if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type)
1735 continue;
1736
1737 addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx));
1738 }
1739
1740 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++)
1741 {
1742
1743 if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type)
1744 continue;
1745
1746 const int numCols = matrices[matNdx].numCols;
1747
1748 for (int colNdx = 0; colNdx < numCols; colNdx++)
1749 {
1750 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(4 * sizeof(float)), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx));
1751 }
1752 }
1753 }
1754 }
1755
render(deUint32 numVertices,deUint32 numTriangles,const deUint16 * indices,const tcu::Vec4 & constCoords)1756 void ShaderRenderCaseInstance::render (deUint32 numVertices,
1757 deUint32 numTriangles,
1758 const deUint16* indices,
1759 const tcu::Vec4& constCoords)
1760 {
1761 render(numVertices, numTriangles * 3, indices, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, constCoords);
1762 }
1763
render(deUint32 numVertices,deUint32 numIndices,const deUint16 * indices,VkPrimitiveTopology topology,const tcu::Vec4 & constCoords)1764 void ShaderRenderCaseInstance::render (deUint32 numVertices,
1765 deUint32 numIndices,
1766 const deUint16* indices,
1767 VkPrimitiveTopology topology,
1768 const tcu::Vec4& constCoords)
1769 {
1770 const VkDevice vkDevice = getDevice();
1771 const DeviceInterface& vk = getDeviceInterface();
1772 const VkQueue queue = getUniversalQueue();
1773 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex();
1774
1775 vk::Move<vk::VkImage> colorImage;
1776 de::MovePtr<vk::Allocation> colorImageAlloc;
1777 vk::Move<vk::VkImageView> colorImageView;
1778 vk::Move<vk::VkImage> resolvedImage;
1779 de::MovePtr<vk::Allocation> resolvedImageAlloc;
1780 vk::Move<vk::VkImageView> resolvedImageView;
1781 vk::Move<vk::VkRenderPass> renderPass;
1782 vk::Move<vk::VkFramebuffer> framebuffer;
1783 vk::Move<vk::VkPipelineLayout> pipelineLayout;
1784 vk::Move<vk::VkPipeline> graphicsPipeline;
1785 vk::Move<vk::VkShaderModule> vertexShaderModule;
1786 vk::Move<vk::VkShaderModule> fragmentShaderModule;
1787 vk::Move<vk::VkBuffer> indexBuffer;
1788 de::MovePtr<vk::Allocation> indexBufferAlloc;
1789 vk::Move<vk::VkDescriptorSetLayout> descriptorSetLayout;
1790 vk::Move<vk::VkDescriptorPool> descriptorPool;
1791 vk::Move<vk::VkDescriptorSet> descriptorSet;
1792 vk::Move<vk::VkCommandPool> cmdPool;
1793 vk::Move<vk::VkCommandBuffer> cmdBuffer;
1794
1795 // Create color image
1796 {
1797 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1798 VkImageFormatProperties properties;
1799
1800 if ((getInstanceInterface().getPhysicalDeviceImageFormatProperties(getPhysicalDevice(),
1801 m_colorFormat,
1802 VK_IMAGE_TYPE_2D,
1803 VK_IMAGE_TILING_OPTIMAL,
1804 imageUsage,
1805 0u,
1806 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1807 {
1808 TCU_THROW(NotSupportedError, "Format not supported");
1809 }
1810
1811 if ((properties.sampleCounts & m_sampleCount) != m_sampleCount)
1812 {
1813 TCU_THROW(NotSupportedError, "Format not supported");
1814 }
1815
1816 const VkImageCreateInfo colorImageParams =
1817 {
1818 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1819 DE_NULL, // const void* pNext;
1820 0u, // VkImageCreateFlags flags;
1821 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1822 m_colorFormat, // VkFormat format;
1823 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
1824 1u, // deUint32 mipLevels;
1825 1u, // deUint32 arraySize;
1826 m_sampleCount, // deUint32 samples;
1827 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1828 imageUsage, // VkImageUsageFlags usage;
1829 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1830 1u, // deUint32 queueFamilyCount;
1831 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1832 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1833 };
1834
1835 colorImage = createImage(vk, vkDevice, &colorImageParams);
1836
1837 // Allocate and bind color image memory
1838 colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any);
1839 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
1840 }
1841
1842 // Create color attachment view
1843 {
1844 const VkImageViewCreateInfo colorImageViewParams =
1845 {
1846 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1847 DE_NULL, // const void* pNext;
1848 0u, // VkImageViewCreateFlags flags;
1849 *colorImage, // VkImage image;
1850 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1851 m_colorFormat, // VkFormat format;
1852 {
1853 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r;
1854 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g;
1855 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b;
1856 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a;
1857 }, // VkChannelMapping channels;
1858 {
1859 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1860 0, // deUint32 baseMipLevel;
1861 1, // deUint32 mipLevels;
1862 0, // deUint32 baseArraySlice;
1863 1 // deUint32 arraySize;
1864 }, // VkImageSubresourceRange subresourceRange;
1865 };
1866
1867 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
1868 }
1869
1870 if (isMultiSampling())
1871 {
1872 // Resolved Image
1873 {
1874 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1875 VkImageFormatProperties properties;
1876
1877 if ((getInstanceInterface().getPhysicalDeviceImageFormatProperties(getPhysicalDevice(),
1878 m_colorFormat,
1879 VK_IMAGE_TYPE_2D,
1880 VK_IMAGE_TILING_OPTIMAL,
1881 imageUsage,
1882 0,
1883 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1884 {
1885 TCU_THROW(NotSupportedError, "Format not supported");
1886 }
1887
1888 const VkImageCreateInfo imageCreateInfo =
1889 {
1890 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1891 DE_NULL, // const void* pNext;
1892 0u, // VkImageCreateFlags flags;
1893 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1894 m_colorFormat, // VkFormat format;
1895 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
1896 1u, // deUint32 mipLevels;
1897 1u, // deUint32 arrayLayers;
1898 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1899 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1900 imageUsage, // VkImageUsageFlags usage;
1901 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1902 1u, // deUint32 queueFamilyIndexCount;
1903 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1904 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1905 };
1906
1907 resolvedImage = vk::createImage(vk, vkDevice, &imageCreateInfo, DE_NULL);
1908 resolvedImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *resolvedImage), MemoryRequirement::Any);
1909 VK_CHECK(vk.bindImageMemory(vkDevice, *resolvedImage, resolvedImageAlloc->getMemory(), resolvedImageAlloc->getOffset()));
1910 }
1911
1912 // Resolved Image View
1913 {
1914 const VkImageViewCreateInfo imageViewCreateInfo =
1915 {
1916 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1917 DE_NULL, // const void* pNext;
1918 0u, // VkImageViewCreateFlags flags;
1919 *resolvedImage, // VkImage image;
1920 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1921 m_colorFormat, // VkFormat format;
1922 {
1923 VK_COMPONENT_SWIZZLE_R, // VkChannelSwizzle r;
1924 VK_COMPONENT_SWIZZLE_G, // VkChannelSwizzle g;
1925 VK_COMPONENT_SWIZZLE_B, // VkChannelSwizzle b;
1926 VK_COMPONENT_SWIZZLE_A // VkChannelSwizzle a;
1927 },
1928 {
1929 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1930 0u, // deUint32 baseMipLevel;
1931 1u, // deUint32 mipLevels;
1932 0u, // deUint32 baseArrayLayer;
1933 1u, // deUint32 arraySize;
1934 }, // VkImageSubresourceRange subresourceRange;
1935 };
1936
1937 resolvedImageView = vk::createImageView(vk, vkDevice, &imageViewCreateInfo, DE_NULL);
1938 }
1939 }
1940
1941 // Create render pass
1942 {
1943 const VkAttachmentDescription attachmentDescription[] =
1944 {
1945 {
1946 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
1947 m_colorFormat, // VkFormat format;
1948 m_sampleCount, // deUint32 samples;
1949 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
1950 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1951 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1952 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1953 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
1954 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
1955 },
1956 {
1957 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
1958 m_colorFormat, // VkFormat format;
1959 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1960 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
1961 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1962 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1963 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1964 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
1965 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
1966 }
1967 };
1968
1969 const VkAttachmentReference attachmentReference =
1970 {
1971 0u, // deUint32 attachment;
1972 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
1973 };
1974
1975 const VkAttachmentReference resolveAttachmentRef =
1976 {
1977 1u, // deUint32 attachment;
1978 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
1979 };
1980
1981 const VkSubpassDescription subpassDescription =
1982 {
1983 0u, // VkSubpassDescriptionFlags flags;
1984 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
1985 0u, // deUint32 inputCount;
1986 DE_NULL, // constVkAttachmentReference* pInputAttachments;
1987 1u, // deUint32 colorCount;
1988 &attachmentReference, // constVkAttachmentReference* pColorAttachments;
1989 isMultiSampling() ? &resolveAttachmentRef : DE_NULL,// constVkAttachmentReference* pResolveAttachments;
1990 DE_NULL, // VkAttachmentReference depthStencilAttachment;
1991 0u, // deUint32 preserveCount;
1992 DE_NULL // constVkAttachmentReference* pPreserveAttachments;
1993 };
1994
1995 const VkRenderPassCreateInfo renderPassParams =
1996 {
1997 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
1998 DE_NULL, // const void* pNext;
1999 0u, // VkRenderPassCreateFlags flags;
2000 isMultiSampling() ? 2u : 1u, // deUint32 attachmentCount;
2001 attachmentDescription, // const VkAttachmentDescription* pAttachments;
2002 1u, // deUint32 subpassCount;
2003 &subpassDescription, // const VkSubpassDescription* pSubpasses;
2004 0u, // deUint32 dependencyCount;
2005 DE_NULL // const VkSubpassDependency* pDependencies;
2006 };
2007
2008 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2009 }
2010
2011 // Create framebuffer
2012 {
2013 const VkImageView attachments[] =
2014 {
2015 *colorImageView,
2016 *resolvedImageView
2017 };
2018
2019 const VkFramebufferCreateInfo framebufferParams =
2020 {
2021 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
2022 DE_NULL, // const void* pNext;
2023 (VkFramebufferCreateFlags)0,
2024 *renderPass, // VkRenderPass renderPass;
2025 isMultiSampling() ? 2u : 1u, // deUint32 attachmentCount;
2026 attachments, // const VkImageView* pAttachments;
2027 (deUint32)m_renderSize.x(), // deUint32 width;
2028 (deUint32)m_renderSize.y(), // deUint32 height;
2029 1u // deUint32 layers;
2030 };
2031
2032 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
2033 }
2034
2035 // Create descriptors
2036 {
2037 setupUniforms(constCoords);
2038
2039 descriptorSetLayout = m_descriptorSetLayoutBuilder->build(vk, vkDevice);
2040 if (!m_uniformInfos.empty())
2041 {
2042 descriptorPool = m_descriptorPoolBuilder->build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2043 const VkDescriptorSetAllocateInfo allocInfo =
2044 {
2045 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2046 DE_NULL,
2047 *descriptorPool,
2048 1u,
2049 &descriptorSetLayout.get(),
2050 };
2051
2052 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2053 }
2054
2055 for (deUint32 i = 0; i < m_uniformInfos.size(); i++)
2056 {
2057 const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
2058 deUint32 location = uniformInfo->location;
2059
2060 if (uniformInfo->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
2061 {
2062 const BufferUniform* bufferInfo = dynamic_cast<const BufferUniform*>(uniformInfo);
2063
2064 m_descriptorSetUpdateBuilder->writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &bufferInfo->descriptor);
2065 }
2066 else if (uniformInfo->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
2067 {
2068 const SamplerUniform* samplerInfo = dynamic_cast<const SamplerUniform*>(uniformInfo);
2069
2070 m_descriptorSetUpdateBuilder->writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &samplerInfo->descriptor);
2071 }
2072 else
2073 DE_FATAL("Impossible");
2074 }
2075
2076 m_descriptorSetUpdateBuilder->update(vk, vkDevice);
2077 }
2078
2079 // Create pipeline layout
2080 {
2081 const VkPushConstantRange* const pcRanges = m_pushConstantRanges.empty() ? DE_NULL : &m_pushConstantRanges[0];
2082 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2083 {
2084 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2085 DE_NULL, // const void* pNext;
2086 (VkPipelineLayoutCreateFlags)0,
2087 1u, // deUint32 descriptorSetCount;
2088 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
2089 deUint32(m_pushConstantRanges.size()), // deUint32 pushConstantRangeCount;
2090 pcRanges // const VkPushConstantRange* pPushConstantRanges;
2091 };
2092
2093 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2094 }
2095
2096 // Create shaders
2097 {
2098 vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(m_vertexShaderName), 0);
2099 fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(m_fragmentShaderName), 0);
2100 }
2101
2102 // Create pipeline
2103 {
2104 // Add test case specific attributes
2105 if (m_attribFunc)
2106 m_attribFunc(*this, numVertices);
2107
2108 // Add base attributes
2109 setupDefaultInputs();
2110
2111 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2112 {
2113 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
2114 DE_NULL, // const void* pNext;
2115 (VkPipelineVertexInputStateCreateFlags)0,
2116 (deUint32)m_vertexBindingDescription.size(), // deUint32 bindingCount;
2117 &m_vertexBindingDescription[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
2118 (deUint32)m_vertexAttributeDescription.size(), // deUint32 attributeCount;
2119 &m_vertexAttributeDescription[0], // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
2120 };
2121
2122 const std::vector<VkViewport> viewports (1, makeViewport(m_renderSize));
2123 const std::vector<VkRect2D> scissors (1, makeRect2D(m_renderSize));
2124
2125 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2126 {
2127 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
2128 DE_NULL, // const void* pNext;
2129 0u, // VkPipelineMultisampleStateCreateFlags flags;
2130 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
2131 VK_FALSE, // VkBool32 sampleShadingEnable;
2132 0.0f, // float minSampleShading;
2133 DE_NULL, // const VkSampleMask* pSampleMask;
2134 VK_FALSE, // VkBool32 alphaToCoverageEnable;
2135 VK_FALSE // VkBool32 alphaToOneEnable;
2136 };
2137
2138 graphicsPipeline = makeGraphicsPipeline(vk, // const DeviceInterface& vk
2139 vkDevice, // const VkDevice device
2140 *pipelineLayout, // const VkPipelineLayout pipelineLayout
2141 *vertexShaderModule, // const VkShaderModule vertexShaderModule
2142 DE_NULL, // const VkShaderModule tessellationControlShaderModule
2143 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
2144 DE_NULL, // const VkShaderModule geometryShaderModule
2145 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
2146 *renderPass, // const VkRenderPass renderPass
2147 viewports, // const std::vector<VkViewport>& viewports
2148 scissors, // const std::vector<VkRect2D>& scissors
2149 topology, // const VkPrimitiveTopology topology
2150 0u, // const deUint32 subpass
2151 0u, // const deUint32 patchControlPoints
2152 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
2153 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
2154 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
2155 }
2156
2157 // Create vertex indices buffer
2158 if (numIndices != 0)
2159 {
2160 const VkDeviceSize indexBufferSize = numIndices * sizeof(deUint16);
2161 const VkBufferCreateInfo indexBufferParams =
2162 {
2163 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2164 DE_NULL, // const void* pNext;
2165 0u, // VkBufferCreateFlags flags;
2166 indexBufferSize, // VkDeviceSize size;
2167 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage;
2168 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2169 1u, // deUint32 queueFamilyCount;
2170 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
2171 };
2172
2173 indexBuffer = createBuffer(vk, vkDevice, &indexBufferParams);
2174 indexBufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *indexBuffer), MemoryRequirement::HostVisible);
2175
2176 VK_CHECK(vk.bindBufferMemory(vkDevice, *indexBuffer, indexBufferAlloc->getMemory(), indexBufferAlloc->getOffset()));
2177
2178 // Load vertice indices into buffer
2179 deMemcpy(indexBufferAlloc->getHostPtr(), indices, (size_t)indexBufferSize);
2180 flushAlloc(vk, vkDevice, *indexBufferAlloc);
2181 }
2182
2183 // Create command pool
2184 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
2185
2186 // Create command buffer
2187 {
2188 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2189
2190 beginCommandBuffer(vk, *cmdBuffer);
2191
2192 {
2193 const VkImageMemoryBarrier imageBarrier =
2194 {
2195 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2196 DE_NULL, // const void* pNext;
2197 0u, // VkAccessFlags srcAccessMask;
2198 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
2199 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
2200 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
2201 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2202 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2203 *colorImage, // VkImage image;
2204 { // VkImageSubresourceRange subresourceRange;
2205 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2206 0u, // deUint32 baseMipLevel;
2207 1u, // deUint32 mipLevels;
2208 0u, // deUint32 baseArrayLayer;
2209 1u, // deUint32 arraySize;
2210 }
2211 };
2212
2213 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, DE_NULL, 1, &imageBarrier);
2214
2215 if (isMultiSampling()) {
2216 // add multisample barrier
2217 const VkImageMemoryBarrier multiSampleImageBarrier =
2218 {
2219 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2220 DE_NULL, // const void* pNext;
2221 0u, // VkAccessFlags srcAccessMask;
2222 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
2223 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
2224 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
2225 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2226 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2227 *resolvedImage, // VkImage image;
2228 { // VkImageSubresourceRange subresourceRange;
2229 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2230 0u, // deUint32 baseMipLevel;
2231 1u, // deUint32 mipLevels;
2232 0u, // deUint32 baseArrayLayer;
2233 1u, // deUint32 arraySize;
2234 }
2235 };
2236
2237 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, DE_NULL, 1, &multiSampleImageBarrier);
2238 }
2239 }
2240
2241 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), m_clearColor);
2242
2243 updatePushConstants(*cmdBuffer, *pipelineLayout);
2244 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2245 if (!m_uniformInfos.empty())
2246 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &*descriptorSet, 0u, DE_NULL);
2247
2248 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
2249 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
2250
2251 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
2252 for (size_t i = 0; i < numberOfVertexAttributes; i++)
2253 {
2254 buffers[i] = m_vertexBuffers[i].get()->get();
2255 }
2256
2257 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
2258 if (numIndices != 0)
2259 {
2260 vk.cmdBindIndexBuffer(*cmdBuffer, *indexBuffer, 0, VK_INDEX_TYPE_UINT16);
2261 vk.cmdDrawIndexed(*cmdBuffer, numIndices, 1, 0, 0, 0);
2262 }
2263 else
2264 vk.cmdDraw(*cmdBuffer, numVertices, 1, 0, 1);
2265
2266 endRenderPass(vk, *cmdBuffer);
2267 endCommandBuffer(vk, *cmdBuffer);
2268 }
2269
2270 // Execute Draw
2271 submitCommandsAndWait(vk, vkDevice, queue, cmdBuffer.get());
2272
2273 // Read back the result
2274 {
2275 const tcu::TextureFormat resultFormat = mapVkFormat(m_colorFormat);
2276 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(resultFormat.getPixelSize() * m_renderSize.x() * m_renderSize.y());
2277 const VkBufferCreateInfo readImageBufferParams =
2278 {
2279 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2280 DE_NULL, // const void* pNext;
2281 0u, // VkBufferCreateFlags flags;
2282 imageSizeBytes, // VkDeviceSize size;
2283 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
2284 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2285 1u, // deUint32 queueFamilyCount;
2286 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2287 };
2288 const Unique<VkBuffer> readImageBuffer (createBuffer(vk, vkDevice, &readImageBufferParams));
2289 const de::UniquePtr<Allocation> readImageBufferMemory (m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
2290
2291 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
2292
2293 // Copy image to buffer
2294 const Move<VkCommandBuffer> resultCmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2295
2296 beginCommandBuffer(vk, *resultCmdBuffer);
2297
2298 copyImageToBuffer(vk, *resultCmdBuffer, isMultiSampling() ? *resolvedImage : *colorImage, *readImageBuffer, tcu::IVec2(m_renderSize.x(), m_renderSize.y()));
2299
2300 endCommandBuffer(vk, *resultCmdBuffer);
2301
2302 submitCommandsAndWait(vk, vkDevice, queue, resultCmdBuffer.get());
2303
2304 invalidateAlloc(vk, vkDevice, *readImageBufferMemory);
2305
2306 const tcu::ConstPixelBufferAccess resultAccess (resultFormat, m_renderSize.x(), m_renderSize.y(), 1, readImageBufferMemory->getHostPtr());
2307
2308 m_resultImage.setStorage(resultFormat, m_renderSize.x(), m_renderSize.y());
2309 tcu::copy(m_resultImage.getAccess(), resultAccess);
2310 }
2311 }
2312
computeVertexReference(tcu::Surface & result,const QuadGrid & quadGrid)2313 void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid)
2314 {
2315 DE_ASSERT(m_evaluator);
2316
2317 // Buffer info.
2318 const int width = result.getWidth();
2319 const int height = result.getHeight();
2320 const int gridSize = quadGrid.getGridSize();
2321 const int stride = gridSize + 1;
2322 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
2323 ShaderEvalContext evalCtx (quadGrid);
2324
2325 // Evaluate color for each vertex.
2326 std::vector<tcu::Vec4> colors ((gridSize + 1) * (gridSize + 1));
2327 for (int y = 0; y < gridSize+1; y++)
2328 for (int x = 0; x < gridSize+1; x++)
2329 {
2330 const float sx = (float)x / (float)gridSize;
2331 const float sy = (float)y / (float)gridSize;
2332 const int vtxNdx = ((y * (gridSize+1)) + x);
2333
2334 evalCtx.reset(sx, sy);
2335 m_evaluator->evaluate(evalCtx);
2336 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader.
2337 tcu::Vec4 color = evalCtx.color;
2338
2339 if (!hasAlpha)
2340 color.w() = 1.0f;
2341
2342 colors[vtxNdx] = color;
2343 }
2344
2345 // Render quads.
2346 for (int y = 0; y < gridSize; y++)
2347 for (int x = 0; x < gridSize; x++)
2348 {
2349 const float x0 = (float)x / (float)gridSize;
2350 const float x1 = (float)(x + 1) / (float)gridSize;
2351 const float y0 = (float)y / (float)gridSize;
2352 const float y1 = (float)(y + 1) / (float)gridSize;
2353
2354 const float sx0 = x0 * (float)width;
2355 const float sx1 = x1 * (float)width;
2356 const float sy0 = y0 * (float)height;
2357 const float sy1 = y1 * (float)height;
2358 const float oosx = 1.0f / (sx1 - sx0);
2359 const float oosy = 1.0f / (sy1 - sy0);
2360
2361 const int ix0 = deCeilFloatToInt32(sx0 - 0.5f);
2362 const int ix1 = deCeilFloatToInt32(sx1 - 0.5f);
2363 const int iy0 = deCeilFloatToInt32(sy0 - 0.5f);
2364 const int iy1 = deCeilFloatToInt32(sy1 - 0.5f);
2365
2366 const int v00 = (y * stride) + x;
2367 const int v01 = (y * stride) + x + 1;
2368 const int v10 = ((y + 1) * stride) + x;
2369 const int v11 = ((y + 1) * stride) + x + 1;
2370 const tcu::Vec4 c00 = colors[v00];
2371 const tcu::Vec4 c01 = colors[v01];
2372 const tcu::Vec4 c10 = colors[v10];
2373 const tcu::Vec4 c11 = colors[v11];
2374
2375 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1);
2376
2377 for (int iy = iy0; iy < iy1; iy++)
2378 for (int ix = ix0; ix < ix1; ix++)
2379 {
2380 DE_ASSERT(deInBounds32(ix, 0, width));
2381 DE_ASSERT(deInBounds32(iy, 0, height));
2382
2383 const float sfx = (float)ix + 0.5f;
2384 const float sfy = (float)iy + 0.5f;
2385 const float fx1 = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f);
2386 const float fy1 = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f);
2387
2388 // Triangle quad interpolation.
2389 const bool tri = fx1 + fy1 <= 1.0f;
2390 const float tx = tri ? fx1 : (1.0f-fx1);
2391 const float ty = tri ? fy1 : (1.0f-fy1);
2392 const tcu::Vec4& t0 = tri ? c00 : c11;
2393 const tcu::Vec4& t1 = tri ? c01 : c10;
2394 const tcu::Vec4& t2 = tri ? c10 : c01;
2395 const tcu::Vec4 color = t0 + (t1-t0)*tx + (t2-t0)*ty;
2396
2397 result.setPixel(ix, iy, tcu::RGBA(color));
2398 }
2399 }
2400 }
2401
computeFragmentReference(tcu::Surface & result,const QuadGrid & quadGrid)2402 void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid)
2403 {
2404 DE_ASSERT(m_evaluator);
2405
2406 // Buffer info.
2407 const int width = result.getWidth();
2408 const int height = result.getHeight();
2409 const bool hasAlpha = true; // \todo [2015-09-07 elecro] add correct alpha check
2410 ShaderEvalContext evalCtx (quadGrid);
2411
2412 // Render.
2413 for (int y = 0; y < height; y++)
2414 for (int x = 0; x < width; x++)
2415 {
2416 const float sx = ((float)x + 0.5f) / (float)width;
2417 const float sy = ((float)y + 0.5f) / (float)height;
2418
2419 evalCtx.reset(sx, sy);
2420 m_evaluator->evaluate(evalCtx);
2421 // Select either clear color or computed color based on discarded bit.
2422 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color;
2423
2424 if (!hasAlpha)
2425 color.w() = 1.0f;
2426
2427 result.setPixel(x, y, tcu::RGBA(color));
2428 }
2429 }
2430
compareImages(const tcu::Surface & resImage,const tcu::Surface & refImage,float errorThreshold)2431 bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold)
2432 {
2433 return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_EVERYTHING);
2434 }
2435
2436 } // sr
2437 } // vkt
2438