1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Reference renderer.
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktPipelineReferenceRenderer.hpp"
26 #include "vktPipelineClearUtil.hpp"
27 #include "rrShadingContext.hpp"
28 #include "rrVertexAttrib.hpp"
29
30 namespace vkt
31 {
32 namespace pipeline
33 {
34
35 using namespace vk;
36
mapVkBlendFactor(VkBlendFactor blend)37 rr::BlendFunc mapVkBlendFactor(VkBlendFactor blend)
38 {
39 switch (blend)
40 {
41 case VK_BLEND_FACTOR_ZERO:
42 return rr::BLENDFUNC_ZERO;
43 case VK_BLEND_FACTOR_ONE:
44 return rr::BLENDFUNC_ONE;
45 case VK_BLEND_FACTOR_SRC_COLOR:
46 return rr::BLENDFUNC_SRC_COLOR;
47 case VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR:
48 return rr::BLENDFUNC_ONE_MINUS_SRC_COLOR;
49 case VK_BLEND_FACTOR_DST_COLOR:
50 return rr::BLENDFUNC_DST_COLOR;
51 case VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR:
52 return rr::BLENDFUNC_ONE_MINUS_DST_COLOR;
53 case VK_BLEND_FACTOR_SRC_ALPHA:
54 return rr::BLENDFUNC_SRC_ALPHA;
55 case VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA:
56 return rr::BLENDFUNC_ONE_MINUS_SRC_ALPHA;
57 case VK_BLEND_FACTOR_DST_ALPHA:
58 return rr::BLENDFUNC_DST_ALPHA;
59 case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA:
60 return rr::BLENDFUNC_ONE_MINUS_DST_ALPHA;
61 case VK_BLEND_FACTOR_CONSTANT_COLOR:
62 return rr::BLENDFUNC_CONSTANT_COLOR;
63 case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR:
64 return rr::BLENDFUNC_ONE_MINUS_CONSTANT_COLOR;
65 case VK_BLEND_FACTOR_CONSTANT_ALPHA:
66 return rr::BLENDFUNC_CONSTANT_ALPHA;
67 case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA:
68 return rr::BLENDFUNC_ONE_MINUS_CONSTANT_ALPHA;
69 case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE:
70 return rr::BLENDFUNC_SRC_ALPHA_SATURATE;
71 case VK_BLEND_FACTOR_SRC1_COLOR:
72 return rr::BLENDFUNC_SRC1_COLOR;
73 case VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR:
74 return rr::BLENDFUNC_ONE_MINUS_SRC1_COLOR;
75 case VK_BLEND_FACTOR_SRC1_ALPHA:
76 return rr::BLENDFUNC_SRC1_ALPHA;
77 case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA:
78 return rr::BLENDFUNC_ONE_MINUS_SRC1_ALPHA;
79 default:
80 DE_ASSERT(false);
81 }
82 return rr::BLENDFUNC_LAST;
83 }
84
mapVkBlendOp(VkBlendOp blendOp)85 rr::BlendEquation mapVkBlendOp(VkBlendOp blendOp)
86 {
87 switch (blendOp)
88 {
89 case VK_BLEND_OP_ADD:
90 return rr::BLENDEQUATION_ADD;
91 case VK_BLEND_OP_SUBTRACT:
92 return rr::BLENDEQUATION_SUBTRACT;
93 case VK_BLEND_OP_REVERSE_SUBTRACT:
94 return rr::BLENDEQUATION_REVERSE_SUBTRACT;
95 case VK_BLEND_OP_MIN:
96 return rr::BLENDEQUATION_MIN;
97 case VK_BLEND_OP_MAX:
98 return rr::BLENDEQUATION_MAX;
99 default:
100 DE_ASSERT(false);
101 }
102 return rr::BLENDEQUATION_LAST;
103 }
104
mapVkColorComponentFlags(VkColorComponentFlags flags)105 tcu::BVec4 mapVkColorComponentFlags(VkColorComponentFlags flags)
106 {
107 return tcu::BVec4((flags & VK_COLOR_COMPONENT_R_BIT) != 0, (flags & VK_COLOR_COMPONENT_G_BIT) != 0,
108 (flags & VK_COLOR_COMPONENT_B_BIT) != 0, (flags & VK_COLOR_COMPONENT_A_BIT) != 0);
109 }
110
mapVkCompareOp(VkCompareOp compareFunc)111 rr::TestFunc mapVkCompareOp(VkCompareOp compareFunc)
112 {
113 switch (compareFunc)
114 {
115 case VK_COMPARE_OP_NEVER:
116 return rr::TESTFUNC_NEVER;
117 case VK_COMPARE_OP_LESS:
118 return rr::TESTFUNC_LESS;
119 case VK_COMPARE_OP_EQUAL:
120 return rr::TESTFUNC_EQUAL;
121 case VK_COMPARE_OP_LESS_OR_EQUAL:
122 return rr::TESTFUNC_LEQUAL;
123 case VK_COMPARE_OP_GREATER:
124 return rr::TESTFUNC_GREATER;
125 case VK_COMPARE_OP_NOT_EQUAL:
126 return rr::TESTFUNC_NOTEQUAL;
127 case VK_COMPARE_OP_GREATER_OR_EQUAL:
128 return rr::TESTFUNC_GEQUAL;
129 case VK_COMPARE_OP_ALWAYS:
130 return rr::TESTFUNC_ALWAYS;
131 default:
132 DE_ASSERT(false);
133 }
134 return rr::TESTFUNC_LAST;
135 }
136
mapVkPrimitiveTopology(VkPrimitiveTopology primitiveTopology)137 rr::PrimitiveType mapVkPrimitiveTopology(VkPrimitiveTopology primitiveTopology)
138 {
139 switch (primitiveTopology)
140 {
141 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
142 return rr::PRIMITIVETYPE_POINTS;
143 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
144 return rr::PRIMITIVETYPE_LINES;
145 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
146 return rr::PRIMITIVETYPE_LINE_STRIP;
147 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
148 return rr::PRIMITIVETYPE_TRIANGLES;
149 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
150 return rr::PRIMITIVETYPE_TRIANGLE_FAN;
151 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
152 return rr::PRIMITIVETYPE_TRIANGLE_STRIP;
153 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
154 return rr::PRIMITIVETYPE_LINES_ADJACENCY;
155 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
156 return rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY;
157 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
158 return rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY;
159 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
160 return rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY;
161 default:
162 DE_ASSERT(false);
163 }
164 return rr::PRIMITIVETYPE_LAST;
165 }
166
mapVkStencilOp(vk::VkStencilOp stencilOp)167 rr::StencilOp mapVkStencilOp(vk::VkStencilOp stencilOp)
168 {
169 switch (stencilOp)
170 {
171 case VK_STENCIL_OP_KEEP:
172 return rr::STENCILOP_KEEP;
173 case VK_STENCIL_OP_ZERO:
174 return rr::STENCILOP_ZERO;
175 case VK_STENCIL_OP_REPLACE:
176 return rr::STENCILOP_REPLACE;
177 case VK_STENCIL_OP_INCREMENT_AND_CLAMP:
178 return rr::STENCILOP_INCR;
179 case VK_STENCIL_OP_DECREMENT_AND_CLAMP:
180 return rr::STENCILOP_DECR;
181 case VK_STENCIL_OP_INVERT:
182 return rr::STENCILOP_INVERT;
183 case VK_STENCIL_OP_INCREMENT_AND_WRAP:
184 return rr::STENCILOP_INCR_WRAP;
185 case VK_STENCIL_OP_DECREMENT_AND_WRAP:
186 return rr::STENCILOP_DECR_WRAP;
187 default:
188 DE_ASSERT(false);
189 }
190 return rr::STENCILOP_LAST;
191 }
192
swizzle(const tcu::Vec4 & color,const tcu::UVec4 & swizzle)193 tcu::Vec4 swizzle(const tcu::Vec4 &color, const tcu::UVec4 &swizzle)
194 {
195 const float channelValues[] = {0.0f, 1.0f, color.x(), color.y(), color.z(), color.w()};
196
197 return tcu::Vec4(channelValues[swizzle.x()], channelValues[swizzle.y()], channelValues[swizzle.z()],
198 channelValues[swizzle.w()]);
199 }
200
ReferenceRenderer(int surfaceWidth,int surfaceHeight,int numSamples,const tcu::TextureFormat & colorFormat,const tcu::TextureFormat & depthStencilFormat,const rr::Program * const program)201 ReferenceRenderer::ReferenceRenderer(int surfaceWidth, int surfaceHeight, int numSamples,
202 const tcu::TextureFormat &colorFormat,
203 const tcu::TextureFormat &depthStencilFormat, const rr::Program *const program)
204 : m_surfaceWidth(surfaceWidth)
205 , m_surfaceHeight(surfaceHeight)
206 , m_numSamples(numSamples)
207 , m_colorFormat(colorFormat)
208 , m_depthStencilFormat(depthStencilFormat)
209 , m_program(program)
210 {
211 const tcu::TextureChannelClass formatClass = tcu::getTextureChannelClass(colorFormat.type);
212 const bool hasDepthStencil = (m_depthStencilFormat.order != tcu::TextureFormat::CHANNELORDER_LAST);
213 const bool hasDepthBufferOnly = (m_depthStencilFormat.order == tcu::TextureFormat::D);
214 const bool hasStencilBufferOnly = (m_depthStencilFormat.order == tcu::TextureFormat::S);
215 const int actualSamples = (formatClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
216 formatClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) ?
217 1 :
218 m_numSamples;
219
220 m_colorBuffer.setStorage(m_colorFormat, actualSamples, m_surfaceWidth, m_surfaceHeight);
221 m_resolveColorBuffer.setStorage(m_colorFormat, m_surfaceWidth, m_surfaceHeight);
222
223 if (formatClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
224 {
225 tcu::clear(m_colorBuffer.getAccess(), defaultClearColorInt(m_colorFormat));
226 tcu::clear(m_resolveColorBuffer.getAccess(), defaultClearColorInt(m_colorFormat));
227 }
228 else if (formatClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
229 {
230 tcu::clear(m_colorBuffer.getAccess(), defaultClearColorUint(m_colorFormat));
231 tcu::clear(m_resolveColorBuffer.getAccess(), defaultClearColorUint(m_colorFormat));
232 }
233 else
234 {
235 tcu::Vec4 clearColor = defaultClearColor(m_colorFormat);
236
237 if (isSRGB(m_colorFormat))
238 clearColor = tcu::linearToSRGB(clearColor);
239
240 tcu::clear(m_colorBuffer.getAccess(), clearColor);
241 tcu::clear(m_resolveColorBuffer.getAccess(), clearColor);
242 }
243
244 if (hasDepthStencil)
245 {
246 if (hasDepthBufferOnly)
247 {
248 m_depthStencilBuffer.setStorage(m_depthStencilFormat, actualSamples, surfaceWidth, surfaceHeight);
249 tcu::clearDepth(m_depthStencilBuffer.getAccess(), defaultClearDepth());
250
251 m_resolveDepthStencilBuffer.setStorage(m_depthStencilFormat, surfaceWidth, surfaceHeight);
252 tcu::clearDepth(m_resolveDepthStencilBuffer.getAccess(), defaultClearDepth());
253
254 m_renderTarget = new rr::RenderTarget(
255 rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()),
256 rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()));
257 }
258 else if (hasStencilBufferOnly)
259 {
260 m_depthStencilBuffer.setStorage(m_depthStencilFormat, actualSamples, surfaceWidth, surfaceHeight);
261 tcu::clearStencil(m_depthStencilBuffer.getAccess(), defaultClearStencil());
262
263 m_resolveDepthStencilBuffer.setStorage(m_depthStencilFormat, surfaceWidth, surfaceHeight);
264 tcu::clearStencil(m_resolveDepthStencilBuffer.getAccess(), defaultClearStencil());
265
266 m_renderTarget = new rr::RenderTarget(
267 rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()),
268 rr::MultisamplePixelBufferAccess(),
269 rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()));
270 }
271 else
272 {
273 m_depthStencilBuffer.setStorage(m_depthStencilFormat, actualSamples, surfaceWidth, surfaceHeight);
274
275 tcu::clearDepth(m_depthStencilBuffer.getAccess(), defaultClearDepth());
276 tcu::clearStencil(m_depthStencilBuffer.getAccess(), defaultClearStencil());
277
278 m_resolveDepthStencilBuffer.setStorage(m_depthStencilFormat, surfaceWidth, surfaceHeight);
279 tcu::clearDepth(m_resolveDepthStencilBuffer.getAccess(), defaultClearDepth());
280
281 m_renderTarget = new rr::RenderTarget(
282 rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()),
283 rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()),
284 rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()));
285 }
286 }
287 else
288 {
289 m_renderTarget =
290 new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()));
291 }
292 }
293
~ReferenceRenderer(void)294 ReferenceRenderer::~ReferenceRenderer(void)
295 {
296 delete m_renderTarget;
297 }
298
colorClear(const tcu::Vec4 & color)299 void ReferenceRenderer::colorClear(const tcu::Vec4 &color)
300 {
301 tcu::clear(m_colorBuffer.getAccess(), color);
302 tcu::clear(m_resolveColorBuffer.getAccess(), color);
303 }
304
draw(const rr::RenderState & renderState,const rr::PrimitiveType primitive,const std::vector<Vertex4RGBA> & vertexBuffer)305 void ReferenceRenderer::draw(const rr::RenderState &renderState, const rr::PrimitiveType primitive,
306 const std::vector<Vertex4RGBA> &vertexBuffer)
307 {
308 const rr::PrimitiveList primitives(primitive, (int)vertexBuffer.size(), 0);
309
310 std::vector<tcu::Vec4> positions;
311 std::vector<tcu::Vec4> colors;
312
313 for (size_t vertexNdx = 0; vertexNdx < vertexBuffer.size(); vertexNdx++)
314 {
315 const Vertex4RGBA &v = vertexBuffer[vertexNdx];
316 positions.push_back(v.position);
317 colors.push_back(v.color);
318 }
319
320 rr::VertexAttrib vertexAttribs[2];
321
322 // Position attribute
323 vertexAttribs[0].type = rr::VERTEXATTRIBTYPE_FLOAT;
324 vertexAttribs[0].size = 4;
325 vertexAttribs[0].pointer = positions.data();
326 // UV attribute
327 vertexAttribs[1].type = rr::VERTEXATTRIBTYPE_FLOAT;
328 vertexAttribs[1].size = 4;
329 vertexAttribs[1].pointer = colors.data();
330
331 rr::DrawCommand drawQuadCommand(renderState, *m_renderTarget, *m_program, 2, vertexAttribs, primitives);
332
333 m_renderer.draw(drawQuadCommand);
334 }
draw(const rr::RenderState & renderState,const rr::PrimitiveType primitive,const std::vector<Vertex4RGBARGBA> & vertexBuffer)335 void ReferenceRenderer::draw(const rr::RenderState &renderState, const rr::PrimitiveType primitive,
336 const std::vector<Vertex4RGBARGBA> &vertexBuffer)
337 {
338 const rr::PrimitiveList primitives(primitive, (int)vertexBuffer.size(), 0);
339
340 std::vector<tcu::Vec4> positions;
341 std::vector<tcu::Vec4> color0s;
342 std::vector<tcu::Vec4> color1s;
343
344 for (size_t vertexNdx = 0; vertexNdx < vertexBuffer.size(); vertexNdx++)
345 {
346 const Vertex4RGBARGBA &v = vertexBuffer[vertexNdx];
347 positions.push_back(v.position);
348 color0s.push_back(v.color0);
349 color1s.push_back(v.color1);
350 }
351
352 rr::VertexAttrib vertexAttribs[3];
353
354 // Position attribute
355 vertexAttribs[0].type = rr::VERTEXATTRIBTYPE_FLOAT;
356 vertexAttribs[0].size = 4;
357 vertexAttribs[0].pointer = positions.data();
358 // Color0 attribute
359 vertexAttribs[1].type = rr::VERTEXATTRIBTYPE_FLOAT;
360 vertexAttribs[1].size = 4;
361 vertexAttribs[1].pointer = color0s.data();
362 // Color1 attribute
363 vertexAttribs[2].type = rr::VERTEXATTRIBTYPE_FLOAT;
364 vertexAttribs[2].size = 4;
365 vertexAttribs[2].pointer = color1s.data();
366
367 rr::DrawCommand drawQuadCommand(renderState, *m_renderTarget, *m_program, 3, vertexAttribs, primitives);
368
369 m_renderer.draw(drawQuadCommand);
370 }
371
draw(const rr::RenderState & renderState,const rr::PrimitiveType primitive,const std::vector<Vertex4Tex4> & vertexBuffer)372 void ReferenceRenderer::draw(const rr::RenderState &renderState, const rr::PrimitiveType primitive,
373 const std::vector<Vertex4Tex4> &vertexBuffer)
374 {
375 const rr::PrimitiveList primitives(primitive, (int)vertexBuffer.size(), 0);
376
377 std::vector<tcu::Vec4> positions;
378 std::vector<tcu::Vec4> texCoords;
379
380 for (size_t vertexNdx = 0; vertexNdx < vertexBuffer.size(); vertexNdx++)
381 {
382 const Vertex4Tex4 &v = vertexBuffer[vertexNdx];
383 positions.push_back(v.position);
384 texCoords.push_back(v.texCoord);
385 }
386
387 rr::VertexAttrib vertexAttribs[2];
388
389 // Position attribute
390 vertexAttribs[0].type = rr::VERTEXATTRIBTYPE_FLOAT;
391 vertexAttribs[0].size = 4;
392 vertexAttribs[0].pointer = positions.data();
393 // UV attribute
394 vertexAttribs[1].type = rr::VERTEXATTRIBTYPE_FLOAT;
395 vertexAttribs[1].size = 4;
396 vertexAttribs[1].pointer = texCoords.data();
397
398 rr::DrawCommand drawQuadCommand(renderState, *m_renderTarget, *m_program, 2, vertexAttribs, primitives);
399
400 m_renderer.draw(drawQuadCommand);
401 }
402
getAccess(void)403 tcu::PixelBufferAccess ReferenceRenderer::getAccess(void)
404 {
405 rr::MultisampleConstPixelBufferAccess multiSampleAccess =
406 rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess());
407 rr::resolveMultisampleColorBuffer(m_resolveColorBuffer.getAccess(), multiSampleAccess);
408
409 return m_resolveColorBuffer.getAccess();
410 }
411
getDepthStencilAccess(void)412 tcu::PixelBufferAccess ReferenceRenderer::getDepthStencilAccess(void)
413 {
414 rr::MultisampleConstPixelBufferAccess multiSampleAccess =
415 rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess());
416 rr::resolveMultisampleColorBuffer(m_resolveDepthStencilBuffer.getAccess(), multiSampleAccess);
417
418 return m_resolveDepthStencilBuffer.getAccess();
419 }
420
getViewportState(void) const421 const rr::ViewportState ReferenceRenderer::getViewportState(void) const
422 {
423 return rr::ViewportState(rr::WindowRectangle(0, 0, m_surfaceWidth, m_surfaceHeight));
424 }
425
426 } // namespace pipeline
427 } // namespace vkt
428