1 #ifndef _VKTPIPELINEREFERENCERENDERER_HPP 2 #define _VKTPIPELINEREFERENCERENDERER_HPP 3 /*------------------------------------------------------------------------ 4 * Vulkan Conformance Tests 5 * ------------------------ 6 * 7 * Copyright (c) 2015 The Khronos Group Inc. 8 * Copyright (c) 2015 Imagination Technologies Ltd. 9 * 10 * Licensed under the Apache License, Version 2.0 (the "License"); 11 * you may not use this file except in compliance with the License. 12 * You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, software 17 * distributed under the License is distributed on an "AS IS" BASIS, 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 * See the License for the specific language governing permissions and 20 * limitations under the License. 21 * 22 *//*! 23 * \file 24 * \brief Reference renderer. 25 *//*--------------------------------------------------------------------*/ 26 27 #include "vkDefs.hpp" 28 #include "vktPipelineVertexUtil.hpp" 29 #include "tcuVector.hpp" 30 #include "tcuVectorType.hpp" 31 #include "tcuTexture.hpp" 32 #include "tcuTextureUtil.hpp" 33 #include "rrRenderState.hpp" 34 #include "rrRenderer.hpp" 35 #include <cstring> 36 37 namespace vkt 38 { 39 40 namespace pipeline 41 { 42 43 tcu::Vec4 swizzle(const tcu::Vec4 &color, const tcu::UVec4 &swizzle); 44 45 class ColorVertexShader : public rr::VertexShader 46 { 47 public: ColorVertexShader(void)48 ColorVertexShader(void) : rr::VertexShader(2, 2) 49 { 50 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 51 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 52 53 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; 54 m_outputs[1].type = rr::GENERICVECTYPE_FLOAT; 55 } 56 ~ColorVertexShader(void)57 virtual ~ColorVertexShader(void) 58 { 59 } 60 shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const61 virtual void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, 62 const int numPackets) const 63 { 64 tcu::Vec4 position; 65 tcu::Vec4 color; 66 67 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 68 { 69 rr::VertexPacket *const packet = packets[packetNdx]; 70 71 readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx); 72 readVertexAttrib(color, inputs[1], packet->instanceNdx, packet->vertexNdx); 73 74 packet->outputs[0] = position; 75 packet->outputs[1] = color; 76 packet->position = position; 77 } 78 } 79 }; 80 81 class ColorVertexShaderDualSource : public rr::VertexShader 82 { 83 public: ColorVertexShaderDualSource(void)84 ColorVertexShaderDualSource(void) : rr::VertexShader(3, 3) 85 { 86 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 87 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 88 m_inputs[2].type = rr::GENERICVECTYPE_FLOAT; 89 90 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; 91 m_outputs[1].type = rr::GENERICVECTYPE_FLOAT; 92 m_outputs[2].type = rr::GENERICVECTYPE_FLOAT; 93 } 94 ~ColorVertexShaderDualSource(void)95 virtual ~ColorVertexShaderDualSource(void) 96 { 97 } 98 shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const99 virtual void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, 100 const int numPackets) const 101 { 102 tcu::Vec4 position; 103 tcu::Vec4 color0; 104 tcu::Vec4 color1; 105 106 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 107 { 108 rr::VertexPacket *const packet = packets[packetNdx]; 109 110 readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx); 111 readVertexAttrib(color0, inputs[1], packet->instanceNdx, packet->vertexNdx); 112 readVertexAttrib(color1, inputs[2], packet->instanceNdx, packet->vertexNdx); 113 114 packet->outputs[0] = position; 115 packet->outputs[1] = color0; 116 packet->outputs[2] = color1; 117 packet->position = position; 118 } 119 } 120 }; 121 122 class TexCoordVertexShader : public rr::VertexShader 123 { 124 public: TexCoordVertexShader(void)125 TexCoordVertexShader(void) : rr::VertexShader(2, 2) 126 { 127 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 128 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 129 130 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; 131 m_outputs[1].type = rr::GENERICVECTYPE_FLOAT; 132 } 133 ~TexCoordVertexShader(void)134 virtual ~TexCoordVertexShader(void) 135 { 136 } 137 shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const138 virtual void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, 139 const int numPackets) const 140 { 141 tcu::Vec4 position; 142 tcu::Vec4 texCoord; 143 144 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 145 { 146 rr::VertexPacket *const packet = packets[packetNdx]; 147 148 readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx); 149 readVertexAttrib(texCoord, inputs[1], packet->instanceNdx, packet->vertexNdx); 150 151 packet->outputs[0] = position; 152 packet->outputs[1] = texCoord; 153 packet->position = position; 154 } 155 } 156 }; 157 158 class ColorFragmentShader : public rr::FragmentShader 159 { 160 private: 161 const tcu::TextureFormat m_colorFormat; 162 const tcu::TextureFormat m_depthStencilFormat; 163 const bool m_disableVulkanDepthRange; 164 165 public: ColorFragmentShader(const tcu::TextureFormat & colorFormat,const tcu::TextureFormat & depthStencilFormat,const bool disableVulkanDepthRange=false)166 ColorFragmentShader(const tcu::TextureFormat &colorFormat, const tcu::TextureFormat &depthStencilFormat, 167 const bool disableVulkanDepthRange = false) 168 : rr::FragmentShader(2, 1) 169 , m_colorFormat(colorFormat) 170 , m_depthStencilFormat(depthStencilFormat) 171 , m_disableVulkanDepthRange(disableVulkanDepthRange) 172 { 173 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(m_colorFormat.type); 174 175 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 176 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 177 m_outputs[0].type = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) ? rr::GENERICVECTYPE_INT32 : 178 (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) ? rr::GENERICVECTYPE_UINT32 : 179 rr::GENERICVECTYPE_FLOAT; 180 } 181 ~ColorFragmentShader(void)182 virtual ~ColorFragmentShader(void) 183 { 184 } 185 shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const186 virtual void shadeFragments(rr::FragmentPacket *packets, const int numPackets, 187 const rr::FragmentShadingContext &context) const 188 { 189 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 190 { 191 const rr::FragmentPacket &packet = packets[packetNdx]; 192 193 // Reference renderer uses OpenGL depth range of -1..1, and does the viewport depth transform using 194 // formula (position.z+1)/2. For Vulkan the depth range is 0..1 and the vertex depth is mapped as is, so 195 // the values gets overridden here, unless depth clip control extension changes the depth clipping to use 196 // the OpenGL depth range. 197 if (!m_disableVulkanDepthRange && (m_depthStencilFormat.order == tcu::TextureFormat::D || 198 m_depthStencilFormat.order == tcu::TextureFormat::DS)) 199 { 200 for (int fragNdx = 0; fragNdx < 4; fragNdx++) 201 { 202 const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx); 203 rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z()); 204 } 205 } 206 207 for (int fragNdx = 0; fragNdx < 4; fragNdx++) 208 { 209 const tcu::Vec4 vtxColor = rr::readVarying<float>(packet, context, 1, fragNdx); 210 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, vtxColor); 211 } 212 } 213 } 214 }; 215 216 class ColorFragmentShaderDualSource : public rr::FragmentShader 217 { 218 private: 219 const tcu::TextureFormat m_colorFormat; 220 const tcu::TextureFormat m_depthStencilFormat; 221 222 public: ColorFragmentShaderDualSource(const tcu::TextureFormat & colorFormat,const tcu::TextureFormat & depthStencilFormat)223 ColorFragmentShaderDualSource(const tcu::TextureFormat &colorFormat, const tcu::TextureFormat &depthStencilFormat) 224 : rr::FragmentShader(3, 1) 225 , m_colorFormat(colorFormat) 226 , m_depthStencilFormat(depthStencilFormat) 227 { 228 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(m_colorFormat.type); 229 230 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 231 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 232 m_inputs[2].type = rr::GENERICVECTYPE_FLOAT; 233 234 m_outputs[0].type = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) ? rr::GENERICVECTYPE_INT32 : 235 (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) ? rr::GENERICVECTYPE_UINT32 : 236 rr::GENERICVECTYPE_FLOAT; 237 } 238 ~ColorFragmentShaderDualSource(void)239 virtual ~ColorFragmentShaderDualSource(void) 240 { 241 } 242 shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const243 virtual void shadeFragments(rr::FragmentPacket *packets, const int numPackets, 244 const rr::FragmentShadingContext &context) const 245 { 246 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 247 { 248 const rr::FragmentPacket &packet = packets[packetNdx]; 249 250 if (m_depthStencilFormat.order == tcu::TextureFormat::D || 251 m_depthStencilFormat.order == tcu::TextureFormat::DS) 252 { 253 for (int fragNdx = 0; fragNdx < 4; fragNdx++) 254 { 255 const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx); 256 rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z()); 257 } 258 } 259 260 for (int fragNdx = 0; fragNdx < 4; fragNdx++) 261 { 262 const tcu::Vec4 vtxColor0 = rr::readVarying<float>(packet, context, 1, fragNdx); 263 const tcu::Vec4 vtxColor1 = rr::readVarying<float>(packet, context, 2, fragNdx); 264 rr::writeFragmentOutputDualSource(context, packetNdx, fragNdx, 0, vtxColor0, vtxColor1); 265 } 266 } 267 } 268 }; 269 270 class CoordinateCaptureFragmentShader : public rr::FragmentShader 271 { 272 public: CoordinateCaptureFragmentShader(void)273 CoordinateCaptureFragmentShader(void) : rr::FragmentShader(2, 1) 274 { 275 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 276 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 277 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; 278 } 279 ~CoordinateCaptureFragmentShader(void)280 virtual ~CoordinateCaptureFragmentShader(void) 281 { 282 } 283 shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const284 virtual void shadeFragments(rr::FragmentPacket *packets, const int numPackets, 285 const rr::FragmentShadingContext &context) const 286 { 287 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 288 { 289 const rr::FragmentPacket &packet = packets[packetNdx]; 290 291 for (int fragNdx = 0; fragNdx < 4; fragNdx++) 292 { 293 const tcu::Vec4 vtxTexCoord = rr::readVarying<float>(packet, context, 1, fragNdx); 294 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, vtxTexCoord); 295 } 296 } 297 } 298 }; 299 300 class Program 301 { 302 public: ~Program(void)303 virtual ~Program(void) 304 { 305 } 306 307 virtual rr::Program getReferenceProgram(void) const = 0; 308 }; 309 310 class CoordinateCaptureProgram : public Program 311 { 312 private: 313 TexCoordVertexShader m_vertexShader; 314 CoordinateCaptureFragmentShader m_fragmentShader; 315 316 public: CoordinateCaptureProgram(void)317 CoordinateCaptureProgram(void) 318 { 319 } 320 ~CoordinateCaptureProgram(void)321 virtual ~CoordinateCaptureProgram(void) 322 { 323 } 324 getReferenceProgram(void) const325 virtual rr::Program getReferenceProgram(void) const 326 { 327 return rr::Program(&m_vertexShader, &m_fragmentShader); 328 } 329 }; 330 331 class ReferenceRenderer 332 { 333 public: 334 ReferenceRenderer(int surfaceWidth, int surfaceHeight, int numSamples, const tcu::TextureFormat &colorFormat, 335 const tcu::TextureFormat &depthStencilFormat, const rr::Program *const program); 336 337 virtual ~ReferenceRenderer(void); 338 339 void colorClear(const tcu::Vec4 &color); 340 341 void draw(const rr::RenderState &renderState, const rr::PrimitiveType primitive, 342 const std::vector<Vertex4RGBA> &vertexBuffer); 343 344 void draw(const rr::RenderState &renderState, const rr::PrimitiveType primitive, 345 const std::vector<Vertex4RGBARGBA> &vertexBuffer); 346 347 void draw(const rr::RenderState &renderState, const rr::PrimitiveType primitive, 348 const std::vector<Vertex4Tex4> &vertexBuffer); 349 350 tcu::PixelBufferAccess getAccess(void); 351 tcu::PixelBufferAccess getDepthStencilAccess(void); 352 const rr::ViewportState getViewportState(void) const; 353 354 private: 355 rr::Renderer m_renderer; 356 357 const int m_surfaceWidth; 358 const int m_surfaceHeight; 359 const int m_numSamples; 360 361 const tcu::TextureFormat m_colorFormat; 362 const tcu::TextureFormat m_depthStencilFormat; 363 364 tcu::TextureLevel m_colorBuffer; 365 tcu::TextureLevel m_resolveColorBuffer; 366 tcu::TextureLevel m_depthStencilBuffer; 367 tcu::TextureLevel m_resolveDepthStencilBuffer; 368 369 rr::RenderTarget *m_renderTarget; 370 const rr::Program *m_program; 371 }; 372 373 rr::TestFunc mapVkCompareOp(vk::VkCompareOp compareFunc); 374 rr::PrimitiveType mapVkPrimitiveTopology(vk::VkPrimitiveTopology primitiveTopology); 375 rr::BlendFunc mapVkBlendFactor(vk::VkBlendFactor blendFactor); 376 rr::BlendEquation mapVkBlendOp(vk::VkBlendOp blendOp); 377 tcu::BVec4 mapVkColorComponentFlags(vk::VkColorComponentFlags flags); 378 rr::StencilOp mapVkStencilOp(vk::VkStencilOp stencilOp); 379 380 } // namespace pipeline 381 } // namespace vkt 382 383 #endif // _VKTPIPELINEREFERENCERENDERER_HPP 384