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 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 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 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 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 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 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 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 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_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()), 214 rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess())); 215 } 216 else if (hasStencilBufferOnly) 217 { 218 m_depthStencilBuffer.setStorage(m_depthStencilFormat, actualSamples, surfaceWidth, surfaceHeight); 219 tcu::clearStencil(m_depthStencilBuffer.getAccess(), defaultClearStencil()); 220 221 m_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()), 222 rr::MultisamplePixelBufferAccess(), 223 rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess())); 224 } 225 else 226 { 227 m_depthStencilBuffer.setStorage(m_depthStencilFormat, actualSamples, surfaceWidth, surfaceHeight); 228 229 tcu::clearDepth(m_depthStencilBuffer.getAccess(), defaultClearDepth()); 230 tcu::clearStencil(m_depthStencilBuffer.getAccess(), defaultClearStencil()); 231 232 m_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()), 233 rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()), 234 rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess())); 235 } 236 } 237 else 238 { 239 m_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess())); 240 } 241 } 242 243 ReferenceRenderer::~ReferenceRenderer (void) 244 { 245 delete m_renderTarget; 246 } 247 248 void ReferenceRenderer::colorClear(const tcu::Vec4& color) 249 { 250 tcu::clear(m_colorBuffer.getAccess(), color); 251 tcu::clear(m_resolveColorBuffer.getAccess(), color); 252 } 253 254 void ReferenceRenderer::draw (const rr::RenderState& renderState, 255 const rr::PrimitiveType primitive, 256 const std::vector<Vertex4RGBA>& vertexBuffer) 257 { 258 const rr::PrimitiveList primitives(primitive, (int)vertexBuffer.size(), 0); 259 260 std::vector<tcu::Vec4> positions; 261 std::vector<tcu::Vec4> colors; 262 263 for (size_t vertexNdx = 0; vertexNdx < vertexBuffer.size(); vertexNdx++) 264 { 265 const Vertex4RGBA& v = vertexBuffer[vertexNdx]; 266 positions.push_back(v.position); 267 colors.push_back(v.color); 268 } 269 270 rr::VertexAttrib vertexAttribs[2]; 271 272 // Position attribute 273 vertexAttribs[0].type = rr::VERTEXATTRIBTYPE_FLOAT; 274 vertexAttribs[0].size = 4; 275 vertexAttribs[0].pointer = positions.data(); 276 // UV attribute 277 vertexAttribs[1].type = rr::VERTEXATTRIBTYPE_FLOAT; 278 vertexAttribs[1].size = 4; 279 vertexAttribs[1].pointer = colors.data(); 280 281 rr::DrawCommand drawQuadCommand(renderState, *m_renderTarget, *m_program, 2, vertexAttribs, primitives); 282 283 m_renderer.draw(drawQuadCommand); 284 } 285 286 void ReferenceRenderer::draw (const rr::RenderState& renderState, 287 const rr::PrimitiveType primitive, 288 const std::vector<Vertex4Tex4>& vertexBuffer) 289 { 290 const rr::PrimitiveList primitives(primitive, (int)vertexBuffer.size(), 0); 291 292 std::vector<tcu::Vec4> positions; 293 std::vector<tcu::Vec4> texCoords; 294 295 for (size_t vertexNdx = 0; vertexNdx < vertexBuffer.size(); vertexNdx++) 296 { 297 const Vertex4Tex4& v = vertexBuffer[vertexNdx]; 298 positions.push_back(v.position); 299 texCoords.push_back(v.texCoord); 300 } 301 302 rr::VertexAttrib vertexAttribs[2]; 303 304 // Position attribute 305 vertexAttribs[0].type = rr::VERTEXATTRIBTYPE_FLOAT; 306 vertexAttribs[0].size = 4; 307 vertexAttribs[0].pointer = positions.data(); 308 // UV attribute 309 vertexAttribs[1].type = rr::VERTEXATTRIBTYPE_FLOAT; 310 vertexAttribs[1].size = 4; 311 vertexAttribs[1].pointer = texCoords.data(); 312 313 rr::DrawCommand drawQuadCommand(renderState, *m_renderTarget, *m_program, 2, vertexAttribs, primitives); 314 315 m_renderer.draw(drawQuadCommand); 316 } 317 318 tcu::PixelBufferAccess ReferenceRenderer::getAccess (void) 319 { 320 rr::MultisampleConstPixelBufferAccess multiSampleAccess = rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()); 321 rr::resolveMultisampleColorBuffer(m_resolveColorBuffer.getAccess(), multiSampleAccess); 322 323 return m_resolveColorBuffer.getAccess(); 324 } 325 326 const rr::ViewportState ReferenceRenderer::getViewportState (void) const 327 { 328 return rr::ViewportState(rr::WindowRectangle(0, 0, m_surfaceWidth, m_surfaceHeight)); 329 } 330 331 } // pipeline 332 } // vkt 333