m_vertexAttributeDescription.clear();
m_vertexBuffers.clear();
m_vertexBufferAllocs.clear();
+ m_pushConstantRanges.clear();
}
void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, size_t size, const void* dataPtr)
createSamplerUniform(bindingLocation, textureType, textureBinding.getParameters().initialization, texFormat, texSize, textureData, refSampler, mipLevels, arrayLayers, textureParams);
}
+void ShaderRenderCaseInstance::setPushConstantRanges (const deUint32 rangeCount, const vk::VkPushConstantRange* const pcRanges)
+{
+ m_pushConstantRanges.clear();
+ for (deUint32 i = 0; i < rangeCount; ++i)
+ {
+ m_pushConstantRanges.push_back(pcRanges[i]);
+ }
+}
+
+void ShaderRenderCaseInstance::updatePushConstants (vk::VkCommandBuffer, vk::VkPipelineLayout)
+{
+}
+
void ShaderRenderCaseInstance::createSamplerUniform (deUint32 bindingLocation,
TextureBinding::Type textureType,
TextureBinding::Init textureInit,
deUint32 numTriangles,
const deUint16* indices,
const tcu::Vec4& constCoords)
+{
+ render(numVertices, numTriangles * 3, indices, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, constCoords);
+}
+
+void ShaderRenderCaseInstance::render (deUint32 numVertices,
+ deUint32 numIndices,
+ const deUint16* indices,
+ VkPrimitiveTopology topology,
+ const tcu::Vec4& constCoords)
{
const VkDevice vkDevice = getDevice();
const DeviceInterface& vk = getDeviceInterface();
vk::Move<vk::VkPipeline> graphicsPipeline;
vk::Move<vk::VkShaderModule> vertexShaderModule;
vk::Move<vk::VkShaderModule> fragmentShaderModule;
- vk::Move<vk::VkBuffer> indiceBuffer;
- de::MovePtr<vk::Allocation> indiceBufferAlloc;
+ vk::Move<vk::VkBuffer> indexBuffer;
+ de::MovePtr<vk::Allocation> indexBufferAlloc;
vk::Move<vk::VkDescriptorSetLayout> descriptorSetLayout;
vk::Move<vk::VkDescriptorPool> descriptorPool;
vk::Move<vk::VkDescriptorSet> descriptorSet;
// Create pipeline layout
{
+ const VkPushConstantRange* const pcRanges = m_pushConstantRanges.empty() ? DE_NULL : &m_pushConstantRanges[0];
const VkPipelineLayoutCreateInfo pipelineLayoutParams =
{
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
(VkPipelineLayoutCreateFlags)0,
1u, // deUint32 descriptorSetCount;
&*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
- 0u, // deUint32 pushConstantRangeCount;
- DE_NULL // const VkPushConstantRange* pPushConstantRanges;
+ deUint32(m_pushConstantRanges.size()), // deUint32 pushConstantRangeCount;
+ pcRanges // const VkPushConstantRange* pPushConstantRanges;
};
pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkPipelineInputAssemblyStateCreateFlags)0,
- VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
+ topology, // VkPrimitiveTopology topology;
false // VkBool32 primitiveRestartEnable;
};
}
// Create vertex indices buffer
+ if (numIndices != 0)
{
- const VkDeviceSize indiceBufferSize = numTriangles * 3 * sizeof(deUint16);
- const VkBufferCreateInfo indiceBufferParams =
+ const VkDeviceSize indexBufferSize = numIndices * sizeof(deUint16);
+ const VkBufferCreateInfo indexBufferParams =
{
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkBufferCreateFlags flags;
- indiceBufferSize, // VkDeviceSize size;
+ indexBufferSize, // VkDeviceSize size;
VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage;
VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1u, // deUint32 queueFamilyCount;
&queueFamilyIndex // const deUint32* pQueueFamilyIndices;
};
- indiceBuffer = createBuffer(vk, vkDevice, &indiceBufferParams);
- indiceBufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *indiceBuffer), MemoryRequirement::HostVisible);
+ indexBuffer = createBuffer(vk, vkDevice, &indexBufferParams);
+ indexBufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *indexBuffer), MemoryRequirement::HostVisible);
- VK_CHECK(vk.bindBufferMemory(vkDevice, *indiceBuffer, indiceBufferAlloc->getMemory(), indiceBufferAlloc->getOffset()));
+ VK_CHECK(vk.bindBufferMemory(vkDevice, *indexBuffer, indexBufferAlloc->getMemory(), indexBufferAlloc->getOffset()));
// Load vertice indices into buffer
- deMemcpy(indiceBufferAlloc->getHostPtr(), indices, (size_t)indiceBufferSize);
- flushMappedMemoryRange(vk, vkDevice, indiceBufferAlloc->getMemory(), indiceBufferAlloc->getOffset(), indiceBufferSize);
+ deMemcpy(indexBufferAlloc->getHostPtr(), indices, (size_t)indexBufferSize);
+ flushMappedMemoryRange(vk, vkDevice, indexBufferAlloc->getMemory(), indexBufferAlloc->getOffset(), indexBufferSize);
}
// Create command pool
}
vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
-
+ updatePushConstants(*cmdBuffer, *pipelineLayout);
vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
if (!m_uniformInfos.empty())
vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &*descriptorSet, 0u, DE_NULL);
- vk.cmdBindIndexBuffer(*cmdBuffer, *indiceBuffer, 0, VK_INDEX_TYPE_UINT16);
const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
}
vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
- vk.cmdDrawIndexed(*cmdBuffer, numTriangles * 3, 1, 0, 0, 0);
+ if (numIndices != 0)
+ {
+ vk.cmdBindIndexBuffer(*cmdBuffer, *indexBuffer, 0, VK_INDEX_TYPE_UINT16);
+ vk.cmdDrawIndexed(*cmdBuffer, numIndices, 1, 0, 0, 0);
+ }
+ else
+ vk.cmdDraw(*cmdBuffer, numVertices, 1, 0, 1);
vk.cmdEndRenderPass(*cmdBuffer);
VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
#include "tcuStringTemplate.hpp"
#include "tcuTextureUtil.hpp"
+#include "deMath.h"
+#include "deRandom.hpp"
+
+#include <map>
+
using namespace std;
using namespace tcu;
using namespace vk;
-1.0f, 1.0f, 0.0f, 1.0f
};
- addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)sizeof(float) * 4, 6, vertices);
+ addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, vertices);
}
class BuiltinGlFrontFacingCase : public TestCase
return new BuiltinGlFrontFacingCaseInstance(context);
}
+class BuiltinGlFragCoordXYZCaseInstance : public ShaderRenderCaseInstance
+{
+public:
+ BuiltinGlFragCoordXYZCaseInstance (Context& context);
+
+ TestStatus iterate (void);
+ virtual void setupDefaultInputs (void);
+};
+
+BuiltinGlFragCoordXYZCaseInstance::BuiltinGlFragCoordXYZCaseInstance (Context& context)
+ : ShaderRenderCaseInstance (context)
+{
+}
+
+TestStatus BuiltinGlFragCoordXYZCaseInstance::iterate (void)
+{
+ const UVec2 viewportSize = getViewportSize();
+ const int width = viewportSize.x();
+ const int height = viewportSize.y();
+ const tcu::Vec3 scale (1.f / float(width), 1.f / float(height), 1.0f);
+ const tcu::RGBA threshold (2, 2, 2, 2);
+ Surface resImage (width, height);
+ Surface refImage (width, height);
+ bool compareOk = false;
+ const deUint16 indices[6] =
+ {
+ 2, 1, 3,
+ 0, 1, 2,
+ };
+
+ setup();
+ addUniform(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, scale);
+
+ render(4, 2, indices);
+ copy(resImage.getAccess(), getResultImage().getAccess());
+
+ // Reference image
+ for (int y = 0; y < refImage.getHeight(); y++)
+ {
+ for (int x = 0; x < refImage.getWidth(); x++)
+ {
+ const float xf = (float(x)+.5f) / float(refImage.getWidth());
+ const float yf = (float(refImage.getHeight()-y-1)+.5f) / float(refImage.getHeight());
+ const float z = (xf + yf) / 2.0f;
+ const Vec3 fragCoord (float(x)+.5f, float(y)+.5f, z);
+ const Vec3 scaledFC = fragCoord*scale;
+ const Vec4 color (scaledFC.x(), scaledFC.y(), scaledFC.z(), 1.0f);
+
+ refImage.setPixel(x, y, RGBA(color));
+ }
+ }
+
+ compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
+
+ if (compareOk)
+ return TestStatus::pass("Result image matches reference");
+ else
+ return TestStatus::fail("Image mismatch");
+}
+
+void BuiltinGlFragCoordXYZCaseInstance::setupDefaultInputs (void)
+{
+ const float vertices[] =
+ {
+ -1.0f, 1.0f, 0.0f, 1.0f,
+ -1.0f, -1.0f, 0.5f, 1.0f,
+ 1.0f, 1.0f, 0.5f, 1.0f,
+ 1.0f, -1.0f, 1.0f, 1.0f,
+ };
+
+ addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
+}
+
+class BuiltinGlFragCoordXYZCase : public TestCase
+{
+public:
+ BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name, const string& description);
+ virtual ~BuiltinGlFragCoordXYZCase (void);
+
+ void initPrograms (SourceCollections& dst) const;
+ TestInstance* createInstance (Context& context) const;
+
+private:
+ BuiltinGlFragCoordXYZCase (const BuiltinGlFragCoordXYZCase&); // not allowed!
+ BuiltinGlFragCoordXYZCase& operator= (const BuiltinGlFragCoordXYZCase&); // not allowed!
+};
+
+BuiltinGlFragCoordXYZCase::BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name, const string& description)
+ : TestCase(testCtx, name, description)
+{
+}
+
+BuiltinGlFragCoordXYZCase::~BuiltinGlFragCoordXYZCase (void)
+{
+}
+
+void BuiltinGlFragCoordXYZCase::initPrograms (SourceCollections& dst) const
+{
+ dst.glslSources.add("vert") << glu::VertexSource(
+ "#version 310 es\n"
+ "layout(location = 0) in highp vec4 a_position;\n"
+ "void main (void)\n"
+ "{\n"
+ " gl_Position = a_position;\n"
+ "}\n");
+
+ dst.glslSources.add("frag") << glu::FragmentSource(
+ "#version 310 es\n"
+ "layout(set=0, binding=0) uniform Scale { highp vec3 u_scale; };\n"
+ "layout(location = 0) out highp vec4 o_color;\n"
+ "void main (void)\n"
+ "{\n"
+ " o_color = vec4(gl_FragCoord.xyz * u_scale, 1.0);\n"
+ "}\n");
+}
+
+TestInstance* BuiltinGlFragCoordXYZCase::createInstance (Context& context) const
+{
+ return new BuiltinGlFragCoordXYZCaseInstance(context);
+}
+
+inline float projectedTriInterpolate (const Vec3& s, const Vec3& w, float nx, float ny)
+{
+ return (s[0]*(1.0f-nx-ny)/w[0] + s[1]*ny/w[1] + s[2]*nx/w[2]) / ((1.0f-nx-ny)/w[0] + ny/w[1] + nx/w[2]);
+}
+
+class BuiltinGlFragCoordWCaseInstance : public ShaderRenderCaseInstance
+{
+public:
+ BuiltinGlFragCoordWCaseInstance (Context& context);
+
+ TestStatus iterate (void);
+ virtual void setupDefaultInputs (void);
+
+private:
+
+ const Vec4 m_w;
+
+};
+
+BuiltinGlFragCoordWCaseInstance::BuiltinGlFragCoordWCaseInstance (Context& context)
+ : ShaderRenderCaseInstance (context)
+ , m_w (1.7f, 2.0f, 1.2f, 1.0f)
+{
+}
+
+TestStatus BuiltinGlFragCoordWCaseInstance::iterate (void)
+{
+ const UVec2 viewportSize = getViewportSize();
+ const int width = viewportSize.x();
+ const int height = viewportSize.y();
+ const tcu::RGBA threshold (2, 2, 2, 2);
+ Surface resImage (width, height);
+ Surface refImage (width, height);
+ bool compareOk = false;
+ const deUint16 indices[6] =
+ {
+ 2, 1, 3,
+ 0, 1, 2,
+ };
+
+ setup();
+ render(4, 2, indices);
+ copy(resImage.getAccess(), getResultImage().getAccess());
+
+ // Reference image
+ for (int y = 0; y < refImage.getHeight(); y++)
+ {
+ for (int x = 0; x < refImage.getWidth(); x++)
+ {
+ const float xf = (float(x)+.5f) / float(refImage.getWidth());
+ const float yf = (float(refImage.getHeight()-y-1)+.5f) / float(refImage.getHeight());
+ const float oow = ((xf + yf) < 1.0f)
+ ? projectedTriInterpolate(Vec3(m_w[0], m_w[1], m_w[2]), Vec3(m_w[0], m_w[1], m_w[2]), xf, yf)
+ : projectedTriInterpolate(Vec3(m_w[3], m_w[2], m_w[1]), Vec3(m_w[3], m_w[2], m_w[1]), 1.0f-xf, 1.0f-yf);
+ const Vec4 color (0.0f, oow - 1.0f, 0.0f, 1.0f);
+
+ refImage.setPixel(x, y, RGBA(color));
+ }
+ }
+
+ compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
+
+ if (compareOk)
+ return TestStatus::pass("Result image matches reference");
+ else
+ return TestStatus::fail("Image mismatch");
+}
+
+void BuiltinGlFragCoordWCaseInstance::setupDefaultInputs (void)
+{
+ const float vertices[] =
+ {
+ -m_w[0], m_w[0], 0.0f, m_w[0],
+ -m_w[1], -m_w[1], 0.0f, m_w[1],
+ m_w[2], m_w[2], 0.0f, m_w[2],
+ m_w[3], -m_w[3], 0.0f, m_w[3]
+ };
+
+ addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
+}
+
+class BuiltinGlFragCoordWCase : public TestCase
+{
+public:
+ BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name, const string& description);
+ virtual ~BuiltinGlFragCoordWCase (void);
+
+ void initPrograms (SourceCollections& dst) const;
+ TestInstance* createInstance (Context& context) const;
+
+private:
+ BuiltinGlFragCoordWCase (const BuiltinGlFragCoordWCase&); // not allowed!
+ BuiltinGlFragCoordWCase& operator= (const BuiltinGlFragCoordWCase&); // not allowed!
+};
+
+BuiltinGlFragCoordWCase::BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name, const string& description)
+ : TestCase(testCtx, name, description)
+{
+}
+
+BuiltinGlFragCoordWCase::~BuiltinGlFragCoordWCase (void)
+{
+}
+
+void BuiltinGlFragCoordWCase::initPrograms (SourceCollections& dst) const
+{
+ dst.glslSources.add("vert") << glu::VertexSource(
+ "#version 310 es\n"
+ "layout(location = 0) in highp vec4 a_position;\n"
+ "void main (void)\n"
+ "{\n"
+ " gl_Position = a_position;\n"
+ "}\n");
+
+ dst.glslSources.add("frag") << glu::FragmentSource(
+ "#version 310 es\n"
+ "layout(location = 0) out highp vec4 o_color;\n"
+ "void main (void)\n"
+ "{\n"
+ " o_color = vec4(0.0, 1.0 / gl_FragCoord.w - 1.0, 0.0, 1.0);\n"
+ "}\n");
+}
+
+TestInstance* BuiltinGlFragCoordWCase::createInstance (Context& context) const
+{
+ return new BuiltinGlFragCoordWCaseInstance(context);
+}
+
+class BuiltinGlPointCoordCaseInstance : public ShaderRenderCaseInstance
+{
+public:
+ BuiltinGlPointCoordCaseInstance (Context& context);
+
+ TestStatus iterate (void);
+ virtual void setupDefaultInputs (void);
+};
+
+BuiltinGlPointCoordCaseInstance::BuiltinGlPointCoordCaseInstance (Context& context)
+ : ShaderRenderCaseInstance (context)
+{
+}
+
+TestStatus BuiltinGlPointCoordCaseInstance::iterate (void)
+{
+ const UVec2 viewportSize = getViewportSize();
+ const int width = viewportSize.x();
+ const int height = viewportSize.y();
+ const float threshold = 0.02f;
+ const int numPoints = 16;
+ vector<Vec3> coords (numPoints);
+ de::Random rnd (0x145fa);
+ Surface resImage (width, height);
+ Surface refImage (width, height);
+ bool compareOk = false;
+ VkPhysicalDeviceLimits limits = m_context.getDeviceProperties().limits;
+
+ // Compute coordinates.
+ {
+ for (vector<Vec3>::iterator coord = coords.begin(); coord != coords.end(); ++coord)
+ {
+ coord->x() = rnd.getFloat(-0.9f, 0.9f);
+ coord->y() = rnd.getFloat(-0.9f, 0.9f);
+ coord->z() = limits.pointSizeRange[0] + float(rnd.getInt(0, int((limits.pointSizeRange[1] - limits.pointSizeRange[0]) / limits.pointSizeGranularity))) * limits.pointSizeGranularity;
+ }
+ }
+
+ setup();
+ addAttribute(0u, VK_FORMAT_R32G32B32_SFLOAT, deUint32(sizeof(Vec3)), numPoints, &coords[0]);
+ render(numPoints, 0, DE_NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
+ copy(resImage.getAccess(), getResultImage().getAccess());
+
+ // Draw reference
+ clear(refImage.getAccess(), m_clearColor);
+ for (vector<Vec3>::const_iterator pointIter = coords.begin(); pointIter != coords.end(); ++pointIter)
+ {
+ const int x0 = deRoundFloatToInt32(float(width) *(pointIter->x()*0.5f + 0.5f) - pointIter->z()*0.5f);
+ const int y0 = deRoundFloatToInt32(float(height)*(pointIter->y()*0.5f + 0.5f) - pointIter->z()*0.5f);
+ const int x1 = deRoundFloatToInt32(float(width) *(pointIter->x()*0.5f + 0.5f) + pointIter->z()*0.5f);
+ const int y1 = deRoundFloatToInt32(float(height)*(pointIter->y()*0.5f + 0.5f) + pointIter->z()*0.5f);
+ const int w = x1-x0;
+ const int h = y1-y0;
+
+ for (int yo = 0; yo < h; yo++)
+ {
+ for (int xo = 0; xo < w; xo++)
+ {
+ const float xf = (float(xo)+0.5f) / float(w);
+ const float yf = (float(yo)+0.5f) / float(h);
+ const Vec4 color (xf, yf, 0.0f, 1.0f);
+ const int dx = x0+xo;
+ const int dy = y0+yo;
+
+ if (de::inBounds(dx, 0, refImage.getWidth()) && de::inBounds(dy, 0, refImage.getHeight()))
+ refImage.setPixel(dx, dy, RGBA(color));
+ }
+ }
+ }
+
+ compareOk = fuzzyCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
+
+ if (compareOk)
+ return TestStatus::pass("Result image matches reference");
+ else
+ return TestStatus::fail("Image mismatch");
+}
+
+void BuiltinGlPointCoordCaseInstance::setupDefaultInputs (void)
+{
+}
+
+class BuiltinGlPointCoordCase : public TestCase
+{
+public:
+ BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description);
+ virtual ~BuiltinGlPointCoordCase (void);
+
+ void initPrograms (SourceCollections& dst) const;
+ TestInstance* createInstance (Context& context) const;
+
+private:
+ BuiltinGlPointCoordCase (const BuiltinGlPointCoordCase&); // not allowed!
+ BuiltinGlPointCoordCase& operator= (const BuiltinGlPointCoordCase&); // not allowed!
+};
+
+BuiltinGlPointCoordCase::BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description)
+ : TestCase(testCtx, name, description)
+{
+}
+
+BuiltinGlPointCoordCase::~BuiltinGlPointCoordCase (void)
+{
+}
+
+void BuiltinGlPointCoordCase::initPrograms (SourceCollections& dst) const
+{
+ dst.glslSources.add("vert") << glu::VertexSource(
+ "#version 310 es\n"
+ "layout(location = 0) in highp vec3 a_position;\n"
+ "void main (void)\n"
+ "{\n"
+ " gl_Position = vec4(a_position.xy, 0.0, 1.0);\n"
+ " gl_PointSize = a_position.z;\n"
+ "}\n");
+
+ dst.glslSources.add("frag") << glu::FragmentSource(
+ "#version 310 es\n"
+ "layout(location = 0) out lowp vec4 o_color;\n"
+ "void main (void)\n"
+ "{\n"
+ " o_color = vec4(gl_PointCoord, 0.0, 1.0);\n"
+ "}\n");
+}
+
+TestInstance* BuiltinGlPointCoordCase::createInstance (Context& context) const
+{
+ return new BuiltinGlPointCoordCaseInstance(context);
+}
+
+enum ShaderInputTypeBits
+{
+ SHADER_INPUT_BUILTIN_BIT = 0x01,
+ SHADER_INPUT_VARYING_BIT = 0x02,
+ SHADER_INPUT_CONSTANT_BIT = 0x04
+};
+
+typedef deUint16 ShaderInputTypes;
+
+string shaderInputTypeToString (ShaderInputTypes type)
+{
+ string typeString = "input";
+
+ if (type == 0)
+ return "input_none";
+
+ if (type & SHADER_INPUT_BUILTIN_BIT)
+ typeString += "_builtin";
+
+ if (type & SHADER_INPUT_VARYING_BIT)
+ typeString += "_varying";
+
+ if (type & SHADER_INPUT_CONSTANT_BIT)
+ typeString += "_constant";
+
+ return typeString;
+}
+
+class BuiltinInputVariationsCaseInstance : public ShaderRenderCaseInstance
+{
+public:
+ BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes);
+
+ TestStatus iterate (void);
+ virtual void setupDefaultInputs (void);
+ virtual void updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout);
+
+private:
+ const ShaderInputTypes m_shaderInputTypes;
+ const Vec4 m_constantColor;
+};
+
+BuiltinInputVariationsCaseInstance::BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes)
+ : ShaderRenderCaseInstance (context)
+ , m_shaderInputTypes (shaderInputTypes)
+ , m_constantColor (0.1f, 0.05f, 0.2f, 0.0f)
+{
+}
+
+TestStatus BuiltinInputVariationsCaseInstance::iterate (void)
+{
+ const UVec2 viewportSize = getViewportSize();
+ const int width = viewportSize.x();
+ const int height = viewportSize.y();
+ const tcu::RGBA threshold (2, 2, 2, 2);
+ Surface resImage (width, height);
+ Surface refImage (width, height);
+ bool compareOk = false;
+ const VkPushConstantRange pcRanges =
+ {
+ VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
+ 0u, // deUint32 offset;
+ sizeof(Vec4) // deUint32 size;
+ };
+ const deUint16 indices[12] =
+ {
+ 0, 4, 1,
+ 0, 5, 4,
+ 1, 2, 3,
+ 1, 3, 4
+ };
+
+ setup();
+
+ if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
+ setPushConstantRanges(1, &pcRanges);
+
+ render(6, 4, indices);
+ copy(resImage.getAccess(), getResultImage().getAccess());
+
+ // Reference image
+ for (int y = 0; y < refImage.getHeight(); y++)
+ {
+ for (int x = 0; x < refImage.getWidth(); x++)
+ {
+ Vec4 color (0.1f, 0.2f, 0.3f, 1.0f);
+
+ if (((m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT) && (x < refImage.getWidth() / 2)) ||
+ !(m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT))
+ {
+ if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
+ {
+ const float xf = (float(x)+.5f) / float(refImage.getWidth());
+ color += Vec4(0.6f * (1 - xf), 0.6f * xf, 0.0f, 0.0f);
+ }
+ else
+ color += Vec4(0.3f, 0.2f, 0.1f, 0.0f);
+ }
+
+ if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
+ color += m_constantColor;
+
+ refImage.setPixel(x, y, RGBA(color));
+ }
+ }
+
+ compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
+
+ if (compareOk)
+ return TestStatus::pass("Result image matches reference");
+ else
+ return TestStatus::fail("Image mismatch");
+}
+
+void BuiltinInputVariationsCaseInstance::setupDefaultInputs (void)
+{
+ const float vertices[] =
+ {
+ -1.0f, -1.0f, 0.0f, 1.0f,
+ 0.0f, -1.0f, 0.0f, 1.0f,
+ 1.0f, -1.0f, 0.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f,
+ 0.0f, 1.0f, 0.0f, 1.0f,
+ -1.0f, 1.0f, 0.0f, 1.0f
+ };
+
+ addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, vertices);
+
+ if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
+ {
+ const float colors[] =
+ {
+ 0.6f, 0.0f, 0.0f, 1.0f,
+ 0.3f, 0.3f, 0.0f, 1.0f,
+ 0.0f, 0.6f, 0.0f, 1.0f,
+ 0.0f, 0.6f, 0.0f, 1.0f,
+ 0.3f, 0.3f, 0.0f, 1.0f,
+ 0.6f, 0.0f, 0.0f, 1.0f
+ };
+ addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, colors);
+ }
+}
+
+void BuiltinInputVariationsCaseInstance::updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout)
+{
+ if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
+ {
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ vk.cmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4), &m_constantColor);
+ }
+}
+
+class BuiltinInputVariationsCase : public TestCase
+{
+public:
+ BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const string& description, const ShaderInputTypes shaderInputTypes);
+ virtual ~BuiltinInputVariationsCase (void);
+
+ void initPrograms (SourceCollections& dst) const;
+ TestInstance* createInstance (Context& context) const;
+
+private:
+ BuiltinInputVariationsCase (const BuiltinInputVariationsCase&); // not allowed!
+ BuiltinInputVariationsCase& operator= (const BuiltinInputVariationsCase&); // not allowed!
+ const ShaderInputTypes m_shaderInputTypes;
+};
+
+BuiltinInputVariationsCase::BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const string& description, ShaderInputTypes shaderInputTypes)
+ : TestCase (testCtx, name, description)
+ , m_shaderInputTypes (shaderInputTypes)
+{
+}
+
+BuiltinInputVariationsCase::~BuiltinInputVariationsCase (void)
+{
+}
+
+void BuiltinInputVariationsCase::initPrograms (SourceCollections& dst) const
+{
+ map<string, string> vertexParams;
+ map<string, string> fragmentParams;
+ const tcu::StringTemplate vertexCodeTemplate (
+ "#version 450\n"
+ "layout(location = 0) in highp vec4 a_position;\n"
+ "out gl_PerVertex {\n"
+ " vec4 gl_Position;\n"
+ "};\n"
+ "${VARYING_DECL}"
+ "void main (void)\n"
+ "{\n"
+ " gl_Position = a_position;\n"
+ " ${VARYING_USAGE}"
+ "}\n");
+
+ const tcu::StringTemplate fragmentCodeTemplate (
+ "#version 450\n"
+ "${VARYING_DECL}"
+ "${CONSTANT_DECL}"
+ "layout(location = 0) out highp vec4 o_color;\n"
+ "void main (void)\n"
+ "{\n"
+ " o_color = vec4(0.1, 0.2, 0.3, 1.0);\n"
+ " ${BUILTIN_USAGE}"
+ " ${VARYING_USAGE}"
+ " ${CONSTANT_USAGE}"
+ "}\n");
+
+ vertexParams["VARYING_DECL"] =
+ m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "layout(location = 1) in highp vec4 a_color;\n"
+ "layout(location = 0) out highp vec4 v_color;\n"
+ : "";
+
+ vertexParams["VARYING_USAGE"] =
+ m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "v_color = a_color;\n"
+ : "";
+
+ fragmentParams["VARYING_DECL"] =
+ m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "layout(location = 0) in highp vec4 a_color;\n"
+ : "";
+
+ fragmentParams["CONSTANT_DECL"] =
+ m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT ? "layout(push_constant) uniform PCBlock {\n"
+ " vec4 color;\n"
+ "} pc;\n"
+ : "";
+
+ fragmentParams["BUILTIN_USAGE"] =
+ m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT ? "if (gl_FrontFacing)\n"
+ : "";
+
+ fragmentParams["VARYING_USAGE"] =
+ m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "o_color += vec4(a_color.xyz, 0.0);\n"
+ : "o_color += vec4(0.3, 0.2, 0.1, 0.0);\n";
+
+
+ fragmentParams["CONSTANT_USAGE"] =
+ m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT ? "o_color += pc.color;\n"
+ : "";
+
+ dst.glslSources.add("vert") << glu::VertexSource(vertexCodeTemplate.specialize(vertexParams));
+ dst.glslSources.add("frag") << glu::FragmentSource(fragmentCodeTemplate.specialize(fragmentParams));
+}
+
+TestInstance* BuiltinInputVariationsCase::createInstance (Context& context) const
+{
+ return new BuiltinInputVariationsCaseInstance(context, m_shaderInputTypes);
+}
+
} // anonymous
TestCaseGroup* createBuiltinVarTests (TestContext& testCtx)
{
- de::MovePtr<TestCaseGroup> varyingGroup(new TestCaseGroup(testCtx, "builtin_var", "Shader builtin variable tests."));
+ de::MovePtr<TestCaseGroup> builtinGroup (new TestCaseGroup(testCtx, "builtin_var", "Shader builtin variable tests."));
+ de::MovePtr<TestCaseGroup> simpleGroup (new TestCaseGroup(testCtx, "simple", "Simple cases."));
+ de::MovePtr<TestCaseGroup> inputVariationsGroup (new TestCaseGroup(testCtx, "input_variations", "Input type variation tests."));
+
+ simpleGroup->addChild(new BuiltinGlFrontFacingCase(testCtx, "frontfacing", "FrontFacing test"));
+ simpleGroup->addChild(new BuiltinGlFragCoordXYZCase(testCtx, "fragcoord_xyz", "FragCoord xyz test"));
+ simpleGroup->addChild(new BuiltinGlFragCoordWCase(testCtx, "fragcoord_w", "FragCoord w test"));
+ simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord", "PointCoord test"));
+
+ builtinGroup->addChild(simpleGroup.release());
- varyingGroup->addChild(new BuiltinGlFrontFacingCase(testCtx, "gl_frontfacing", "gl_FrontFacing test"));
+ for (deUint16 shaderType = 0; shaderType <= (SHADER_INPUT_BUILTIN_BIT | SHADER_INPUT_VARYING_BIT | SHADER_INPUT_CONSTANT_BIT); ++shaderType)
+ {
+ inputVariationsGroup->addChild(new BuiltinInputVariationsCase(testCtx, shaderInputTypeToString(shaderType), "Input variation test", shaderType));
+ }
- return varyingGroup.release();
+ builtinGroup->addChild(inputVariationsGroup.release());
+ return builtinGroup.release();
}
} // sr