blob: 219340d0fc16954a59ad2a764eb1c7cc1fe8f0a7 [file] [log] [blame]
#ifndef _VKTPIPELINEREFERENCERENDERER_HPP
#define _VKTPIPELINEREFERENCERENDERER_HPP
/*------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2015 The Khronos Group Inc.
* Copyright (c) 2015 Imagination Technologies Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file
* \brief Reference renderer.
*//*--------------------------------------------------------------------*/
#include "vkDefs.hpp"
#include "vktPipelineVertexUtil.hpp"
#include "tcuVector.hpp"
#include "tcuVectorType.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "rrRenderState.hpp"
#include "rrRenderer.hpp"
#include <cstring>
namespace vkt
{
namespace pipeline
{
tcu::Vec4 swizzle(const tcu::Vec4 &color, const tcu::UVec4 &swizzle);
class ColorVertexShader : public rr::VertexShader
{
public:
ColorVertexShader(void) : rr::VertexShader(2, 2)
{
m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
m_inputs[1].type = rr::GENERICVECTYPE_FLOAT;
m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
m_outputs[1].type = rr::GENERICVECTYPE_FLOAT;
}
virtual ~ColorVertexShader(void)
{
}
virtual void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets,
const int numPackets) const
{
tcu::Vec4 position;
tcu::Vec4 color;
for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
{
rr::VertexPacket *const packet = packets[packetNdx];
readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx);
readVertexAttrib(color, inputs[1], packet->instanceNdx, packet->vertexNdx);
packet->outputs[0] = position;
packet->outputs[1] = color;
packet->position = position;
}
}
};
class ColorVertexShaderDualSource : public rr::VertexShader
{
public:
ColorVertexShaderDualSource(void) : rr::VertexShader(3, 3)
{
m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
m_inputs[1].type = rr::GENERICVECTYPE_FLOAT;
m_inputs[2].type = rr::GENERICVECTYPE_FLOAT;
m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
m_outputs[1].type = rr::GENERICVECTYPE_FLOAT;
m_outputs[2].type = rr::GENERICVECTYPE_FLOAT;
}
virtual ~ColorVertexShaderDualSource(void)
{
}
virtual void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets,
const int numPackets) const
{
tcu::Vec4 position;
tcu::Vec4 color0;
tcu::Vec4 color1;
for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
{
rr::VertexPacket *const packet = packets[packetNdx];
readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx);
readVertexAttrib(color0, inputs[1], packet->instanceNdx, packet->vertexNdx);
readVertexAttrib(color1, inputs[2], packet->instanceNdx, packet->vertexNdx);
packet->outputs[0] = position;
packet->outputs[1] = color0;
packet->outputs[2] = color1;
packet->position = position;
}
}
};
class TexCoordVertexShader : public rr::VertexShader
{
public:
TexCoordVertexShader(void) : rr::VertexShader(2, 2)
{
m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
m_inputs[1].type = rr::GENERICVECTYPE_FLOAT;
m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
m_outputs[1].type = rr::GENERICVECTYPE_FLOAT;
}
virtual ~TexCoordVertexShader(void)
{
}
virtual void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets,
const int numPackets) const
{
tcu::Vec4 position;
tcu::Vec4 texCoord;
for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
{
rr::VertexPacket *const packet = packets[packetNdx];
readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx);
readVertexAttrib(texCoord, inputs[1], packet->instanceNdx, packet->vertexNdx);
packet->outputs[0] = position;
packet->outputs[1] = texCoord;
packet->position = position;
}
}
};
class ColorFragmentShader : public rr::FragmentShader
{
private:
const tcu::TextureFormat m_colorFormat;
const tcu::TextureFormat m_depthStencilFormat;
public:
ColorFragmentShader(const tcu::TextureFormat &colorFormat, const tcu::TextureFormat &depthStencilFormat)
: rr::FragmentShader(2, 1)
, m_colorFormat(colorFormat)
, m_depthStencilFormat(depthStencilFormat)
{
const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(m_colorFormat.type);
m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
m_inputs[1].type = rr::GENERICVECTYPE_FLOAT;
m_outputs[0].type = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) ? rr::GENERICVECTYPE_INT32 :
(channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) ? rr::GENERICVECTYPE_UINT32 :
rr::GENERICVECTYPE_FLOAT;
}
virtual ~ColorFragmentShader(void)
{
}
virtual void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
const rr::FragmentShadingContext &context) const
{
for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
{
const rr::FragmentPacket &packet = packets[packetNdx];
if (m_depthStencilFormat.order == tcu::TextureFormat::D ||
m_depthStencilFormat.order == tcu::TextureFormat::DS)
{
for (int fragNdx = 0; fragNdx < 4; fragNdx++)
{
const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx);
rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z());
}
}
for (int fragNdx = 0; fragNdx < 4; fragNdx++)
{
const tcu::Vec4 vtxColor = rr::readVarying<float>(packet, context, 1, fragNdx);
rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, vtxColor);
}
}
}
};
class ColorFragmentShaderDualSource : public rr::FragmentShader
{
private:
const tcu::TextureFormat m_colorFormat;
const tcu::TextureFormat m_depthStencilFormat;
public:
ColorFragmentShaderDualSource(const tcu::TextureFormat &colorFormat, const tcu::TextureFormat &depthStencilFormat)
: rr::FragmentShader(3, 1)
, m_colorFormat(colorFormat)
, m_depthStencilFormat(depthStencilFormat)
{
const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(m_colorFormat.type);
m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
m_inputs[1].type = rr::GENERICVECTYPE_FLOAT;
m_inputs[2].type = rr::GENERICVECTYPE_FLOAT;
m_outputs[0].type = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) ? rr::GENERICVECTYPE_INT32 :
(channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) ? rr::GENERICVECTYPE_UINT32 :
rr::GENERICVECTYPE_FLOAT;
}
virtual ~ColorFragmentShaderDualSource(void)
{
}
virtual void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
const rr::FragmentShadingContext &context) const
{
for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
{
const rr::FragmentPacket &packet = packets[packetNdx];
if (m_depthStencilFormat.order == tcu::TextureFormat::D ||
m_depthStencilFormat.order == tcu::TextureFormat::DS)
{
for (int fragNdx = 0; fragNdx < 4; fragNdx++)
{
const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx);
rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z());
}
}
for (int fragNdx = 0; fragNdx < 4; fragNdx++)
{
const tcu::Vec4 vtxColor0 = rr::readVarying<float>(packet, context, 1, fragNdx);
const tcu::Vec4 vtxColor1 = rr::readVarying<float>(packet, context, 2, fragNdx);
rr::writeFragmentOutputDualSource(context, packetNdx, fragNdx, 0, vtxColor0, vtxColor1);
}
}
}
};
class CoordinateCaptureFragmentShader : public rr::FragmentShader
{
public:
CoordinateCaptureFragmentShader(void) : rr::FragmentShader(2, 1)
{
m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
m_inputs[1].type = rr::GENERICVECTYPE_FLOAT;
m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
}
virtual ~CoordinateCaptureFragmentShader(void)
{
}
virtual void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
const rr::FragmentShadingContext &context) const
{
for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
{
const rr::FragmentPacket &packet = packets[packetNdx];
for (int fragNdx = 0; fragNdx < 4; fragNdx++)
{
const tcu::Vec4 vtxTexCoord = rr::readVarying<float>(packet, context, 1, fragNdx);
rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, vtxTexCoord);
}
}
}
};
class Program
{
public:
virtual ~Program(void)
{
}
virtual rr::Program getReferenceProgram(void) const = 0;
};
class CoordinateCaptureProgram : public Program
{
private:
TexCoordVertexShader m_vertexShader;
CoordinateCaptureFragmentShader m_fragmentShader;
public:
CoordinateCaptureProgram(void)
{
}
virtual ~CoordinateCaptureProgram(void)
{
}
virtual rr::Program getReferenceProgram(void) const
{
return rr::Program(&m_vertexShader, &m_fragmentShader);
}
};
class ReferenceRenderer
{
public:
ReferenceRenderer(int surfaceWidth, int surfaceHeight, int numSamples, const tcu::TextureFormat &colorFormat,
const tcu::TextureFormat &depthStencilFormat, const rr::Program *const program);
virtual ~ReferenceRenderer(void);
void colorClear(const tcu::Vec4 &color);
void draw(const rr::RenderState &renderState, const rr::PrimitiveType primitive,
const std::vector<Vertex4RGBA> &vertexBuffer);
void draw(const rr::RenderState &renderState, const rr::PrimitiveType primitive,
const std::vector<Vertex4RGBARGBA> &vertexBuffer);
void draw(const rr::RenderState &renderState, const rr::PrimitiveType primitive,
const std::vector<Vertex4Tex4> &vertexBuffer);
tcu::PixelBufferAccess getAccess(void);
tcu::PixelBufferAccess getDepthStencilAccess(void);
const rr::ViewportState getViewportState(void) const;
private:
rr::Renderer m_renderer;
const int m_surfaceWidth;
const int m_surfaceHeight;
const int m_numSamples;
const tcu::TextureFormat m_colorFormat;
const tcu::TextureFormat m_depthStencilFormat;
tcu::TextureLevel m_colorBuffer;
tcu::TextureLevel m_resolveColorBuffer;
tcu::TextureLevel m_depthStencilBuffer;
tcu::TextureLevel m_resolveDepthStencilBuffer;
rr::RenderTarget *m_renderTarget;
const rr::Program *m_program;
};
rr::TestFunc mapVkCompareOp(vk::VkCompareOp compareFunc);
rr::PrimitiveType mapVkPrimitiveTopology(vk::VkPrimitiveTopology primitiveTopology);
rr::BlendFunc mapVkBlendFactor(vk::VkBlendFactor blendFactor);
rr::BlendEquation mapVkBlendOp(vk::VkBlendOp blendOp);
tcu::BVec4 mapVkColorComponentFlags(vk::VkColorComponentFlags flags);
rr::StencilOp mapVkStencilOp(vk::VkStencilOp stencilOp);
} // namespace pipeline
} // namespace vkt
#endif // _VKTPIPELINEREFERENCERENDERER_HPP