#include "deSharedPtr.hpp"
+#include <utility>
+#include <array>
+#include <vector>
+#include <iterator>
+
namespace vkt
{
namespace Draw
float maxDepth;
};
+constexpr deUint32 kImageDim = 256u;
+const VkExtent3D kImageExtent = makeExtent3D(kImageDim, kImageDim, 1u);
+const Vec4 kClearColor (0.0f, 0.0f, 0.0f, 1.0f);
+constexpr float kClearDepth = 1.0f;
+constexpr int kClearStencil = 0;
+constexpr int kMaskedStencil = 1;
+constexpr float kDepthEpsilon = 0.00025f; // Used to decide if a calculated depth passes the depth test.
+constexpr float kDepthThreshold = 0.0025f; // Used when checking depth buffer values. Less than depth delta in each pixel (~= 1.4/205).
+constexpr float kMargin = 0.2f; // Space between triangle and image border. See kVertices.
+constexpr float kDiagonalMargin = 0.00125f; // Makes sure the image diagonal falls inside the triangle. See kVertices.
+const Vec4 kVertexColor (0.0f, 0.5f, 0.5f, 1.0f); // Note: the first component will vary.
+const std::array<Vec4, 3u> kVertices =
+{{
+ Vec4(-1.0f + kMargin, -1.0f + kMargin, -0.2f, 1.0f), // 0-----2
+ Vec4(-1.0f + kMargin, 1.0f - kMargin + kDiagonalMargin, 0.0f, 1.0f), // | /
+ Vec4( 1.0f - kMargin + kDiagonalMargin, -1.0f + kMargin, 1.2f, 1.0f), // 1|/
+}};
+
+
class InvertedDepthRangesTestInstance : public TestInstance
{
public:
- InvertedDepthRangesTestInstance (Context& context, const TestParams& params);
- tcu::TestStatus iterate (void);
- tcu::ConstPixelBufferAccess draw (const VkViewport viewport);
- MovePtr<tcu::TextureLevel> generateReferenceImage (void) const;
+ enum class ReferenceImageType
+ {
+ COLOR = 0,
+ DEPTH,
+ };
+
+ using ColorAndDepth = std::pair<tcu::ConstPixelBufferAccess, tcu::ConstPixelBufferAccess>;
+
+ InvertedDepthRangesTestInstance (Context& context, const TestParams& params);
+ tcu::TestStatus iterate (void);
+ ColorAndDepth draw (const VkViewport viewport);
+ MovePtr<tcu::TextureLevel> generateReferenceImage (ReferenceImageType refType) const;
private:
const TestParams m_params;
const VkFormat m_colorAttachmentFormat;
+ const VkFormat m_depthAttachmentFormat;
SharedPtr<Image> m_colorTargetImage;
Move<VkImageView> m_colorTargetView;
+ SharedPtr<Image> m_depthTargetImage;
+ Move<VkImageView> m_depthTargetView;
SharedPtr<Buffer> m_vertexBuffer;
Move<VkRenderPass> m_renderPass;
Move<VkFramebuffer> m_framebuffer;
: TestInstance (context)
, m_params (params)
, m_colorAttachmentFormat (VK_FORMAT_R8G8B8A8_UNORM)
+ , m_depthAttachmentFormat (VK_FORMAT_D16_UNORM)
{
const DeviceInterface& vk = m_context.getDeviceInterface();
const VkDevice device = m_context.getDevice();
+ auto& alloc = m_context.getDefaultAllocator();
+ auto qIndex = m_context.getUniversalQueueFamilyIndex();
// Vertex data
{
- std::vector<Vec4> vertexData;
-
- vertexData.push_back(Vec4(-0.8f, -0.8f, -0.2f, 1.0f)); // 0-----2
- vertexData.push_back(Vec4(-0.8f, 0.8f, 0.0f, 1.0f)); // | /
- vertexData.push_back(Vec4( 0.8f, -0.8f, 1.2f, 1.0f)); // 1|/
-
- const VkDeviceSize dataSize = vertexData.size() * sizeof(Vec4);
+ const auto dataSize = static_cast<VkDeviceSize>(kVertices.size() * sizeof(decltype(kVertices)::value_type));
m_vertexBuffer = Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
- m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
+ alloc, MemoryRequirement::HostVisible);
- deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), &vertexData[0], static_cast<std::size_t>(dataSize));
+ deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), kVertices.data(), static_cast<size_t>(dataSize));
flushMappedMemoryRange(vk, device, m_vertexBuffer->getBoundMemory().getMemory(), m_vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
}
// Render pass
{
- const VkExtent3D targetImageExtent = { 256, 256, 1 };
const VkImageUsageFlags targetImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+ const VkImageUsageFlags depthTargeUsageFlags = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
const ImageCreateInfo targetImageCreateInfo(
VK_IMAGE_TYPE_2D, // imageType,
m_colorAttachmentFormat, // format,
- targetImageExtent, // extent,
+ kImageExtent, // extent,
1u, // mipLevels,
1u, // arrayLayers,
VK_SAMPLE_COUNT_1_BIT, // samples,
VK_IMAGE_TILING_OPTIMAL, // tiling,
targetImageUsageFlags); // usage,
- m_colorTargetImage = Image::createAndAlloc(vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
+ m_colorTargetImage = Image::createAndAlloc(vk, device, targetImageCreateInfo, alloc, qIndex);
+
+ const ImageCreateInfo depthTargetImageCreateInfo(
+ VK_IMAGE_TYPE_2D, // imageType,
+ m_depthAttachmentFormat, // format,
+ kImageExtent, // extent,
+ 1u, // mipLevels,
+ 1u, // arrayLayers,
+ VK_SAMPLE_COUNT_1_BIT, // samples,
+ VK_IMAGE_TILING_OPTIMAL, // tiling,
+ depthTargeUsageFlags); // usage,
+
+ m_depthTargetImage = Image::createAndAlloc(vk, device, depthTargetImageCreateInfo, alloc, qIndex);
RenderPassCreateInfo renderPassCreateInfo;
renderPassCreateInfo.addAttachment(AttachmentDescription(
VK_IMAGE_LAYOUT_GENERAL, // initialLayout
VK_IMAGE_LAYOUT_GENERAL)); // finalLayout
+ renderPassCreateInfo.addAttachment(AttachmentDescription(
+ m_depthAttachmentFormat, // format
+ VK_SAMPLE_COUNT_1_BIT, // samples
+ VK_ATTACHMENT_LOAD_OP_LOAD, // loadOp
+ VK_ATTACHMENT_STORE_OP_STORE, // storeOp
+ VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
+ VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
+ VK_IMAGE_LAYOUT_GENERAL, // initialLayout
+ VK_IMAGE_LAYOUT_GENERAL)); // finalLayout
+
const VkAttachmentReference colorAttachmentReference =
{
0u,
VK_IMAGE_LAYOUT_GENERAL
};
+ const VkAttachmentReference depthAttachmentReference =
+ {
+ 1u,
+ VK_IMAGE_LAYOUT_GENERAL
+ };
+
renderPassCreateInfo.addSubpass(SubpassDescription(
VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
(VkSubpassDescriptionFlags)0, // flags
1u, // colorAttachmentCount
&colorAttachmentReference, // colorAttachments
DE_NULL, // resolveAttachments
- AttachmentReference(), // depthStencilAttachment
+ depthAttachmentReference, // depthStencilAttachment
0u, // preserveAttachmentCount
DE_NULL)); // preserveAttachments
const ImageViewCreateInfo colorTargetViewInfo (m_colorTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
m_colorTargetView = createImageView(vk, device, &colorTargetViewInfo);
- std::vector<VkImageView> colorAttachments(1);
- colorAttachments[0] = *m_colorTargetView;
+ const ImageViewCreateInfo depthTargetViewInfo (m_depthTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, m_depthAttachmentFormat);
+ m_depthTargetView = createImageView(vk, device, &depthTargetViewInfo);
+
+ std::vector<VkImageView> fbAttachments(2);
+ fbAttachments[0] = *m_colorTargetView;
+ fbAttachments[1] = *m_depthTargetView;
- const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, colorAttachments, 256, 256, 1);
+ const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, fbAttachments, kImageExtent.width, kImageExtent.height, 1u);
m_framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
}
// Graphics pipeline
- const VkRect2D scissor = makeRect2D(256u, 256u);
+ const auto scissor = makeRect2D(kImageExtent);
std::vector<VkDynamicState> dynamicStates;
dynamicStates.push_back(VK_DYNAMIC_STATE_VIEWPORT);
pipelineCreateInfo.addState (PipelineCreateInfo::InputAssemblerState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
pipelineCreateInfo.addState (PipelineCreateInfo::ColorBlendState (1, &colorBlendAttachmentState));
pipelineCreateInfo.addState (PipelineCreateInfo::ViewportState (1, std::vector<VkViewport>(), std::vector<VkRect2D>(1, scissor)));
- pipelineCreateInfo.addState (PipelineCreateInfo::DepthStencilState ());
+ pipelineCreateInfo.addState (PipelineCreateInfo::DepthStencilState (true, true));
pipelineCreateInfo.addState (PipelineCreateInfo::RasterizerState (
m_params.depthClampEnable, // depthClampEnable
VK_FALSE, // rasterizerDiscardEnable
m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
}
-tcu::ConstPixelBufferAccess InvertedDepthRangesTestInstance::draw (const VkViewport viewport)
+InvertedDepthRangesTestInstance::ColorAndDepth InvertedDepthRangesTestInstance::draw (const VkViewport viewport)
{
const DeviceInterface& vk = m_context.getDeviceInterface();
const VkDevice device = m_context.getDevice();
const VkQueue queue = m_context.getUniversalQueue();
const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
+ auto& alloc = m_context.getDefaultAllocator();
// Command buffer
vk.cmdSetViewport(*cmdBuffer, 0u, 1u, &viewport);
{
- const VkClearColorValue clearColor = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f).color;
- const ImageSubresourceRange subresourceRange (VK_IMAGE_ASPECT_COLOR_BIT);
+ const VkClearColorValue clearColor = makeClearValueColor(kClearColor).color;
+ const ImageSubresourceRange subresourceRange (VK_IMAGE_ASPECT_COLOR_BIT);
+
+ const VkClearDepthStencilValue clearDepth = makeClearValueDepthStencil(kClearDepth, 0u).depthStencil;
+ const ImageSubresourceRange depthSubresourceRange (VK_IMAGE_ASPECT_DEPTH_BIT);
initialTransitionColor2DImage(vk, *cmdBuffer, m_colorTargetImage->object(), VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+ initialTransitionDepth2DImage(vk, *cmdBuffer, m_depthTargetImage->object(), VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
vk.cmdClearColorImage(*cmdBuffer, m_colorTargetImage->object(), VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRange);
+ vk.cmdClearDepthStencilImage(*cmdBuffer, m_depthTargetImage->object(), VK_IMAGE_LAYOUT_GENERAL, &clearDepth, 1u, &depthSubresourceRange);
}
{
const VkMemoryBarrier memBarrier =
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT // VkAccessFlags dstAccessMask;
};
+ const VkMemoryBarrier depthBarrier =
+ {
+ VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT // VkAccessFlags dstAccessMask;
+ };
+
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
+ vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT), 0, 1, &depthBarrier, 0, DE_NULL, 0, DE_NULL);
}
- beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, 256u, 256u));
+ beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(kImageExtent));
{
const VkDeviceSize offset = 0;
// Get result
{
- const VkOffset3D zeroOffset = { 0, 0, 0 };
- return m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), VK_IMAGE_LAYOUT_GENERAL, zeroOffset, 256, 256, VK_IMAGE_ASPECT_COLOR_BIT);
+ const auto zeroOffset = makeOffset3D(0, 0, 0);
+ const auto iWidth = static_cast<int>(kImageExtent.width);
+ const auto iHeight = static_cast<int>(kImageExtent.height);
+ const auto colorPixels = m_colorTargetImage->readSurface(queue, alloc, VK_IMAGE_LAYOUT_GENERAL, zeroOffset, iWidth, iHeight, VK_IMAGE_ASPECT_COLOR_BIT);
+ const auto depthPixels = m_depthTargetImage->readSurface(queue, alloc, VK_IMAGE_LAYOUT_GENERAL, zeroOffset, iWidth, iHeight, VK_IMAGE_ASPECT_DEPTH_BIT);
+
+ return ColorAndDepth(colorPixels, depthPixels);
}
}
-MovePtr<tcu::TextureLevel> InvertedDepthRangesTestInstance::generateReferenceImage (void) const
+MovePtr<tcu::TextureLevel> InvertedDepthRangesTestInstance::generateReferenceImage (ReferenceImageType refType) const
{
- MovePtr<tcu::TextureLevel> image (new tcu::TextureLevel(mapVkFormat(m_colorAttachmentFormat), 256, 256));
+ const auto iWidth = static_cast<int>(kImageExtent.width);
+ const auto iHeight = static_cast<int>(kImageExtent.height);
+ const bool color = (refType == ReferenceImageType::COLOR);
+ const auto tcuFormat = mapVkFormat(color ? m_colorAttachmentFormat : VK_FORMAT_D16_UNORM_S8_UINT);
+ MovePtr<tcu::TextureLevel> image (new tcu::TextureLevel(tcuFormat, iWidth, iHeight));
const tcu::PixelBufferAccess access (image->getAccess());
- const Vec4 black (0.0f, 0.0f, 0.0f, 1.0f);
- const int p1 = static_cast<int>(256.0f * 0.2f / 2.0f);
- const int p2 = static_cast<int>(256.0f * 1.8f / 2.0f);
- const float delta = 256.0f * 1.6f / 2.0f;
- const float depthValues[] = { -0.2f, 0.0f, 1.2f };
+ const float fImageDim = static_cast<float>(kImageDim);
+ const float p1f = fImageDim * kMargin / 2.0f;
+ const float p2f = fImageDim * (2.0f - kMargin + kDiagonalMargin) / 2.0f;
+ const float triangleSide = fImageDim * (2.0f - (2.0f*kMargin - kDiagonalMargin)) / 2.0f;
+ const float clampMin = de::min(m_params.minDepth, m_params.maxDepth);
+ const float clampMax = de::max(m_params.minDepth, m_params.maxDepth);
+ std::array<float, 3> depthValues;
+
+ // Depth value of each vertex in kVertices.
+ DE_ASSERT(depthValues.size() == kVertices.size());
+ std::transform(begin(kVertices), end(kVertices), begin(depthValues), [](const Vec4& coord) { return coord.z(); });
+
+ if (color)
+ tcu::clear(access, kClearColor);
+ else
+ {
+ tcu::clearDepth(access, kClearDepth);
+ tcu::clearStencil(access, kClearStencil);
+ }
+
+ for (int y = 0; y < iHeight; ++y)
+ for (int x = 0; x < iWidth; ++x)
+ {
+ const float xcoord = static_cast<float>(x) + 0.5f;
+ const float ycoord = static_cast<float>(y) + 0.5f;
+
+ if (xcoord < p1f || xcoord > p2f)
+ continue;
+
+ if (ycoord < p1f || ycoord > p2f)
+ continue;
+
+ if (ycoord > -xcoord + fImageDim)
+ continue;
+
+ // Interpolate depth value taking the 3 triangle corners into account.
+ const float b = (ycoord - p1f) / triangleSide;
+ const float c = (xcoord - p1f) / triangleSide;
+ const float a = 1.0f - b - c;
+ const float depth = a * depthValues[0] + b * depthValues[1] + c * depthValues[2];
- tcu::clear(access, black);
+ const float depthClamped = de::clamp(depth, 0.0f, 1.0f);
+ const float depthFinal = depthClamped * m_params.maxDepth + (1.0f - depthClamped) * m_params.minDepth;
+ const float storedDepth = (m_params.depthClampEnable ? de::clamp(depthFinal, clampMin, clampMax) : depthFinal);
- for (int y = p1; y <= p2; ++y)
- for (int x = p1; x < 256 - y; ++x)
+ if (m_params.depthClampEnable || de::inRange(depth, -kDepthEpsilon, 1.0f + kDepthEpsilon))
{
- const float a = static_cast<float>(p2 - x + p1 - y) / delta;
- const float b = static_cast<float>(y - p1) / delta;
- const float c = 1.0f - a - b;
- const float depth = a * depthValues[0] + b * depthValues[1] + c * depthValues[2];
- const float depthClamped = de::clamp(depth, 0.0f, 1.0f);
- const float depthFinal = depthClamped * m_params.maxDepth + (1.0f - depthClamped) * m_params.minDepth;
-
- if (m_params.depthClampEnable || (depth >= 0.0f && depth <= 1.0f))
- access.setPixel(Vec4(depthFinal, 0.5f, 0.5f, 1.0f), x, y);
+ if (color)
+ access.setPixel(Vec4(depthFinal, kVertexColor.y(), kVertexColor.z(), kVertexColor.w()), x, y);
+ else
+ {
+ if (!m_params.depthClampEnable &&
+ (de::inRange(depth, -kDepthEpsilon, kDepthEpsilon) ||
+ de::inRange(depth, 1.0f - kDepthEpsilon, 1.0f + kDepthEpsilon)))
+ {
+ // We should avoid comparing this pixel due to possible rounding problems.
+ // Pixels that should not be compared will be marked in the stencil aspect.
+ access.setPixStencil(kMaskedStencil, x, y);
+ }
+ access.setPixDepth(storedDepth, x, y);
+ }
}
+ }
return image;
}
const VkViewport viewport =
{
- 0.0f, // float x;
- 0.0f, // float y;
- 256.0f, // float width;
- 256.0f, // float height;
- m_params.minDepth, // float minDepth;
- m_params.maxDepth, // float maxDepth;
+ 0.0f, // float x;
+ 0.0f, // float y;
+ static_cast<float>(kImageExtent.width), // float width;
+ static_cast<float>(kImageExtent.height), // float height;
+ m_params.minDepth, // float minDepth;
+ m_params.maxDepth, // float maxDepth;
};
- const tcu::ConstPixelBufferAccess resultImage = draw(viewport);
-
- // Verify the results
+ ColorAndDepth results = draw(viewport);
+ auto& resultImage = results.first;
+ auto& resultDepth = results.second;
- tcu::TestLog& log = m_context.getTestContext().getLog();
- MovePtr<tcu::TextureLevel> referenceImage = generateReferenceImage();
+ // Verify results
+ auto& log = m_context.getTestContext().getLog();
+ auto referenceImage = generateReferenceImage(ReferenceImageType::COLOR);
+ auto referenceDepth = generateReferenceImage(ReferenceImageType::DEPTH);
+ // Color aspect.
if (!tcu::fuzzyCompare(log, "Image compare", "Image compare", referenceImage->getAccess(), resultImage, 0.02f, tcu::COMPARE_LOG_RESULT))
return tcu::TestStatus::fail("Rendered image is incorrect");
- else
- return tcu::TestStatus::pass("Pass");
+
+ // Depth aspect.
+ const auto refWidth = referenceDepth->getWidth();
+ const auto refHeight = referenceDepth->getHeight();
+ const auto refAccess = referenceDepth->getAccess();
+
+ tcu::TextureLevel errorMask (mapVkFormat(VK_FORMAT_R8G8B8_UNORM), refWidth, refHeight);
+ auto errorAccess = errorMask.getAccess();
+ const tcu::Vec4 kGreen (0.0f, 1.0f, 0.0f, 1.0f);
+ const tcu::Vec4 kRed (1.0f, 0.0f, 0.0f, 1.0f);
+
+ bool fail = false;
+ tcu::clear(errorAccess, kGreen);
+
+ for (int y = 0; y < refHeight; ++y)
+ for (int x = 0; x < refWidth; ++x)
+ {
+ // Ignore pixels that could be too close to having or not having coverage.
+ const auto stencil = refAccess.getPixStencil(x, y);
+ if (stencil == kMaskedStencil)
+ continue;
+
+ // Compare the rest using a known threshold.
+ const auto refValue = refAccess.getPixDepth(x, y);
+ const auto resValue = resultDepth.getPixDepth(x, y);
+ if (!de::inRange(resValue, refValue - kDepthThreshold, refValue + kDepthThreshold))
+ {
+ fail = true;
+ errorAccess.setPixel(kRed, x, y);
+ }
+ }
+
+ if (fail)
+ {
+ log << tcu::TestLog::Image("ErrorMask", "Error mask", errorAccess);
+ return tcu::TestStatus::fail("Result depth buffer is incorrect");
+ }
+
+ return tcu::TestStatus::pass("Pass");
}
class InvertedDepthRangesTest : public TestCase
std::ostringstream src;
src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
<< "\n"
- << "layout(location = 0) in vec4 in_position;\n"
+ << "layout(location = 0) in highp vec4 in_position;\n"
<< "\n"
<< "out gl_PerVertex {\n"
- << " vec4 gl_Position;\n"
+ << " highp vec4 gl_Position;\n"
<< "};\n"
<< "\n"
<< "void main(void)\n"
std::ostringstream src;
src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
<< "\n"
- << "layout(location = 0) out vec4 out_color;\n"
+ << "layout(location = 0) out highp vec4 out_color;\n"
<< "\n"
<< "void main(void)\n"
<< "{\n"
- << " out_color = vec4(gl_FragCoord.z, 0.5, 0.5, 1.0);\n"
+ << " out_color = vec4(gl_FragCoord.z, " << kVertexColor.y() << ", " << kVertexColor.z() << ", " << kVertexColor.w() << ");\n"
<< "}\n";
programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());