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: return rr::BLENDFUNC_ZERO;
42 case VK_BLEND_FACTOR_ONE: return rr::BLENDFUNC_ONE;
43 case VK_BLEND_FACTOR_SRC_COLOR: return rr::BLENDFUNC_SRC_COLOR;
44 case VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR: return rr::BLENDFUNC_ONE_MINUS_SRC_COLOR;
45 case VK_BLEND_FACTOR_DST_COLOR: return rr::BLENDFUNC_DST_COLOR;
46 case VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR: return rr::BLENDFUNC_ONE_MINUS_DST_COLOR;
47 case VK_BLEND_FACTOR_SRC_ALPHA: return rr::BLENDFUNC_SRC_ALPHA;
48 case VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: return rr::BLENDFUNC_ONE_MINUS_SRC_ALPHA;
49 case VK_BLEND_FACTOR_DST_ALPHA: return rr::BLENDFUNC_DST_ALPHA;
50 case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: return rr::BLENDFUNC_ONE_MINUS_DST_ALPHA;
51 case VK_BLEND_FACTOR_CONSTANT_COLOR: return rr::BLENDFUNC_CONSTANT_COLOR;
52 case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR: return rr::BLENDFUNC_ONE_MINUS_CONSTANT_COLOR;
53 case VK_BLEND_FACTOR_CONSTANT_ALPHA: return rr::BLENDFUNC_CONSTANT_ALPHA;
54 case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA: return rr::BLENDFUNC_ONE_MINUS_CONSTANT_ALPHA;
55 case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE: return rr::BLENDFUNC_SRC_ALPHA_SATURATE;
56 case VK_BLEND_FACTOR_SRC1_COLOR: return rr::BLENDFUNC_SRC1_COLOR;
57 case VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR: return rr::BLENDFUNC_ONE_MINUS_SRC1_COLOR;
58 case VK_BLEND_FACTOR_SRC1_ALPHA: return rr::BLENDFUNC_SRC1_ALPHA;
59 case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA: return rr::BLENDFUNC_ONE_MINUS_SRC1_ALPHA;
60 default:
61 DE_ASSERT(false);
62 }
63 return rr::BLENDFUNC_LAST;
64 }
65
mapVkBlendOp(VkBlendOp blendOp)66 rr::BlendEquation mapVkBlendOp (VkBlendOp blendOp)
67 {
68 switch (blendOp)
69 {
70 case VK_BLEND_OP_ADD: return rr::BLENDEQUATION_ADD;
71 case VK_BLEND_OP_SUBTRACT: return rr::BLENDEQUATION_SUBTRACT;
72 case VK_BLEND_OP_REVERSE_SUBTRACT: return rr::BLENDEQUATION_REVERSE_SUBTRACT;
73 case VK_BLEND_OP_MIN: return rr::BLENDEQUATION_MIN;
74 case VK_BLEND_OP_MAX: return rr::BLENDEQUATION_MAX;
75 default:
76 DE_ASSERT(false);
77 }
78 return rr::BLENDEQUATION_LAST;
79 }
80
mapVkColorComponentFlags(VkColorComponentFlags flags)81 tcu::BVec4 mapVkColorComponentFlags (VkColorComponentFlags flags)
82 {
83 return tcu::BVec4((flags & VK_COLOR_COMPONENT_R_BIT) != 0,
84 (flags & VK_COLOR_COMPONENT_G_BIT) != 0,
85 (flags & VK_COLOR_COMPONENT_B_BIT) != 0,
86 (flags & VK_COLOR_COMPONENT_A_BIT) != 0);
87 }
88
mapVkCompareOp(VkCompareOp compareFunc)89 rr::TestFunc mapVkCompareOp (VkCompareOp compareFunc)
90 {
91 switch (compareFunc)
92 {
93 case VK_COMPARE_OP_NEVER: return rr::TESTFUNC_NEVER;
94 case VK_COMPARE_OP_LESS: return rr::TESTFUNC_LESS;
95 case VK_COMPARE_OP_EQUAL: return rr::TESTFUNC_EQUAL;
96 case VK_COMPARE_OP_LESS_OR_EQUAL: return rr::TESTFUNC_LEQUAL;
97 case VK_COMPARE_OP_GREATER: return rr::TESTFUNC_GREATER;
98 case VK_COMPARE_OP_NOT_EQUAL: return rr::TESTFUNC_NOTEQUAL;
99 case VK_COMPARE_OP_GREATER_OR_EQUAL: return rr::TESTFUNC_GEQUAL;
100 case VK_COMPARE_OP_ALWAYS: return rr::TESTFUNC_ALWAYS;
101 default:
102 DE_ASSERT(false);
103 }
104 return rr::TESTFUNC_LAST;
105 }
106
mapVkPrimitiveTopology(VkPrimitiveTopology primitiveTopology)107 rr::PrimitiveType mapVkPrimitiveTopology (VkPrimitiveTopology primitiveTopology)
108 {
109 switch (primitiveTopology)
110 {
111 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: return rr::PRIMITIVETYPE_POINTS;
112 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: return rr::PRIMITIVETYPE_LINES;
113 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: return rr::PRIMITIVETYPE_LINE_STRIP;
114 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: return rr::PRIMITIVETYPE_TRIANGLES;
115 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: return rr::PRIMITIVETYPE_TRIANGLE_FAN;
116 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: return rr::PRIMITIVETYPE_TRIANGLE_STRIP;
117 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: return rr::PRIMITIVETYPE_LINES_ADJACENCY;
118 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: return rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY;
119 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: return rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY;
120 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: return rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY;
121 default:
122 DE_ASSERT(false);
123 }
124 return rr::PRIMITIVETYPE_LAST;
125 }
126
mapVkStencilOp(vk::VkStencilOp stencilOp)127 rr::StencilOp mapVkStencilOp (vk::VkStencilOp stencilOp)
128 {
129 switch (stencilOp)
130 {
131 case VK_STENCIL_OP_KEEP: return rr::STENCILOP_KEEP;
132 case VK_STENCIL_OP_ZERO: return rr::STENCILOP_ZERO;
133 case VK_STENCIL_OP_REPLACE: return rr::STENCILOP_REPLACE;
134 case VK_STENCIL_OP_INCREMENT_AND_CLAMP: return rr::STENCILOP_INCR;
135 case VK_STENCIL_OP_DECREMENT_AND_CLAMP: return rr::STENCILOP_DECR;
136 case VK_STENCIL_OP_INVERT: return rr::STENCILOP_INVERT;
137 case VK_STENCIL_OP_INCREMENT_AND_WRAP: return rr::STENCILOP_INCR_WRAP;
138 case VK_STENCIL_OP_DECREMENT_AND_WRAP: return rr::STENCILOP_DECR_WRAP;
139 default:
140 DE_ASSERT(false);
141 }
142 return rr::STENCILOP_LAST;
143 }
144
swizzle(const tcu::Vec4 & color,const tcu::UVec4 & swizzle)145 tcu::Vec4 swizzle (const tcu::Vec4& color, const tcu::UVec4& swizzle)
146 {
147 const float channelValues[] =
148 {
149 0.0f,
150 1.0f,
151 color.x(),
152 color.y(),
153 color.z(),
154 color.w()
155 };
156
157 return tcu::Vec4(channelValues[swizzle.x()],
158 channelValues[swizzle.y()],
159 channelValues[swizzle.z()],
160 channelValues[swizzle.w()]);
161 }
162
ReferenceRenderer(int surfaceWidth,int surfaceHeight,int numSamples,const tcu::TextureFormat & colorFormat,const tcu::TextureFormat & depthStencilFormat,const rr::Program * const program)163 ReferenceRenderer::ReferenceRenderer(int surfaceWidth,
164 int surfaceHeight,
165 int numSamples,
166 const tcu::TextureFormat& colorFormat,
167 const tcu::TextureFormat& depthStencilFormat,
168 const rr::Program* const program)
169 : m_surfaceWidth (surfaceWidth)
170 , m_surfaceHeight (surfaceHeight)
171 , m_numSamples (numSamples)
172 , m_colorFormat (colorFormat)
173 , m_depthStencilFormat (depthStencilFormat)
174 , m_program (program)
175 {
176 const tcu::TextureChannelClass formatClass = tcu::getTextureChannelClass(colorFormat.type);
177 const bool hasDepthStencil = (m_depthStencilFormat.order != tcu::TextureFormat::CHANNELORDER_LAST);
178 const bool hasDepthBufferOnly = (m_depthStencilFormat.order == tcu::TextureFormat::D);
179 const bool hasStencilBufferOnly = (m_depthStencilFormat.order == tcu::TextureFormat::S);
180 const int actualSamples = (formatClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || formatClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)? 1: m_numSamples;
181
182 m_colorBuffer.setStorage(m_colorFormat, actualSamples, m_surfaceWidth, m_surfaceHeight);
183 m_resolveColorBuffer.setStorage(m_colorFormat, m_surfaceWidth, m_surfaceHeight);
184
185 if (formatClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
186 {
187 tcu::clear(m_colorBuffer.getAccess(), defaultClearColorInt(m_colorFormat));
188 tcu::clear(m_resolveColorBuffer.getAccess(), defaultClearColorInt(m_colorFormat));
189 }
190 else if (formatClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
191 {
192 tcu::clear(m_colorBuffer.getAccess(), defaultClearColorUint(m_colorFormat));
193 tcu::clear(m_resolveColorBuffer.getAccess(), defaultClearColorUint(m_colorFormat));
194 }
195 else
196 {
197 tcu::Vec4 clearColor = defaultClearColor(m_colorFormat);
198
199 if (isSRGB(m_colorFormat))
200 clearColor = tcu::linearToSRGB(clearColor);
201
202 tcu::clear(m_colorBuffer.getAccess(), clearColor);
203 tcu::clear(m_resolveColorBuffer.getAccess(), clearColor);
204 }
205
206 if (hasDepthStencil)
207 {
208 if (hasDepthBufferOnly)
209 {
210 m_depthStencilBuffer.setStorage(m_depthStencilFormat, actualSamples, surfaceWidth, surfaceHeight);
211 tcu::clearDepth(m_depthStencilBuffer.getAccess(), defaultClearDepth());
212
213 m_resolveDepthStencilBuffer.setStorage(m_depthStencilFormat, surfaceWidth, surfaceHeight);
214 tcu::clearDepth(m_resolveDepthStencilBuffer.getAccess(), defaultClearDepth());
215
216 m_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()),
217 rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()));
218 }
219 else if (hasStencilBufferOnly)
220 {
221 m_depthStencilBuffer.setStorage(m_depthStencilFormat, actualSamples, surfaceWidth, surfaceHeight);
222 tcu::clearStencil(m_depthStencilBuffer.getAccess(), defaultClearStencil());
223
224 m_resolveDepthStencilBuffer.setStorage(m_depthStencilFormat, surfaceWidth, surfaceHeight);
225 tcu::clearStencil(m_resolveDepthStencilBuffer.getAccess(), defaultClearStencil());
226
227 m_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()),
228 rr::MultisamplePixelBufferAccess(),
229 rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()));
230 }
231 else
232 {
233 m_depthStencilBuffer.setStorage(m_depthStencilFormat, actualSamples, surfaceWidth, surfaceHeight);
234
235 tcu::clearDepth(m_depthStencilBuffer.getAccess(), defaultClearDepth());
236 tcu::clearStencil(m_depthStencilBuffer.getAccess(), defaultClearStencil());
237
238 m_resolveDepthStencilBuffer.setStorage(m_depthStencilFormat, surfaceWidth, surfaceHeight);
239 tcu::clearDepth(m_resolveDepthStencilBuffer.getAccess(), defaultClearDepth());
240
241 m_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()),
242 rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()),
243 rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()));
244 }
245 }
246 else
247 {
248 m_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()));
249 }
250 }
251
~ReferenceRenderer(void)252 ReferenceRenderer::~ReferenceRenderer (void)
253 {
254 delete m_renderTarget;
255 }
256
colorClear(const tcu::Vec4 & color)257 void ReferenceRenderer::colorClear(const tcu::Vec4& color)
258 {
259 tcu::clear(m_colorBuffer.getAccess(), color);
260 tcu::clear(m_resolveColorBuffer.getAccess(), color);
261 }
262
draw(const rr::RenderState & renderState,const rr::PrimitiveType primitive,const std::vector<Vertex4RGBA> & vertexBuffer)263 void ReferenceRenderer::draw (const rr::RenderState& renderState,
264 const rr::PrimitiveType primitive,
265 const std::vector<Vertex4RGBA>& vertexBuffer)
266 {
267 const rr::PrimitiveList primitives(primitive, (int)vertexBuffer.size(), 0);
268
269 std::vector<tcu::Vec4> positions;
270 std::vector<tcu::Vec4> colors;
271
272 for (size_t vertexNdx = 0; vertexNdx < vertexBuffer.size(); vertexNdx++)
273 {
274 const Vertex4RGBA& v = vertexBuffer[vertexNdx];
275 positions.push_back(v.position);
276 colors.push_back(v.color);
277 }
278
279 rr::VertexAttrib vertexAttribs[2];
280
281 // Position attribute
282 vertexAttribs[0].type = rr::VERTEXATTRIBTYPE_FLOAT;
283 vertexAttribs[0].size = 4;
284 vertexAttribs[0].pointer = positions.data();
285 // UV attribute
286 vertexAttribs[1].type = rr::VERTEXATTRIBTYPE_FLOAT;
287 vertexAttribs[1].size = 4;
288 vertexAttribs[1].pointer = colors.data();
289
290 rr::DrawCommand drawQuadCommand(renderState, *m_renderTarget, *m_program, 2, vertexAttribs, primitives);
291
292 m_renderer.draw(drawQuadCommand);
293 }
draw(const rr::RenderState & renderState,const rr::PrimitiveType primitive,const std::vector<Vertex4RGBARGBA> & vertexBuffer)294 void ReferenceRenderer::draw (const rr::RenderState& renderState,
295 const rr::PrimitiveType primitive,
296 const std::vector<Vertex4RGBARGBA>& vertexBuffer)
297 {
298 const rr::PrimitiveList primitives(primitive, (int)vertexBuffer.size(), 0);
299
300 std::vector<tcu::Vec4> positions;
301 std::vector<tcu::Vec4> color0s;
302 std::vector<tcu::Vec4> color1s;
303
304 for (size_t vertexNdx = 0; vertexNdx < vertexBuffer.size(); vertexNdx++)
305 {
306 const Vertex4RGBARGBA& v = vertexBuffer[vertexNdx];
307 positions.push_back(v.position);
308 color0s.push_back(v.color0);
309 color1s.push_back(v.color1);
310 }
311
312 rr::VertexAttrib vertexAttribs[3];
313
314 // Position attribute
315 vertexAttribs[0].type = rr::VERTEXATTRIBTYPE_FLOAT;
316 vertexAttribs[0].size = 4;
317 vertexAttribs[0].pointer = positions.data();
318 // Color0 attribute
319 vertexAttribs[1].type = rr::VERTEXATTRIBTYPE_FLOAT;
320 vertexAttribs[1].size = 4;
321 vertexAttribs[1].pointer = color0s.data();
322 // Color1 attribute
323 vertexAttribs[2].type = rr::VERTEXATTRIBTYPE_FLOAT;
324 vertexAttribs[2].size = 4;
325 vertexAttribs[2].pointer = color1s.data();
326
327 rr::DrawCommand drawQuadCommand(renderState, *m_renderTarget, *m_program, 3, vertexAttribs, primitives);
328
329 m_renderer.draw(drawQuadCommand);
330 }
331
draw(const rr::RenderState & renderState,const rr::PrimitiveType primitive,const std::vector<Vertex4Tex4> & vertexBuffer)332 void ReferenceRenderer::draw (const rr::RenderState& renderState,
333 const rr::PrimitiveType primitive,
334 const std::vector<Vertex4Tex4>& vertexBuffer)
335 {
336 const rr::PrimitiveList primitives(primitive, (int)vertexBuffer.size(), 0);
337
338 std::vector<tcu::Vec4> positions;
339 std::vector<tcu::Vec4> texCoords;
340
341 for (size_t vertexNdx = 0; vertexNdx < vertexBuffer.size(); vertexNdx++)
342 {
343 const Vertex4Tex4& v = vertexBuffer[vertexNdx];
344 positions.push_back(v.position);
345 texCoords.push_back(v.texCoord);
346 }
347
348 rr::VertexAttrib vertexAttribs[2];
349
350 // Position attribute
351 vertexAttribs[0].type = rr::VERTEXATTRIBTYPE_FLOAT;
352 vertexAttribs[0].size = 4;
353 vertexAttribs[0].pointer = positions.data();
354 // UV attribute
355 vertexAttribs[1].type = rr::VERTEXATTRIBTYPE_FLOAT;
356 vertexAttribs[1].size = 4;
357 vertexAttribs[1].pointer = texCoords.data();
358
359 rr::DrawCommand drawQuadCommand(renderState, *m_renderTarget, *m_program, 2, vertexAttribs, primitives);
360
361 m_renderer.draw(drawQuadCommand);
362 }
363
getAccess(void)364 tcu::PixelBufferAccess ReferenceRenderer::getAccess (void)
365 {
366 rr::MultisampleConstPixelBufferAccess multiSampleAccess = rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess());
367 rr::resolveMultisampleColorBuffer(m_resolveColorBuffer.getAccess(), multiSampleAccess);
368
369 return m_resolveColorBuffer.getAccess();
370 }
371
getDepthStencilAccess(void)372 tcu::PixelBufferAccess ReferenceRenderer::getDepthStencilAccess (void)
373 {
374 rr::MultisampleConstPixelBufferAccess multiSampleAccess = rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess());
375 rr::resolveMultisampleColorBuffer(m_resolveDepthStencilBuffer.getAccess(), multiSampleAccess);
376
377 return m_resolveDepthStencilBuffer.getAccess();
378 }
379
getViewportState(void) const380 const rr::ViewportState ReferenceRenderer::getViewportState (void) const
381 {
382 return rr::ViewportState(rr::WindowRectangle(0, 0, m_surfaceWidth, m_surfaceHeight));
383 }
384
385 } // pipeline
386 } // vkt
387