DO NOT MERGE Refresh GLES 3.1 must-pass XML am: d8e85a9be9 -s ours am: ba3d0b4eb3...
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineReferenceRenderer.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Imagination Technologies Ltd.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and/or associated documentation files (the
10  * "Materials"), to deal in the Materials without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sublicense, and/or sell copies of the Materials, and to
13  * permit persons to whom the Materials are furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice(s) and this permission notice shall be included
17  * in all copies or substantial portions of the Materials.
18  *
19  * The Materials are Confidential Information as defined by the
20  * Khronos Membership Agreement until designated non-confidential by Khronos,
21  * at which point this condition clause shall be removed.
22  *
23  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
30  *
31  *//*!
32  * \file
33  * \brief Reference renderer.
34  *//*--------------------------------------------------------------------*/
35
36 #include "vktPipelineReferenceRenderer.hpp"
37 #include "vktPipelineClearUtil.hpp"
38 #include "rrShadingContext.hpp"
39 #include "rrVertexAttrib.hpp"
40
41 namespace vkt
42 {
43 namespace pipeline
44 {
45
46 using namespace vk;
47
48 rr::BlendFunc mapVkBlendFactor (VkBlendFactor blend)
49 {
50         switch (blend)
51         {
52                 case VK_BLEND_FACTOR_ZERO:                                              return rr::BLENDFUNC_ZERO;
53                 case VK_BLEND_FACTOR_ONE:                                               return rr::BLENDFUNC_ONE;
54                 case VK_BLEND_FACTOR_SRC_COLOR:                                 return rr::BLENDFUNC_SRC_COLOR;
55                 case VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR:               return rr::BLENDFUNC_ONE_MINUS_SRC_COLOR;
56                 case VK_BLEND_FACTOR_DST_COLOR:                                 return rr::BLENDFUNC_DST_COLOR;
57                 case VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR:               return rr::BLENDFUNC_ONE_MINUS_DST_COLOR;
58                 case VK_BLEND_FACTOR_SRC_ALPHA:                                 return rr::BLENDFUNC_SRC_ALPHA;
59                 case VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA:               return rr::BLENDFUNC_ONE_MINUS_SRC_ALPHA;
60                 case VK_BLEND_FACTOR_DST_ALPHA:                                 return rr::BLENDFUNC_DST_ALPHA;
61                 case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA:               return rr::BLENDFUNC_ONE_MINUS_DST_ALPHA;
62                 case VK_BLEND_FACTOR_CONSTANT_COLOR:                    return rr::BLENDFUNC_CONSTANT_COLOR;
63                 case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR:  return rr::BLENDFUNC_ONE_MINUS_CONSTANT_COLOR;
64                 case VK_BLEND_FACTOR_CONSTANT_ALPHA:                    return rr::BLENDFUNC_CONSTANT_ALPHA;
65                 case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA:  return rr::BLENDFUNC_ONE_MINUS_CONSTANT_ALPHA;
66                 case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE:                return rr::BLENDFUNC_SRC_ALPHA_SATURATE;
67                 case VK_BLEND_FACTOR_SRC1_COLOR:                                return rr::BLENDFUNC_SRC1_COLOR;
68                 case VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR:              return rr::BLENDFUNC_ONE_MINUS_SRC1_COLOR;
69                 case VK_BLEND_FACTOR_SRC1_ALPHA:                                return rr::BLENDFUNC_SRC1_ALPHA;
70                 case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA:              return rr::BLENDFUNC_ONE_MINUS_SRC1_ALPHA;
71                 default:
72                         DE_ASSERT(false);
73         }
74         return rr::BLENDFUNC_LAST;
75 }
76
77 rr::BlendEquation mapVkBlendOp (VkBlendOp blendOp)
78 {
79         switch (blendOp)
80         {
81                 case VK_BLEND_OP_ADD:                                   return rr::BLENDEQUATION_ADD;
82                 case VK_BLEND_OP_SUBTRACT:                              return rr::BLENDEQUATION_SUBTRACT;
83                 case VK_BLEND_OP_REVERSE_SUBTRACT:              return rr::BLENDEQUATION_REVERSE_SUBTRACT;
84                 case VK_BLEND_OP_MIN:                                   return rr::BLENDEQUATION_MIN;
85                 case VK_BLEND_OP_MAX:                                   return rr::BLENDEQUATION_MAX;
86                 default:
87                         DE_ASSERT(false);
88         }
89         return rr::BLENDEQUATION_LAST;
90 }
91
92 tcu::BVec4 mapVkColorComponentFlags (VkColorComponentFlags flags)
93 {
94         return tcu::BVec4((flags & VK_COLOR_COMPONENT_R_BIT) != 0,
95                                           (flags & VK_COLOR_COMPONENT_G_BIT) != 0,
96                                           (flags & VK_COLOR_COMPONENT_B_BIT) != 0,
97                                           (flags & VK_COLOR_COMPONENT_A_BIT) != 0);
98 }
99
100 rr::TestFunc mapVkCompareOp (VkCompareOp compareFunc)
101 {
102         switch (compareFunc)
103         {
104                 case VK_COMPARE_OP_NEVER:                               return rr::TESTFUNC_NEVER;
105                 case VK_COMPARE_OP_LESS:                                return rr::TESTFUNC_LESS;
106                 case VK_COMPARE_OP_EQUAL:                               return rr::TESTFUNC_EQUAL;
107                 case VK_COMPARE_OP_LESS_OR_EQUAL:               return rr::TESTFUNC_LEQUAL;
108                 case VK_COMPARE_OP_GREATER:                             return rr::TESTFUNC_GREATER;
109                 case VK_COMPARE_OP_NOT_EQUAL:                   return rr::TESTFUNC_NOTEQUAL;
110                 case VK_COMPARE_OP_GREATER_OR_EQUAL:    return rr::TESTFUNC_GEQUAL;
111                 case VK_COMPARE_OP_ALWAYS:                              return rr::TESTFUNC_ALWAYS;
112                 default:
113                         DE_ASSERT(false);
114         }
115         return rr::TESTFUNC_LAST;
116 }
117
118 rr::PrimitiveType mapVkPrimitiveTopology (VkPrimitiveTopology primitiveTopology)
119 {
120         switch (primitiveTopology)
121         {
122                 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:                                          return rr::PRIMITIVETYPE_POINTS;
123                 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:                                           return rr::PRIMITIVETYPE_LINES;
124                 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:                                          return rr::PRIMITIVETYPE_LINE_STRIP;
125                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:                                       return rr::PRIMITIVETYPE_TRIANGLES;
126                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:                                        return rr::PRIMITIVETYPE_TRIANGLE_FAN;
127                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:                                      return rr::PRIMITIVETYPE_TRIANGLE_STRIP;
128                 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:            return rr::PRIMITIVETYPE_LINES_ADJACENCY;
129                 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:           return rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY;
130                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:        return rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY;
131                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:       return rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY;
132                 default:
133                         DE_ASSERT(false);
134         }
135         return rr::PRIMITIVETYPE_LAST;
136 }
137
138 rr::StencilOp mapVkStencilOp (vk::VkStencilOp stencilOp)
139 {
140         switch (stencilOp)
141         {
142                 case VK_STENCIL_OP_KEEP:                                        return rr::STENCILOP_KEEP;
143                 case VK_STENCIL_OP_ZERO:                                        return rr::STENCILOP_ZERO;
144                 case VK_STENCIL_OP_REPLACE:                                     return rr::STENCILOP_REPLACE;
145                 case VK_STENCIL_OP_INCREMENT_AND_CLAMP:         return rr::STENCILOP_INCR;
146                 case VK_STENCIL_OP_DECREMENT_AND_CLAMP:         return rr::STENCILOP_DECR;
147                 case VK_STENCIL_OP_INVERT:                                      return rr::STENCILOP_INVERT;
148                 case VK_STENCIL_OP_INCREMENT_AND_WRAP:          return rr::STENCILOP_INCR_WRAP;
149                 case VK_STENCIL_OP_DECREMENT_AND_WRAP:          return rr::STENCILOP_DECR_WRAP;
150                 default:
151                         DE_ASSERT(false);
152         }
153         return rr::STENCILOP_LAST;
154 }
155
156 tcu::Vec4 swizzle (const tcu::Vec4& color, const tcu::UVec4& swizzle)
157 {
158         const float channelValues[] =
159         {
160                 0.0f,
161                 1.0f,
162                 color.x(),
163                 color.y(),
164                 color.z(),
165                 color.w()
166         };
167
168         return tcu::Vec4(channelValues[swizzle.x()],
169                                          channelValues[swizzle.y()],
170                                          channelValues[swizzle.z()],
171                                          channelValues[swizzle.w()]);
172 }
173
174 ReferenceRenderer::ReferenceRenderer(int                                                surfaceWidth,
175                                                                          int                                            surfaceHeight,
176                                                                          int                                            numSamples,
177                                                                          const tcu::TextureFormat&      colorFormat,
178                                                                          const tcu::TextureFormat&      depthStencilFormat,
179                                                                          const rr::Program* const       program)
180         : m_surfaceWidth                (surfaceWidth)
181         , m_surfaceHeight               (surfaceHeight)
182         , m_numSamples                  (numSamples)
183         , m_colorFormat                 (colorFormat)
184         , m_depthStencilFormat  (depthStencilFormat)
185         , m_program                             (program)
186 {
187         const tcu::TextureChannelClass  formatClass                             = tcu::getTextureChannelClass(colorFormat.type);
188         const bool                                              hasDepthStencil                 = (m_depthStencilFormat.order != tcu::TextureFormat::CHANNELORDER_LAST);
189         const bool                                              hasDepthBufferOnly              = (m_depthStencilFormat.order == tcu::TextureFormat::D);
190         const bool                                              hasStencilBufferOnly    = (m_depthStencilFormat.order == tcu::TextureFormat::S);
191         const int                                               actualSamples                   = (formatClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || formatClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)? 1: m_numSamples;
192
193         m_colorBuffer.setStorage(m_colorFormat, actualSamples, m_surfaceWidth, m_surfaceHeight);
194         m_resolveColorBuffer.setStorage(m_colorFormat, m_surfaceWidth, m_surfaceHeight);
195
196         if (formatClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
197         {
198                 tcu::clear(m_colorBuffer.getAccess(), defaultClearColorInt(m_colorFormat));
199                 tcu::clear(m_resolveColorBuffer.getAccess(), defaultClearColorInt(m_colorFormat));
200         }
201         else if (formatClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
202         {
203                 tcu::clear(m_colorBuffer.getAccess(), defaultClearColorUint(m_colorFormat));
204                 tcu::clear(m_resolveColorBuffer.getAccess(), defaultClearColorUint(m_colorFormat));
205         }
206         else
207         {
208                 tcu::Vec4 clearColor = defaultClearColor(m_colorFormat);
209
210                 if (isSRGB(m_colorFormat))
211                         clearColor = tcu::linearToSRGB(clearColor);
212
213                 tcu::clear(m_colorBuffer.getAccess(), clearColor);
214                 tcu::clear(m_resolveColorBuffer.getAccess(), clearColor);
215         }
216
217         if (hasDepthStencil)
218         {
219                 if (hasDepthBufferOnly)
220                 {
221                         m_depthStencilBuffer.setStorage(m_depthStencilFormat, actualSamples, surfaceWidth, surfaceHeight);
222                         tcu::clearDepth(m_depthStencilBuffer.getAccess(), defaultClearDepth());
223
224                         m_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()),
225                                                                                                   rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()));
226                 }
227                 else if (hasStencilBufferOnly)
228                 {
229                         m_depthStencilBuffer.setStorage(m_depthStencilFormat, actualSamples, surfaceWidth, surfaceHeight);
230                         tcu::clearStencil(m_depthStencilBuffer.getAccess(), defaultClearStencil());
231
232                         m_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()),
233                                                                                                   rr::MultisamplePixelBufferAccess(),
234                                                                                                   rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()));
235                 }
236                 else
237                 {
238                         m_depthStencilBuffer.setStorage(m_depthStencilFormat, actualSamples, surfaceWidth, surfaceHeight);
239
240                         tcu::clearDepth(m_depthStencilBuffer.getAccess(), defaultClearDepth());
241                         tcu::clearStencil(m_depthStencilBuffer.getAccess(), defaultClearStencil());
242
243                         m_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()),
244                                                                                                   rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()),
245                                                                                                   rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()));
246                 }
247         }
248         else
249         {
250                 m_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()));
251         }
252 }
253
254 ReferenceRenderer::~ReferenceRenderer (void)
255 {
256         delete m_renderTarget;
257 }
258
259 void ReferenceRenderer::colorClear(const tcu::Vec4& color)
260 {
261         tcu::clear(m_colorBuffer.getAccess(), color);
262         tcu::clear(m_resolveColorBuffer.getAccess(), color);
263 }
264
265 void ReferenceRenderer::draw (const rr::RenderState&                    renderState,
266                                                           const rr::PrimitiveType                       primitive,
267                                                           const std::vector<Vertex4RGBA>&       vertexBuffer)
268 {
269         const rr::PrimitiveList primitives(primitive, (int)vertexBuffer.size(), 0);
270
271         std::vector<tcu::Vec4> positions;
272         std::vector<tcu::Vec4> colors;
273
274         for (size_t vertexNdx = 0; vertexNdx < vertexBuffer.size(); vertexNdx++)
275         {
276                 const Vertex4RGBA& v = vertexBuffer[vertexNdx];
277                 positions.push_back(v.position);
278                 colors.push_back(v.color);
279         }
280
281         rr::VertexAttrib vertexAttribs[2];
282
283         // Position attribute
284         vertexAttribs[0].type           = rr::VERTEXATTRIBTYPE_FLOAT;
285         vertexAttribs[0].size           = 4;
286         vertexAttribs[0].pointer        = positions.data();
287         // UV attribute
288         vertexAttribs[1].type           = rr::VERTEXATTRIBTYPE_FLOAT;
289         vertexAttribs[1].size           = 4;
290         vertexAttribs[1].pointer        = colors.data();
291
292         rr::DrawCommand drawQuadCommand(renderState, *m_renderTarget, *m_program, 2, vertexAttribs, primitives);
293
294         m_renderer.draw(drawQuadCommand);
295 }
296
297 void ReferenceRenderer::draw (const rr::RenderState&                    renderState,
298                                                           const rr::PrimitiveType                       primitive,
299                                                           const std::vector<Vertex4Tex4>&       vertexBuffer)
300 {
301         const rr::PrimitiveList primitives(primitive, (int)vertexBuffer.size(), 0);
302
303         std::vector<tcu::Vec4> positions;
304         std::vector<tcu::Vec4> texCoords;
305
306         for (size_t vertexNdx = 0; vertexNdx < vertexBuffer.size(); vertexNdx++)
307         {
308                 const Vertex4Tex4& v = vertexBuffer[vertexNdx];
309                 positions.push_back(v.position);
310                 texCoords.push_back(v.texCoord);
311         }
312
313         rr::VertexAttrib vertexAttribs[2];
314
315         // Position attribute
316         vertexAttribs[0].type           = rr::VERTEXATTRIBTYPE_FLOAT;
317         vertexAttribs[0].size           = 4;
318         vertexAttribs[0].pointer        = positions.data();
319         // UV attribute
320         vertexAttribs[1].type           = rr::VERTEXATTRIBTYPE_FLOAT;
321         vertexAttribs[1].size           = 4;
322         vertexAttribs[1].pointer        = texCoords.data();
323
324         rr::DrawCommand drawQuadCommand(renderState, *m_renderTarget, *m_program, 2, vertexAttribs, primitives);
325
326         m_renderer.draw(drawQuadCommand);
327 }
328
329 tcu::PixelBufferAccess ReferenceRenderer::getAccess (void)
330 {
331         rr::MultisampleConstPixelBufferAccess multiSampleAccess = rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess());
332         rr::resolveMultisampleColorBuffer(m_resolveColorBuffer.getAccess(), multiSampleAccess);
333
334         return m_resolveColorBuffer.getAccess();
335 }
336
337 const rr::ViewportState ReferenceRenderer::getViewportState (void) const
338 {
339         return rr::ViewportState(rr::WindowRectangle(0, 0, m_surfaceWidth, m_surfaceHeight));
340 }
341
342 } // pipeline
343 } // vkt