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 TexCoordVertexShader : public rr::VertexShader 81 { 82 public: TexCoordVertexShader(void)83 TexCoordVertexShader (void) : rr::VertexShader(2, 2) 84 { 85 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 86 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 87 88 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; 89 m_outputs[1].type = rr::GENERICVECTYPE_FLOAT; 90 } 91 ~TexCoordVertexShader(void)92 virtual ~TexCoordVertexShader (void) {} 93 shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const94 virtual void shadeVertices (const rr::VertexAttrib* inputs, 95 rr::VertexPacket* const* packets, 96 const int numPackets) const 97 { 98 tcu::Vec4 position; 99 tcu::Vec4 texCoord; 100 101 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 102 { 103 rr::VertexPacket* const packet = packets[packetNdx]; 104 105 readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx); 106 readVertexAttrib(texCoord, inputs[1], packet->instanceNdx, packet->vertexNdx); 107 108 packet->outputs[0] = position; 109 packet->outputs[1] = texCoord; 110 packet->position = position; 111 } 112 } 113 }; 114 115 class ColorFragmentShader : public rr::FragmentShader 116 { 117 private: 118 const tcu::TextureFormat m_colorFormat; 119 const tcu::TextureFormat m_depthStencilFormat; 120 121 public: ColorFragmentShader(const tcu::TextureFormat & colorFormat,const tcu::TextureFormat & depthStencilFormat)122 ColorFragmentShader (const tcu::TextureFormat& colorFormat, 123 const tcu::TextureFormat& depthStencilFormat) 124 : rr::FragmentShader (2, 1) 125 , m_colorFormat (colorFormat) 126 , m_depthStencilFormat (depthStencilFormat) 127 { 128 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(m_colorFormat.type); 129 130 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 131 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 132 m_outputs[0].type = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)? rr::GENERICVECTYPE_INT32 : 133 (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)? rr::GENERICVECTYPE_UINT32 134 : rr::GENERICVECTYPE_FLOAT; 135 } 136 ~ColorFragmentShader(void)137 virtual ~ColorFragmentShader (void) {} 138 shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const139 virtual void shadeFragments (rr::FragmentPacket* packets, 140 const int numPackets, 141 const rr::FragmentShadingContext& context) const 142 { 143 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 144 { 145 const rr::FragmentPacket& packet = packets[packetNdx]; 146 147 if (m_depthStencilFormat.order == tcu::TextureFormat::D || m_depthStencilFormat.order == tcu::TextureFormat::DS) 148 { 149 for (int fragNdx = 0; fragNdx < 4; fragNdx++) 150 { 151 const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx); 152 rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z()); 153 } 154 } 155 156 for (int fragNdx = 0; fragNdx < 4; fragNdx++) 157 { 158 const tcu::Vec4 vtxColor = rr::readVarying<float>(packet, context, 1, fragNdx); 159 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, vtxColor); 160 } 161 } 162 } 163 }; 164 165 template<typename TextureType> 166 class SamplerFragmentShader : public rr::FragmentShader 167 { 168 private: 169 const tcu::TextureFormat m_colorFormat; 170 const tcu::TextureFormatInfo m_colorFormatInfo; 171 const TextureType m_texture; 172 const tcu::Sampler m_sampler; 173 const float m_lod; 174 const tcu::Vec4 m_lookupScale; 175 const tcu::Vec4 m_lookupBias; 176 const tcu::UVec4 m_swizzle; 177 178 public: SamplerFragmentShader(const tcu::TextureFormat & colorFormat,const TextureType & texture,const tcu::Sampler & sampler,float lod,const tcu::Vec4 & lookupScale,const tcu::Vec4 & lookupBias,const tcu::UVec4 & swizzle)179 SamplerFragmentShader (const tcu::TextureFormat& colorFormat, const TextureType& texture, const tcu::Sampler& sampler, float lod, const tcu::Vec4& lookupScale, const tcu::Vec4& lookupBias, const tcu::UVec4& swizzle) 180 : rr::FragmentShader (2, 1) 181 , m_colorFormat (colorFormat) 182 , m_colorFormatInfo (tcu::getTextureFormatInfo(m_colorFormat)) 183 , m_texture (texture) 184 , m_sampler (sampler) 185 , m_lod (lod) 186 , m_lookupScale (lookupScale) 187 , m_lookupBias (lookupBias) 188 , m_swizzle (swizzle) 189 { 190 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(m_colorFormat.type); 191 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 192 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 193 m_outputs[0].type = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)? rr::GENERICVECTYPE_INT32 : 194 (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)? rr::GENERICVECTYPE_UINT32 195 : rr::GENERICVECTYPE_FLOAT; 196 } 197 ~SamplerFragmentShader(void)198 virtual ~SamplerFragmentShader (void) 199 { 200 } 201 sampleTexture(const tcu::Texture1D & texture,const tcu::Sampler & sampler,const tcu::Vec4 & texCoord,float lod)202 static tcu::Vec4 sampleTexture (const tcu::Texture1D& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod) 203 { 204 return texture.sample(sampler, texCoord.x(), lod); 205 } 206 sampleTexture(const tcu::Texture1DArray & texture,const tcu::Sampler & sampler,const tcu::Vec4 & texCoord,float lod)207 static tcu::Vec4 sampleTexture (const tcu::Texture1DArray& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod) 208 { 209 return texture.sample(sampler, texCoord.x(), texCoord.y(), lod); 210 } 211 sampleTexture(const tcu::Texture2D & texture,const tcu::Sampler & sampler,const tcu::Vec4 & texCoord,float lod)212 static tcu::Vec4 sampleTexture (const tcu::Texture2D& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod) 213 { 214 return texture.sample(sampler, texCoord.x(), texCoord.y(), lod); 215 } 216 sampleTexture(const tcu::Texture2DArray & texture,const tcu::Sampler & sampler,const tcu::Vec4 & texCoord,float lod)217 static tcu::Vec4 sampleTexture (const tcu::Texture2DArray& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod) 218 { 219 return texture.sample(sampler, texCoord.x(), texCoord.y(), texCoord.z(), lod); 220 } 221 sampleTexture(const tcu::Texture3D & texture,const tcu::Sampler & sampler,const tcu::Vec4 & texCoord,float lod)222 static tcu::Vec4 sampleTexture (const tcu::Texture3D& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod) 223 { 224 return texture.sample(sampler, texCoord.x(), texCoord.y(), texCoord.z(), lod); 225 } 226 sampleTexture(const tcu::TextureCube & texture,const tcu::Sampler & sampler,const tcu::Vec4 & texCoord,float lod)227 static tcu::Vec4 sampleTexture (const tcu::TextureCube& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod) 228 { 229 return texture.sample(sampler, texCoord.x(), texCoord.y(), texCoord.z(), lod); 230 } 231 sampleTexture(const tcu::TextureCubeArray & texture,const tcu::Sampler & sampler,const tcu::Vec4 & texCoord,float lod)232 static tcu::Vec4 sampleTexture (const tcu::TextureCubeArray& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod) 233 { 234 return texture.sample(sampler, texCoord.x(), texCoord.y(), texCoord.z(), texCoord.w(), lod); 235 } 236 shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const237 virtual void shadeFragments (rr::FragmentPacket* packets, 238 const int numPackets, 239 const rr::FragmentShadingContext& context) const 240 { 241 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 242 { 243 const rr::FragmentPacket& packet = packets[packetNdx]; 244 245 for (int fragNdx = 0; fragNdx < 4; fragNdx++) 246 { 247 const tcu::Vec4 vtxTexCoord = rr::readVarying<float>(packet, context, 1, fragNdx); 248 const tcu::Vec4 texColor = sampleTexture(m_texture, m_sampler, vtxTexCoord, m_lod); 249 const tcu::Vec4 normColor = texColor * m_lookupScale + m_lookupBias; 250 const tcu::Vec4 swizColor = swizzle(normColor, m_swizzle); 251 const tcu::Vec4 color = (swizColor + m_colorFormatInfo.lookupBias) / m_colorFormatInfo.lookupScale; 252 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color); 253 } 254 } 255 } 256 }; 257 258 class Program 259 { 260 public: ~Program(void)261 virtual ~Program (void) { } 262 263 virtual rr::Program getReferenceProgram (void) const = 0; 264 }; 265 266 template<typename TextureType> 267 class SamplerProgram: public Program 268 { 269 private: 270 TexCoordVertexShader m_vertexShader; 271 SamplerFragmentShader<TextureType> m_fragmentShader; 272 public: SamplerProgram(const tcu::TextureFormat & colorFormat,const TextureType & texture,const tcu::Sampler & sampler,float lod,const tcu::Vec4 & lookupScale,const tcu::Vec4 & lookupBias,const tcu::UVec4 & swizzle)273 SamplerProgram (const tcu::TextureFormat& colorFormat, const TextureType& texture, const tcu::Sampler& sampler, float lod, const tcu::Vec4& lookupScale, const tcu::Vec4& lookupBias, const tcu::UVec4& swizzle) 274 : m_vertexShader () 275 , m_fragmentShader (colorFormat, texture, sampler, lod, lookupScale, lookupBias, swizzle) 276 { 277 } 278 ~SamplerProgram(void)279 virtual ~SamplerProgram (void) { } 280 getReferenceProgram(void) const281 virtual rr::Program getReferenceProgram (void) const 282 { 283 return rr::Program(&m_vertexShader, &m_fragmentShader); 284 } 285 }; 286 287 class ReferenceRenderer 288 { 289 public: 290 ReferenceRenderer (int surfaceWidth, 291 int surfaceHeight, 292 int numSamples, 293 const tcu::TextureFormat& colorFormat, 294 const tcu::TextureFormat& depthStencilFormat, 295 const rr::Program* const program); 296 297 virtual ~ReferenceRenderer (void); 298 299 void colorClear (const tcu::Vec4& color); 300 301 void draw (const rr::RenderState& renderState, 302 const rr::PrimitiveType primitive, 303 const std::vector<Vertex4RGBA>& vertexBuffer); 304 305 void draw (const rr::RenderState& renderState, 306 const rr::PrimitiveType primitive, 307 const std::vector<Vertex4Tex4>& vertexBuffer); 308 309 tcu::PixelBufferAccess getAccess (void); 310 const rr::ViewportState getViewportState (void) const; 311 312 private: 313 rr::Renderer m_renderer; 314 315 const int m_surfaceWidth; 316 const int m_surfaceHeight; 317 const int m_numSamples; 318 319 const tcu::TextureFormat m_colorFormat; 320 const tcu::TextureFormat m_depthStencilFormat; 321 322 tcu::TextureLevel m_colorBuffer; 323 tcu::TextureLevel m_resolveColorBuffer; 324 tcu::TextureLevel m_depthStencilBuffer; 325 326 rr::RenderTarget* m_renderTarget; 327 const rr::Program* m_program; 328 }; 329 330 rr::TestFunc mapVkCompareOp (vk::VkCompareOp compareFunc); 331 rr::PrimitiveType mapVkPrimitiveTopology (vk::VkPrimitiveTopology primitiveTopology); 332 rr::BlendFunc mapVkBlendFactor (vk::VkBlendFactor blendFactor); 333 rr::BlendEquation mapVkBlendOp (vk::VkBlendOp blendOp); 334 tcu::BVec4 mapVkColorComponentFlags (vk::VkColorComponentFlags flags); 335 rr::StencilOp mapVkStencilOp (vk::VkStencilOp stencilOp); 336 337 } // pipeline 338 } // vkt 339 340 #endif // _VKTPIPELINEREFERENCERENDERER_HPP 341