* \brief Vulkan ShaderRenderCase
*//*--------------------------------------------------------------------*/
-#ifndef _VKTSHADERRENDERCASE_HPP
-
#include "vktShaderRenderCase.hpp"
+#include "tcuImageCompare.hpp"
#include "tcuSurface.hpp"
#include "tcuVector.hpp"
#include "tcuTestLog.hpp"
+#include "deMath.h"
+
#include <vector>
#include <string>
using namespace std;
using namespace tcu;
+
+static const int GRID_SIZE = 64;
+static const int MAX_RENDER_WIDTH = 128;
+static const int MAX_RENDER_HEIGHT = 112;
+static const tcu::Vec4 DEFAULT_CLEAR_COLOR = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f);
+
// QuadGrid.
class QuadGrid
*/
}
+ShaderEvalContext::~ShaderEvalContext (void)
+{
+}
+
void ShaderEvalContext::reset (float sx, float sy)
{
// Clear old values
tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords)
{
- if (textures[unitNdx].tex2D)
+ // TODO: add texture binding
+/* if (textures[unitNdx].tex2D)
return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f);
else
+*/
return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
}
void ShaderRenderCase::initPrograms (vk::ProgramCollection<glu::ProgramSources>& programCollection) const
{
- // TODO??
+ if (!m_vertShaderSource.empty())
+ programCollection.add(m_name + "_vert") << glu::VertexSource(m_vertShaderSource);
+
+ if (!m_fragShaderSource.empty())
+ programCollection.add(m_name + "_frag") << glu::FragmentSource(m_fragShaderSource);
}
TestInstance* ShaderRenderCase::createInstance (Context& context) const
{
- return new ShaderRenderCaseInstance(context, m_isVertexCase, *m_evaluator);
+ return new ShaderRenderCaseInstance(context, m_name, m_isVertexCase, *m_evaluator);
}
// ShaderRenderCaseInstance.
-ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context, bool isVertexCase, ShaderEvaluator& evaluator)
+ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context, const string& name, bool isVertexCase, ShaderEvaluator& evaluator)
: vkt::TestInstance(context)
+ , m_name(name)
, m_isVertexCase(isVertexCase)
, m_evaluator(evaluator)
+ , m_clearColor(DEFAULT_CLEAR_COLOR)
+ , m_renderSize(100, 100)
+ , m_colorFormat(vk::VK_FORMAT_R8G8B8A8_UNORM)
{
}
tcu::TestStatus ShaderRenderCaseInstance::iterate (void)
{
- return tcu::TestStatus::pass("Dummy test ok");
+ // Create quad grid.
+ IVec2 viewportSize = getViewportSize();
+ int width = viewportSize.x();
+ int height = viewportSize.y();
+
+ QuadGrid quadGrid(m_isVertexCase ? GRID_SIZE : 4, width, height, Vec4(0.125f, 0.25f, 0.5f, 1.0f), m_userAttribTransforms/*, m_textures*/);
+
+ // Render result.
+ Surface resImage(width, height);
+ render(resImage, quadGrid);
+
+ // Compute reference.
+ Surface refImage(width, height);
+ if (m_isVertexCase)
+ computeVertexReference(refImage, quadGrid);
+ else
+ computeFragmentReference(refImage, quadGrid);
+
+ //m_context.getTestContext().getLog() << TestLog::Image("Result", "Result", refImage.getAccess());
+/*tcu::ConstPixelBufferAccess(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), m_renderSize.x(), m_renderSize.y(), 1, imagePtr)*/
+
+ // Compare.
+ bool compareOk = compareImages(resImage, refImage, 0.05f);
+
+ if (compareOk)
+ return tcu::TestStatus::pass("Result image matches reference");
+ else
+ return tcu::TestStatus::fail("Image mismatch");
+}
+
+void ShaderRenderCaseInstance::setupShaderData (void)
+{
+ // TODO!!!
+}
+
+void ShaderRenderCaseInstance::setup (void)
+{
+ // TODO!!
+}
+
+void ShaderRenderCaseInstance::setupUniforms (const Vec4& constCoords)
+{
+ // TODO!!
+ DE_UNREF(constCoords);
+}
+
+tcu::IVec2 ShaderRenderCaseInstance::getViewportSize (void) const
+{
+ return tcu::IVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH),
+ de::min(m_renderSize.y(), MAX_RENDER_HEIGHT));
+}
+
+void ShaderRenderCaseInstance::setupDefaultInputs (void)
+{
+ // TODO!!
+ // SetupUniforms: map unifrom ids and set the values
}
+void ShaderRenderCaseInstance::render (Surface& result, const QuadGrid& quadGrid)
+{
+ // TODO!! Vk rendering
+}
+
+void ShaderRenderCaseInstance::computeVertexReference (Surface& result, const QuadGrid& quadGrid)
+{
+ // TODO!!
+ // Buffer info.
+ int width = result.getWidth();
+ int height = result.getHeight();
+ int gridSize = quadGrid.getGridSize();
+ int stride = gridSize + 1;
+ //bool hasAlpha = m_context.getRenderTarget().getPixelFormat().alphaBits > 0;
+ bool hasAlpha = true;
+ ShaderEvalContext evalCtx (quadGrid);
+
+ // Evaluate color for each vertex.
+ vector<Vec4> colors((gridSize+1)*(gridSize+1));
+ for (int y = 0; y < gridSize+1; y++)
+ for (int x = 0; x < gridSize+1; x++)
+ {
+ float sx = (float)x / (float)gridSize;
+ float sy = (float)y / (float)gridSize;
+ int vtxNdx = ((y * (gridSize+1)) + x);
+
+ evalCtx.reset(sx, sy);
+ m_evaluator.evaluate(evalCtx);
+ DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader.
+ Vec4 color = evalCtx.color;
+
+ if (!hasAlpha)
+ color.w() = 1.0f;
+
+ colors[vtxNdx] = color;
+ }
+
+ // Render quads.
+ for (int y = 0; y < gridSize; y++)
+ for (int x = 0; x < gridSize; x++)
+ {
+ float x0 = (float)x / (float)gridSize;
+ float x1 = (float)(x + 1) / (float)gridSize;
+ float y0 = (float)y / (float)gridSize;
+ float y1 = (float)(y + 1) / (float)gridSize;
+
+ float sx0 = x0 * (float)width;
+ float sx1 = x1 * (float)width;
+ float sy0 = y0 * (float)height;
+ float sy1 = y1 * (float)height;
+ float oosx = 1.0f / (sx1 - sx0);
+ float oosy = 1.0f / (sy1 - sy0);
+
+ int ix0 = deCeilFloatToInt32(sx0 - 0.5f);
+ int ix1 = deCeilFloatToInt32(sx1 - 0.5f);
+ int iy0 = deCeilFloatToInt32(sy0 - 0.5f);
+ int iy1 = deCeilFloatToInt32(sy1 - 0.5f);
+
+ int v00 = (y * stride) + x;
+ int v01 = (y * stride) + x + 1;
+ int v10 = ((y + 1) * stride) + x;
+ int v11 = ((y + 1) * stride) + x + 1;
+ Vec4 c00 = colors[v00];
+ Vec4 c01 = colors[v01];
+ Vec4 c10 = colors[v10];
+ Vec4 c11 = colors[v11];
+
+ //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1);
+
+ for (int iy = iy0; iy < iy1; iy++)
+ for (int ix = ix0; ix < ix1; ix++)
+ {
+ DE_ASSERT(deInBounds32(ix, 0, width));
+ DE_ASSERT(deInBounds32(iy, 0, height));
+
+ float sfx = (float)ix + 0.5f;
+ float sfy = (float)iy + 0.5f;
+ float fx1 = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f);
+ float fy1 = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f);
+
+ // Triangle quad interpolation.
+ bool tri = fx1 + fy1 <= 1.0f;
+ float tx = tri ? fx1 : (1.0f-fx1);
+ float ty = tri ? fy1 : (1.0f-fy1);
+ const Vec4& t0 = tri ? c00 : c11;
+ const Vec4& t1 = tri ? c01 : c10;
+ const Vec4& t2 = tri ? c10 : c01;
+ Vec4 color = t0 + (t1-t0)*tx + (t2-t0)*ty;
+
+ result.setPixel(ix, iy, tcu::RGBA(color));
+ }
+ }
+}
+
+void ShaderRenderCaseInstance::computeFragmentReference (Surface& result, const QuadGrid& quadGrid)
+{
+ // Buffer info.
+ int width = result.getWidth();
+ int height = result.getHeight();
+ //bool hasAlpha = m_renderCtx.getRenderTarget().getPixelFormat().alphaBits > 0;
+ bool hasAlpha = true;
+ ShaderEvalContext evalCtx (quadGrid);
+
+ // Render.
+ for (int y = 0; y < height; y++)
+ for (int x = 0; x < width; x++)
+ {
+ float sx = ((float)x + 0.5f) / (float)width;
+ float sy = ((float)y + 0.5f) / (float)height;
+
+ evalCtx.reset(sx, sy);
+ m_evaluator.evaluate(evalCtx);
+ // Select either clear color or computed color based on discarded bit.
+ Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color;
+
+ if (!hasAlpha)
+ color.w() = 1.0f;
+
+ result.setPixel(x, y, tcu::RGBA(color));
+ }
+}
+
+bool ShaderRenderCaseInstance::compareImages (const Surface& resImage, const Surface& refImage, float errorThreshold)
+{
+ return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_RESULT);
+}
+
+
} // shaderrendercase
} // vkt
-
-#endif // _VKTSHADERRENDERCASE_HPP
+#ifndef _VKTSHADERRENDERCASE_HPP
+#define _VKTSHADERRENDERCASE_HPP
/*------------------------------------------------------------------------
* Copyright (c) 2015 The Khronos Group Inc.
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
* \brief Vulkan ShaderRenderCase
*//*--------------------------------------------------------------------*/
-#ifndef _VKTSHADERRENDERCASE_HPP
-
#include "tcuTexture.hpp"
-
-#include "vktTestCase.hpp"
+#include "tcuSurface.hpp"
+
+#include "vktTestCaseUtil.hpp"
+
+#include "vkDefs.hpp"
+/*#include "vkPlatform.hpp"
+#include "vkStrUtil.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkMemUtil.hpp"
+#include "vkDeviceUtil.hpp"*/
#include "vkPrograms.hpp"
namespace vkt
virtual void initPrograms (vk::ProgramCollection<glu::ProgramSources>& programCollection) const;
virtual TestInstance* createInstance (Context& context) const;
+protected:
+ std::string m_vertShaderSource;
+ std::string m_fragShaderSource;
+
private:
bool m_isVertexCase;
ShaderEvaluator* m_evaluator;
+
};
// ShaderRenderCaseInstance.
class ShaderRenderCaseInstance : public vkt::TestInstance
{
public:
- ShaderRenderCaseInstance (Context& context, bool isVertexCase, ShaderEvaluator& evaluator);
+ ShaderRenderCaseInstance (Context& context, const std::string& name, bool isVertexCase, ShaderEvaluator& evaluator);
virtual ~ShaderRenderCaseInstance (void);
virtual tcu::TestStatus iterate (void);
+protected:
+ virtual void setupShaderData (void);
+ virtual void setup (void);
+ virtual void setupUniforms (const tcu::Vec4& constCoords);
+
+ tcu::IVec2 getViewportSize (void) const;
+
+ std::vector<tcu::Mat4> m_userAttribTransforms;
+ tcu::Vec4 m_clearColor;
+
private:
- bool m_isVertexCase;
- ShaderEvaluator& m_evaluator;
+
+ void setupDefaultInputs (void);
+
+ void render (tcu::Surface& result, const QuadGrid& quadGrid);
+ void computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid);
+ void computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid);
+ bool compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold);
+
+ std::string m_name;
+ bool m_isVertexCase;
+ ShaderEvaluator& m_evaluator;
+
+ const tcu::IVec2 m_renderSize;
+ const vk::VkFormat m_colorFormat;
+
};