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 shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const59 virtual void shadeVertices (const rr::VertexAttrib* inputs, 60 rr::VertexPacket* const* packets, 61 const int numPackets) const 62 { 63 tcu::Vec4 position; 64 tcu::Vec4 color; 65 66 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 67 { 68 rr::VertexPacket* const packet = packets[packetNdx]; 69 70 readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx); 71 readVertexAttrib(color, inputs[1], packet->instanceNdx, packet->vertexNdx); 72 73 packet->outputs[0] = position; 74 packet->outputs[1] = color; 75 packet->position = position; 76 } 77 } 78 }; 79 80 class ColorVertexShaderDualSource : public rr::VertexShader 81 { 82 public: ColorVertexShaderDualSource(void)83 ColorVertexShaderDualSource (void) : rr::VertexShader(3, 3) 84 { 85 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 86 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 87 m_inputs[2].type = rr::GENERICVECTYPE_FLOAT; 88 89 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; 90 m_outputs[1].type = rr::GENERICVECTYPE_FLOAT; 91 m_outputs[2].type = rr::GENERICVECTYPE_FLOAT; 92 } 93 ~ColorVertexShaderDualSource(void)94 virtual ~ColorVertexShaderDualSource (void) {} 95 shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const96 virtual void shadeVertices (const rr::VertexAttrib* inputs, 97 rr::VertexPacket* const* packets, 98 const int numPackets) const 99 { 100 tcu::Vec4 position; 101 tcu::Vec4 color0; 102 tcu::Vec4 color1; 103 104 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 105 { 106 rr::VertexPacket* const packet = packets[packetNdx]; 107 108 readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx); 109 readVertexAttrib(color0, inputs[1], packet->instanceNdx, packet->vertexNdx); 110 readVertexAttrib(color1, inputs[2], packet->instanceNdx, packet->vertexNdx); 111 112 packet->outputs[0] = position; 113 packet->outputs[1] = color0; 114 packet->outputs[2] = color1; 115 packet->position = position; 116 } 117 } 118 }; 119 120 class TexCoordVertexShader : public rr::VertexShader 121 { 122 public: TexCoordVertexShader(void)123 TexCoordVertexShader (void) : rr::VertexShader(2, 2) 124 { 125 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 126 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 127 128 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; 129 m_outputs[1].type = rr::GENERICVECTYPE_FLOAT; 130 } 131 ~TexCoordVertexShader(void)132 virtual ~TexCoordVertexShader (void) {} 133 shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const134 virtual void shadeVertices (const rr::VertexAttrib* inputs, 135 rr::VertexPacket* const* packets, 136 const int numPackets) const 137 { 138 tcu::Vec4 position; 139 tcu::Vec4 texCoord; 140 141 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 142 { 143 rr::VertexPacket* const packet = packets[packetNdx]; 144 145 readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx); 146 readVertexAttrib(texCoord, inputs[1], packet->instanceNdx, packet->vertexNdx); 147 148 packet->outputs[0] = position; 149 packet->outputs[1] = texCoord; 150 packet->position = position; 151 } 152 } 153 }; 154 155 class ColorFragmentShader : public rr::FragmentShader 156 { 157 private: 158 const tcu::TextureFormat m_colorFormat; 159 const tcu::TextureFormat m_depthStencilFormat; 160 const bool m_disableVulkanDepthRange; 161 162 public: ColorFragmentShader(const tcu::TextureFormat & colorFormat,const tcu::TextureFormat & depthStencilFormat,const bool disableVulkanDepthRange=false)163 ColorFragmentShader (const tcu::TextureFormat& colorFormat, 164 const tcu::TextureFormat& depthStencilFormat, 165 const bool disableVulkanDepthRange = false) 166 : rr::FragmentShader (2, 1) 167 , m_colorFormat (colorFormat) 168 , m_depthStencilFormat (depthStencilFormat) 169 , m_disableVulkanDepthRange (disableVulkanDepthRange) 170 { 171 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(m_colorFormat.type); 172 173 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 174 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 175 m_outputs[0].type = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)? rr::GENERICVECTYPE_INT32 : 176 (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)? rr::GENERICVECTYPE_UINT32 177 : rr::GENERICVECTYPE_FLOAT; 178 } 179 ~ColorFragmentShader(void)180 virtual ~ColorFragmentShader (void) {} 181 shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const182 virtual void shadeFragments (rr::FragmentPacket* packets, 183 const int numPackets, 184 const rr::FragmentShadingContext& context) const 185 { 186 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 187 { 188 const rr::FragmentPacket& packet = packets[packetNdx]; 189 190 // Reference renderer uses OpenGL depth range of -1..1, and does the viewport depth transform using 191 // formula (position.z+1)/2. For Vulkan the depth range is 0..1 and the vertex depth is mapped as is, so 192 // the values gets overridden here, unless depth clip control extension changes the depth clipping to use 193 // the OpenGL depth range. 194 if (!m_disableVulkanDepthRange && (m_depthStencilFormat.order == tcu::TextureFormat::D || m_depthStencilFormat.order == tcu::TextureFormat::DS)) 195 { 196 for (int fragNdx = 0; fragNdx < 4; fragNdx++) 197 { 198 const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx); 199 rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z()); 200 } 201 } 202 203 for (int fragNdx = 0; fragNdx < 4; fragNdx++) 204 { 205 const tcu::Vec4 vtxColor = rr::readVarying<float>(packet, context, 1, fragNdx); 206 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, vtxColor); 207 } 208 } 209 } 210 }; 211 212 class ColorFragmentShaderDualSource : public rr::FragmentShader 213 { 214 private: 215 const tcu::TextureFormat m_colorFormat; 216 const tcu::TextureFormat m_depthStencilFormat; 217 218 public: ColorFragmentShaderDualSource(const tcu::TextureFormat & colorFormat,const tcu::TextureFormat & depthStencilFormat)219 ColorFragmentShaderDualSource (const tcu::TextureFormat& colorFormat, 220 const tcu::TextureFormat& depthStencilFormat) 221 : rr::FragmentShader (3, 1) 222 , m_colorFormat (colorFormat) 223 , m_depthStencilFormat (depthStencilFormat) 224 { 225 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(m_colorFormat.type); 226 227 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 228 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 229 m_inputs[2].type = rr::GENERICVECTYPE_FLOAT; 230 231 m_outputs[0].type = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)? rr::GENERICVECTYPE_INT32 : 232 (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)? rr::GENERICVECTYPE_UINT32 233 : rr::GENERICVECTYPE_FLOAT; 234 } 235 ~ColorFragmentShaderDualSource(void)236 virtual ~ColorFragmentShaderDualSource (void) {} 237 shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const238 virtual void shadeFragments (rr::FragmentPacket* packets, 239 const int numPackets, 240 const rr::FragmentShadingContext& context) const 241 { 242 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 243 { 244 const rr::FragmentPacket& packet = packets[packetNdx]; 245 246 if (m_depthStencilFormat.order == tcu::TextureFormat::D || m_depthStencilFormat.order == tcu::TextureFormat::DS) 247 { 248 for (int fragNdx = 0; fragNdx < 4; fragNdx++) 249 { 250 const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx); 251 rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z()); 252 } 253 } 254 255 for (int fragNdx = 0; fragNdx < 4; fragNdx++) 256 { 257 const tcu::Vec4 vtxColor0 = rr::readVarying<float>(packet, context, 1, fragNdx); 258 const tcu::Vec4 vtxColor1 = rr::readVarying<float>(packet, context, 2, fragNdx); 259 rr::writeFragmentOutputDualSource(context, packetNdx, fragNdx, 0, vtxColor0, vtxColor1); 260 } 261 } 262 } 263 }; 264 265 class CoordinateCaptureFragmentShader : public rr::FragmentShader 266 { 267 public: CoordinateCaptureFragmentShader(void)268 CoordinateCaptureFragmentShader (void) 269 : rr::FragmentShader(2, 1) 270 { 271 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 272 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 273 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; 274 } 275 ~CoordinateCaptureFragmentShader(void)276 virtual ~CoordinateCaptureFragmentShader (void) 277 { 278 } 279 shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const280 virtual void shadeFragments (rr::FragmentPacket* packets, 281 const int numPackets, 282 const rr::FragmentShadingContext& context) const 283 { 284 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 285 { 286 const rr::FragmentPacket& packet = packets[packetNdx]; 287 288 for (int fragNdx = 0; fragNdx < 4; fragNdx++) 289 { 290 const tcu::Vec4 vtxTexCoord = rr::readVarying<float>(packet, context, 1, fragNdx); 291 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, vtxTexCoord); 292 } 293 } 294 } 295 }; 296 297 class Program 298 { 299 public: ~Program(void)300 virtual ~Program (void) { } 301 302 virtual rr::Program getReferenceProgram (void) const = 0; 303 }; 304 305 class CoordinateCaptureProgram : public Program 306 { 307 private: 308 TexCoordVertexShader m_vertexShader; 309 CoordinateCaptureFragmentShader m_fragmentShader; 310 public: CoordinateCaptureProgram(void)311 CoordinateCaptureProgram (void) 312 { 313 } 314 ~CoordinateCaptureProgram(void)315 virtual ~CoordinateCaptureProgram (void) { } 316 getReferenceProgram(void) const317 virtual rr::Program getReferenceProgram (void) const 318 { 319 return rr::Program(&m_vertexShader, &m_fragmentShader); 320 } 321 }; 322 323 class ReferenceRenderer 324 { 325 public: 326 ReferenceRenderer (int surfaceWidth, 327 int surfaceHeight, 328 int numSamples, 329 const tcu::TextureFormat& colorFormat, 330 const tcu::TextureFormat& depthStencilFormat, 331 const rr::Program* const program); 332 333 virtual ~ReferenceRenderer (void); 334 335 void colorClear (const tcu::Vec4& color); 336 337 void draw (const rr::RenderState& renderState, 338 const rr::PrimitiveType primitive, 339 const std::vector<Vertex4RGBA>& vertexBuffer); 340 341 void draw (const rr::RenderState& renderState, 342 const rr::PrimitiveType primitive, 343 const std::vector<Vertex4RGBARGBA>& vertexBuffer); 344 345 void draw (const rr::RenderState& renderState, 346 const rr::PrimitiveType primitive, 347 const std::vector<Vertex4Tex4>& vertexBuffer); 348 349 tcu::PixelBufferAccess getAccess (void); 350 tcu::PixelBufferAccess getDepthStencilAccess (void); 351 const rr::ViewportState getViewportState (void) const; 352 353 private: 354 rr::Renderer m_renderer; 355 356 const int m_surfaceWidth; 357 const int m_surfaceHeight; 358 const int m_numSamples; 359 360 const tcu::TextureFormat m_colorFormat; 361 const tcu::TextureFormat m_depthStencilFormat; 362 363 tcu::TextureLevel m_colorBuffer; 364 tcu::TextureLevel m_resolveColorBuffer; 365 tcu::TextureLevel m_depthStencilBuffer; 366 tcu::TextureLevel m_resolveDepthStencilBuffer; 367 368 rr::RenderTarget* m_renderTarget; 369 const rr::Program* m_program; 370 }; 371 372 rr::TestFunc mapVkCompareOp (vk::VkCompareOp compareFunc); 373 rr::PrimitiveType mapVkPrimitiveTopology (vk::VkPrimitiveTopology primitiveTopology); 374 rr::BlendFunc mapVkBlendFactor (vk::VkBlendFactor blendFactor); 375 rr::BlendEquation mapVkBlendOp (vk::VkBlendOp blendOp); 376 tcu::BVec4 mapVkColorComponentFlags (vk::VkColorComponentFlags flags); 377 rr::StencilOp mapVkStencilOp (vk::VkStencilOp stencilOp); 378 379 } // pipeline 380 } // vkt 381 382 #endif // _VKTPIPELINEREFERENCERENDERER_HPP 383