blob: 0ce3e11b2f1e2ff3ea66de9772d8259c4cea09ec [file] [log] [blame]
/*------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2018 The Khronos Group Inc.
* Copyright (c) 2018 Intel Corporation
*
* 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 VK_EXT_conditional_rendering extension tests.
*//*--------------------------------------------------------------------*/
#include "vktConditionalDrawAndClearTests.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktDrawBaseClass.hpp"
#include "vktDrawTestCaseUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"
#include <bitset>
namespace vkt
{
namespace conditional
{
namespace
{
using namespace vk;
using namespace Draw;
struct ClearTestParams
{
bool m_discard;
bool m_invert;
bool m_testDepth;
bool m_partialClear;
bool m_useOffset;
bool m_clearAttachmentTwice;
};
const ClearTestParams clearColorTestGrid[] =
{
{ false, false, false, false, false, false },
{ true, false, false, false, false, false },
{ false, true, false, false, false, false },
{ true, true, false, false, false, false },
{ false, false, false, true, false, false },
{ true, false, false, true, false, false },
{ false, true, false, true, false, false },
{ true, true, false, true, false, false },
{ false, false, false, true, true, false },
{ true, false, false, true, true, false },
{ false, true, false, true, true, false },
{ true, true, false, true, true, false },
{ true, true, false, false, true, false },
};
const ClearTestParams clearDepthTestGrid[] =
{
{ false, false, true, false, false, false },
{ true, false, true, false, false, false },
{ false, true, true, false, false, false },
{ true, true, true, false, false, false },
{ false, false, true, true, false, false },
{ true, false, true, true, false, false },
{ false, true, true, true, false, false },
{ true, true, true, true, false, false },
{ false, false, true, true, true, false },
{ true, false, true, true, true, false },
{ false, true, true, true, true, false },
{ true, true, true, true, true, false },
};
const ClearTestParams clearColorTwiceGrid[] =
{
{ false, false, false, false, false, true },
{ true, false, false, false, false, true },
{ false, true, false, false, false, true },
{ true, true, false, false, false, true },
{ false, true, false, true, true, true },
{ true, true, false, true, true, true }
};
const ClearTestParams clearDepthTwiceGrid[] =
{
{ false, false, true, false, false, true },
{ true, false, true, false, false, true },
{ false, true, true, false, false, true },
{ true, true, true, false, false, true },
{ false, true, true, true, true, true },
{ true, true, true, true, true, true }
};
enum TogglePredicateMode { FILL, COPY, NONE };
struct DrawTestParams
{
bool m_discard; //controls the setting of the predicate for conditional rendering.Initial state, may be toggled later depending on the m_togglePredicate setting.
bool m_invert;
bool m_useOffset;
deUint32 m_beginSequenceBits; //bits 0..3 control BEFORE which of the 4 draw calls the vkCmdBeginConditionalRenderingEXT call is executed. Least significant bit corresponds to the first draw call.
deUint32 m_endSequenceBits; //bits 0..3 control AFTER which of the 4 draw calls the vkCmdEndConditionalRenderingEXT call is executed. Least significant bit corresponds to the first draw call.
deUint32 m_resultBits; //used for reference image preparation.
bool m_togglePredicate; //if true, toggle the predicate setting before rendering.
TogglePredicateMode m_toggleMode; //method of the predicate toggling
};
enum
{
b0000 = 0x0,
b0001 = 0x1,
b0010 = 0x2,
b0011 = 0x3,
b0100 = 0x4,
b0101 = 0x5,
b0110 = 0x6,
b0111 = 0x7,
b1000 = 0x8,
b1001 = 0x9,
b1010 = 0xA,
b1011 = 0xB,
b1100 = 0xC,
b1101 = 0xD,
b1110 = 0xE,
b1111 = 0xF,
};
const DrawTestParams drawTestGrid[] =
{
{ false, false, false, b0001, b1000, b1111, false, NONE },
{ true, false, false, b0001, b1000, b0000, false, NONE },
{ true, false, false, b0001, b0001, b1110, false, NONE },
{ true, false, false, b1111, b1111, b0000, false, NONE },
{ true, false, false, b0010, b0010, b1101, false, NONE },
{ true, true, false, b1010, b1010, b0101, false, NONE },
{ false, true, true, b1010, b1010, b1111, false, NONE },
{ true, true, true, b0010, b1000, b0001, false, NONE },
{ true, true, true, b1001, b1001, b0110, false, NONE },
{ true, true, true, b0010, b1000, b1111, true, FILL },
{ true, true, true, b1001, b1001, b1111, true, FILL },
{ false, true, true, b1001, b1001, b0110, true, FILL },
{ true, true, true, b0010, b1000, b1111, true, COPY },
{ true, true, true, b1001, b1001, b1111, true, COPY },
{ false, true, true, b1001, b1001, b0110, true, COPY },
};
std::string generateClearTestName(const ClearTestParams& clearTestParams)
{
std::string name = (clearTestParams.m_discard ? "discard_" : "no_discard_");
name += (clearTestParams.m_invert ? "invert_" : "no_invert_");
name += (clearTestParams.m_partialClear ? "partial_" : "full_");
name += (clearTestParams.m_useOffset ? "offset" : "no_offset");
return name;
}
inline deUint32 getBit(deUint32 src, int ndx)
{
return (src >> ndx) & 1;
}
inline bool isBitSet(deUint32 src, int ndx)
{
return getBit(src, ndx) != 0;
}
class ConditionalRenderingBaseTestInstance : public TestInstance
{
public:
ConditionalRenderingBaseTestInstance (Context& context);
protected:
virtual tcu::TestStatus iterate (void) = 0;
void createInitBufferWithPredicate (bool discard, bool invert, deUint32 offsetMultiplier, VkBufferUsageFlagBits extraUsage);
void createTargetColorImageAndImageView (void);
void createTargetDepthImageAndImageView (void);
void createRenderPass (VkFormat format, VkImageLayout layout);
void createFramebuffer (VkImageView imageView);
void clearWithClearColorImage (const VkClearColorValue& color);
void clearWithClearDepthStencilImage (const VkClearDepthStencilValue& value);
void clearColorWithClearAttachments (const VkClearColorValue& color, bool partial);
void clearDepthWithClearAttachments (const VkClearDepthStencilValue& depthStencil, bool partial);
void createResultBuffer (VkFormat format);
void createVertexBuffer (void);
void createPipelineLayout (void);
void createAndUpdateDescriptorSet (void);
void createPipeline (void);
void copyResultImageToBuffer (VkImageAspectFlags imageAspectFlags, VkImage image);
void draw (void);
void imageMemoryBarrier (VkImage image, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout,
VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkImageAspectFlags imageAspectFlags);
void bufferMemoryBarrier (VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask,
VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask);
void prepareReferenceImageOneColor (tcu::PixelBufferAccess& reference, const VkClearColorValue& clearColor);
void prepareReferenceImageOneColor (tcu::PixelBufferAccess& reference, const tcu::Vec4& color);
void prepareReferenceImageOneDepth (tcu::PixelBufferAccess& reference, const VkClearDepthStencilValue& clearValue);
void prepareReferenceImageDepthClearPartial (tcu::PixelBufferAccess& reference, const VkClearDepthStencilValue& clearValueInitial, const VkClearDepthStencilValue& clearValueFinal);
void prepareReferenceImageColorClearPartial (tcu::PixelBufferAccess& reference, const VkClearColorValue& clearColorInitial, const VkClearColorValue& clearColorFinal);
const InstanceInterface& m_vki;
const DeviceInterface& m_vkd;
const VkDevice m_device;
const VkPhysicalDevice m_physicalDevice;
const VkQueue m_queue;
de::SharedPtr<Buffer> m_conditionalRenderingBuffer;
de::SharedPtr<Buffer> m_resultBuffer;
de::SharedPtr<Buffer> m_vertexBuffer;
de::SharedPtr<Image> m_colorTargetImage;
de::SharedPtr<Image> m_depthTargetImage;
Move<VkImageView> m_colorTargetView;
Move<VkImageView> m_depthTargetView;
Move<VkRenderPass> m_renderPass;
Move<VkFramebuffer> m_framebuffer;
Move<VkCommandPool> m_cmdPool;
Move<VkCommandBuffer> m_cmdBufferPrimary;
Move<VkDescriptorPool> m_descriptorPool;
Move<VkDescriptorSetLayout> m_descriptorSetLayout;
Move<VkDescriptorSet> m_descriptorSet;
Move<VkPipelineLayout> m_pipelineLayout;
Move<VkShaderModule> m_vertexShaderModule;
Move<VkShaderModule> m_fragmentShaderModule;
Move<VkPipeline> m_pipeline;
VkDeviceSize m_conditionalRenderingBufferOffset;
enum
{
WIDTH = 256,
HEIGHT = 256
};
};
class ConditionalRenderingClearAttachmentsTestInstance : public ConditionalRenderingBaseTestInstance
{
public:
ConditionalRenderingClearAttachmentsTestInstance (Context& context, const ClearTestParams& testParams);
protected:
virtual tcu::TestStatus iterate (void);
ClearTestParams m_testParams;
};
class ConditionalRenderingDrawTestInstance : public ConditionalRenderingBaseTestInstance
{
public:
ConditionalRenderingDrawTestInstance (Context& context, const DrawTestParams& testParams);
protected:
//Execute 4 draw calls, each can be drawn with or without conditional rendering. Each draw call renders to the different part of an image - this is achieved by
//using push constant and 'discard' in the fragment shader. This way it is possible to tell which of the rendering command were discarded by the conditional rendering mechanism.
virtual tcu::TestStatus iterate (void);
void createPipelineLayout (void);
void prepareReferenceImage (tcu::PixelBufferAccess& reference, const VkClearColorValue& clearColor, deUint32 resultBits);
DrawTestParams m_testParams;
de::SharedPtr<Buffer> m_conditionalRenderingBufferForCopy;
};
class ConditionalRenderingUpdateBufferWithDrawTestInstance : public ConditionalRenderingBaseTestInstance
{
public:
ConditionalRenderingUpdateBufferWithDrawTestInstance (Context& context, bool testParams);
protected:
virtual tcu::TestStatus iterate (void);
void createAndUpdateDescriptorSets (void);
void createPipelines (void);
void createRenderPass (VkFormat format, VkImageLayout layout);
Move<VkDescriptorSet> m_descriptorSetUpdate;
Move<VkShaderModule> m_vertexShaderModuleDraw;
Move<VkShaderModule> m_fragmentShaderModuleDraw;
Move<VkShaderModule> m_vertexShaderModuleUpdate;
Move<VkShaderModule> m_fragmentShaderModuleDiscard;
Move<VkPipeline> m_pipelineDraw;
Move<VkPipeline> m_pipelineUpdate;
bool m_testParams;
};
ConditionalRenderingBaseTestInstance::ConditionalRenderingBaseTestInstance (Context& context)
: TestInstance (context)
, m_vki (m_context.getInstanceInterface())
, m_vkd (m_context.getDeviceInterface())
, m_device (m_context.getDevice())
, m_physicalDevice (m_context.getPhysicalDevice())
, m_queue (m_context.getUniversalQueue())
{
}
void ConditionalRenderingBaseTestInstance::createInitBufferWithPredicate (bool discard, bool invert, deUint32 offsetMultiplier = 0, VkBufferUsageFlagBits extraUsage = (VkBufferUsageFlagBits)0)
{
m_conditionalRenderingBufferOffset = sizeof(deUint32) * offsetMultiplier;
const VkDeviceSize dataSize = sizeof(deUint32) + m_conditionalRenderingBufferOffset;
deUint32 predicate = discard ? invert : !invert;
m_conditionalRenderingBuffer = Buffer::createAndAlloc(m_vkd, m_device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT | extraUsage), m_context.getDefaultAllocator(),
MemoryRequirement::HostVisible);
void * conditionalRenderingBufferDataPointer = static_cast<char*>(m_conditionalRenderingBuffer->getBoundMemory().getHostPtr()) + m_conditionalRenderingBufferOffset;
deMemcpy(conditionalRenderingBufferDataPointer, &predicate, static_cast<size_t>(sizeof(deUint32)));
flushMappedMemoryRange(m_vkd, m_device, m_conditionalRenderingBuffer->getBoundMemory().getMemory(), m_conditionalRenderingBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
}
void ConditionalRenderingBaseTestInstance::createTargetColorImageAndImageView (void)
{
const VkExtent3D targetImageExtent = { WIDTH, HEIGHT, 1 };
const ImageCreateInfo targetImageCreateInfo( VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, targetImageExtent, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
m_colorTargetImage = Image::createAndAlloc(m_vkd, m_device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM);
m_colorTargetView = createImageView(m_vkd, m_device, &colorTargetViewInfo);
}
void ConditionalRenderingBaseTestInstance::createTargetDepthImageAndImageView (void)
{
const VkExtent3D targetImageExtent = { WIDTH, HEIGHT, 1 };
const ImageCreateInfo targetImageCreateInfo(VK_IMAGE_TYPE_2D, VK_FORMAT_D32_SFLOAT, targetImageExtent, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
m_depthTargetImage = Image::createAndAlloc(m_vkd, m_device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
const ImageViewCreateInfo depthTargetViewInfo(m_depthTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D32_SFLOAT);
m_depthTargetView = createImageView(m_vkd, m_device, &depthTargetViewInfo);
}
void ConditionalRenderingBaseTestInstance::createRenderPass (VkFormat format, VkImageLayout layout)
{
RenderPassCreateInfo renderPassCreateInfo;
renderPassCreateInfo.addAttachment(AttachmentDescription(format,
VK_SAMPLE_COUNT_1_BIT,
VK_ATTACHMENT_LOAD_OP_LOAD,
VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE,
VK_ATTACHMENT_STORE_OP_STORE,
isDepthStencilFormat(format) ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
isDepthStencilFormat(format) ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
const VkAttachmentReference attachmentReference =
{
0u, // deUint32 attachment
layout // VkImageLayout layout
};
renderPassCreateInfo.addSubpass(SubpassDescription(VK_PIPELINE_BIND_POINT_GRAPHICS,
0,
0,
DE_NULL,
isDepthStencilFormat(format) ? 0 : 1,
isDepthStencilFormat(format) ? DE_NULL : &attachmentReference,
DE_NULL,
isDepthStencilFormat(format) ? attachmentReference : AttachmentReference(),
0,
DE_NULL));
m_renderPass = vk::createRenderPass(m_vkd, m_device, &renderPassCreateInfo);
}
void ConditionalRenderingBaseTestInstance::createFramebuffer (VkImageView imageView)
{
const VkFramebufferCreateInfo framebufferCreateInfo =
{
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
DE_NULL, // const void* pNext
(VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
*m_renderPass, // VkRenderPass renderPass
1, // deUint32 attachmentCount
&imageView, // const VkImageView* pAttachments
WIDTH, // deUint32 width
HEIGHT, // deUint32 height
1 // deUint32 layers
};
m_framebuffer = vk::createFramebuffer(m_vkd, m_device, &framebufferCreateInfo);
}
void ConditionalRenderingBaseTestInstance::imageMemoryBarrier ( VkImage image, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout,
VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkImageAspectFlags imageAspectFlags)
{
const struct VkImageSubresourceRange subRangeColor =
{
imageAspectFlags, // VkImageAspectFlags aspectMask
0u, // deUint32 baseMipLevel
1u, // deUint32 mipLevels
0u, // deUint32 baseArrayLayer
1u, // deUint32 arraySize
};
const VkImageMemoryBarrier imageBarrier =
{
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
DE_NULL, // const void* pNext
srcAccessMask, // VkAccessFlags srcAccessMask
dstAccessMask, // VkAccessFlags dstAccessMask
oldLayout, // VkImageLayout oldLayout
newLayout, // VkImageLayout newLayout
VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex
VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex
image, // VkImage image
subRangeColor // VkImageSubresourceRange subresourceRange
};
m_vkd.cmdPipelineBarrier(*m_cmdBufferPrimary, srcStageMask, dstStageMask, DE_FALSE, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
}
void ConditionalRenderingBaseTestInstance::bufferMemoryBarrier (VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask,
VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask)
{
const VkBufferMemoryBarrier bufferBarrier =
{
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, //VkStructureType sType;
DE_NULL, //const void* pNext;
srcAccessMask, //VkAccessFlags srcAccessMask;
dstAccessMask, //VkAccessFlags dstAccessMask;
VK_QUEUE_FAMILY_IGNORED, //uint32_t srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, //uint32_t dstQueueFamilyIndex;
buffer, //VkBuffer buffer;
offset, //VkDeviceSize offset;
size //VkDeviceSize size;
};
m_vkd.cmdPipelineBarrier(*m_cmdBufferPrimary, srcStageMask, dstStageMask, DE_FALSE, 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
}
void ConditionalRenderingBaseTestInstance::prepareReferenceImageOneColor (tcu::PixelBufferAccess& reference, const VkClearColorValue& clearColor)
{
for (int w = 0; w < WIDTH; ++w)
for (int h = 0; h < HEIGHT; ++h)
reference.setPixel(tcu::Vec4(clearColor.float32[0], clearColor.float32[1], clearColor.float32[2], clearColor.float32[3]), w, h);
}
void ConditionalRenderingBaseTestInstance::prepareReferenceImageOneColor (tcu::PixelBufferAccess& reference, const tcu::Vec4& color)
{
for (int w = 0; w < WIDTH; ++w)
for (int h = 0; h < HEIGHT; ++h)
reference.setPixel(tcu::Vec4(color), w, h);
}
void ConditionalRenderingBaseTestInstance::prepareReferenceImageOneDepth (tcu::PixelBufferAccess& reference, const VkClearDepthStencilValue& clearValue)
{
for (int w = 0; w < WIDTH; ++w)
for (int h = 0; h < HEIGHT; ++h)
reference.setPixDepth(clearValue.depth, w, h);
}
void ConditionalRenderingBaseTestInstance::prepareReferenceImageDepthClearPartial (tcu::PixelBufferAccess& reference, const VkClearDepthStencilValue& clearValueInitial, const VkClearDepthStencilValue& clearValueFinal)
{
for (int w = 0; w < WIDTH; ++w)
for (int h = 0; h < HEIGHT; ++h)
{
if
(w >= (WIDTH / 2) && h >= (HEIGHT / 2)) reference.setPixDepth(clearValueFinal.depth, w, h);
else
reference.setPixDepth(clearValueInitial.depth, w, h);
}
}
void ConditionalRenderingBaseTestInstance::prepareReferenceImageColorClearPartial (tcu::PixelBufferAccess& reference, const VkClearColorValue& clearColorInitial, const VkClearColorValue& clearColorFinal)
{
for (int w = 0; w < WIDTH; ++w)
for (int h = 0; h < HEIGHT; ++h)
{
if
(w >= (WIDTH / 2) && h >= (HEIGHT / 2)) reference.setPixel(tcu::Vec4(clearColorFinal.float32[0], clearColorFinal.float32[1], clearColorFinal.float32[2], clearColorFinal.float32[3]), w, h);
else
reference.setPixel(tcu::Vec4(clearColorInitial.float32[0], clearColorInitial.float32[1], clearColorInitial.float32[2], clearColorInitial.float32[3]), w, h);
}
}
void ConditionalRenderingBaseTestInstance::clearWithClearColorImage (const VkClearColorValue& color)
{
const struct VkImageSubresourceRange subRangeColor =
{
VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
0u, // deUint32 baseMipLevel
1u, // deUint32 mipLevels
0u, // deUint32 baseArrayLayer
1u, // deUint32 arraySize
};
m_vkd.cmdClearColorImage(*m_cmdBufferPrimary, m_colorTargetImage->object(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &color, 1, &subRangeColor);
}
void ConditionalRenderingBaseTestInstance::clearWithClearDepthStencilImage (const VkClearDepthStencilValue& value)
{
const struct VkImageSubresourceRange subRangeColor =
{
VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask
0u, // deUint32 baseMipLevel
1u, // deUint32 mipLevels
0u, // deUint32 baseArrayLayer
1u, // deUint32 arraySize
};
m_vkd.cmdClearDepthStencilImage(*m_cmdBufferPrimary, m_depthTargetImage->object(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &value, 1, &subRangeColor);
}
void ConditionalRenderingBaseTestInstance::clearColorWithClearAttachments (const VkClearColorValue& color, bool partial)
{
const VkClearAttachment clearAttachment =
{
VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
0u, // deUint32 colorAttachment;
{ color } // VkClearValue clearValue;
};
VkRect2D renderArea = { { 0, 0 },{ WIDTH, HEIGHT } };
if (partial)
{
renderArea.offset.x = WIDTH / 2;
renderArea.offset.y = HEIGHT / 2;
renderArea.extent.width = WIDTH / 2;
renderArea.extent.height = HEIGHT / 2;
}
const VkClearRect clearRect =
{
renderArea, // VkRect2D rect;
0u, // deUint32 baseArrayLayer;
1u // deUint32 layerCount;
};
m_vkd.cmdClearAttachments(*m_cmdBufferPrimary, 1, &clearAttachment, 1, &clearRect);
}
void ConditionalRenderingBaseTestInstance::clearDepthWithClearAttachments (const VkClearDepthStencilValue& depthStencil, bool partial)
{
const VkClearAttachment clearAttachment =
{
VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
0u, // deUint32 colorAttachment;
makeClearValueDepthStencil(depthStencil.depth, depthStencil.stencil) // VkClearValue clearValue;
};
VkRect2D renderArea = { { 0, 0 },{ WIDTH, HEIGHT } };
if (partial)
{
renderArea.offset.x = WIDTH / 2;
renderArea.offset.y = HEIGHT / 2;
renderArea.extent.width = WIDTH / 2;
renderArea.extent.height = HEIGHT / 2;
}
const VkClearRect clearRect =
{
renderArea, // VkRect2D rect;
0u, // deUint32 baseArrayLayer;
1u // deUint32 layerCount;
};
m_vkd.cmdClearAttachments(*m_cmdBufferPrimary, 1, &clearAttachment, 1, &clearRect);
}
void ConditionalRenderingBaseTestInstance::createResultBuffer (VkFormat format)
{
VkDeviceSize size = WIDTH * HEIGHT * mapVkFormat(format).getPixelSize();
m_resultBuffer = Buffer::createAndAlloc(m_vkd, m_device, BufferCreateInfo(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT), m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
}
void ConditionalRenderingBaseTestInstance::createVertexBuffer (void)
{
float triangleData[] = { -1.0f, -1.0f, 0.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f };
m_vertexBuffer = Buffer::createAndAlloc(m_vkd, m_device, BufferCreateInfo(sizeof(triangleData), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
void * vertexBufferDataPointer = m_vertexBuffer->getBoundMemory().getHostPtr();
deMemcpy(vertexBufferDataPointer, triangleData, sizeof(triangleData));
flushMappedMemoryRange(m_vkd, m_device, m_vertexBuffer->getBoundMemory().getMemory(), m_vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
}
void ConditionalRenderingBaseTestInstance::createPipelineLayout (void)
{
const VkPipelineLayoutCreateInfo pipelineLayoutParams =
{
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
DE_NULL, // const void* pNext
(VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags
1u, // deUint32 descriptorSetCount
&(m_descriptorSetLayout.get()), // const VkDescriptorSetLayout* pSetLayouts
0u, // deUint32 pushConstantRangeCount
DE_NULL // const VkPushConstantRange* pPushConstantRanges
};
m_pipelineLayout = vk::createPipelineLayout(m_vkd, m_device, &pipelineLayoutParams);
}
void ConditionalRenderingBaseTestInstance::createAndUpdateDescriptorSet (void)
{
const VkDescriptorSetAllocateInfo allocInfo =
{
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType
DE_NULL, // const void* pNext
*m_descriptorPool, // VkDescriptorPool descriptorPool
1u, // deUint32 setLayoutCount
&(m_descriptorSetLayout.get()) // const VkDescriptorSetLayout* pSetLayouts
};
m_descriptorSet = allocateDescriptorSet(m_vkd, m_device, &allocInfo);
VkDescriptorBufferInfo descriptorInfo = makeDescriptorBufferInfo(m_vertexBuffer->object(), (VkDeviceSize)0u, sizeof(float) * 16);
DescriptorSetUpdateBuilder()
.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
.update(m_vkd, m_device);
}
void ConditionalRenderingBaseTestInstance::createPipeline (void)
{
const std::vector<VkViewport> viewports(1, makeViewport(tcu::UVec2(WIDTH, HEIGHT)));
const std::vector<VkRect2D> scissors(1, makeRect2D(tcu::UVec2(WIDTH, HEIGHT)));
const VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
{
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
DE_NULL, // const void* pNext
0u, // vkPipelineVertexInputStateCreateFlags flags
0u, // deUint32 bindingCount
DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
0u, // deUint32 attributeCount
DE_NULL, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
};
m_pipeline = makeGraphicsPipeline(m_vkd, // const DeviceInterface& vk
m_device, // const VkDevice device
*m_pipelineLayout, // const VkPipelineLayout pipelineLayout
*m_vertexShaderModule, // const VkShaderModule vertexShaderModule
DE_NULL, // const VkShaderModule tessellationControlShaderModule
DE_NULL, // const VkShaderModule tessellationEvalShaderModule
DE_NULL, // const VkShaderModule geometryShaderModule
*m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
*m_renderPass, // const VkRenderPass renderPass
viewports, // const std::vector<VkViewport>& viewports
scissors, // const std::vector<VkRect2D>& scissors
topology, // const VkPrimitiveTopology topology
0u, // const deUint32 subpass
0u, // const deUint32 patchControlPoints
&vertexInputStateParams); // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
}
void ConditionalRenderingBaseTestInstance::copyResultImageToBuffer (VkImageAspectFlags imageAspectFlags, VkImage image)
{
const VkBufferImageCopy region_all =
{
0, // VkDeviceSize bufferOffset
0, // deUint32 bufferRowLength
0, // deUint32 bufferImageHeight
{ imageAspectFlags, 0, 0, 1 }, // VkImageSubresourceLayers imageSubresource
{ 0, 0, 0 }, // VkOffset3D imageOffset
{ WIDTH, HEIGHT, 1 } // VkExtent3D imageExtent
};
m_vkd.cmdCopyImageToBuffer(*m_cmdBufferPrimary, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_resultBuffer->object(), 1, &region_all);
}
void ConditionalRenderingBaseTestInstance::draw (void)
{
m_vkd.cmdDraw(*m_cmdBufferPrimary, 4, 1, 0, 0);
}
ConditionalRenderingClearAttachmentsTestInstance::ConditionalRenderingClearAttachmentsTestInstance (Context& context, const ClearTestParams& testParams)
: ConditionalRenderingBaseTestInstance (context)
, m_testParams (testParams)
{}
tcu::TestStatus ConditionalRenderingClearAttachmentsTestInstance::iterate (void)
{
const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
deUint32 offsetMultiplier = 0;
VkClearColorValue clearColorInitial = { { 0.0f, 0.0f, 1.0f, 1.0f } };
VkClearColorValue clearColorMiddle = { { 1.0f, 0.0f, 0.0f, 1.0f } };
VkClearColorValue clearColorFinal = { { 0.0f, 1.0f, 0.0f, 1.0f } };
VkClearDepthStencilValue clearDepthValueInitial = { 0.4f, 0 };
VkClearDepthStencilValue clearDepthValueMiddle = { 0.6f, 0 };
VkClearDepthStencilValue clearDepthValueFinal = { 0.9f, 0 };
if (m_testParams.m_useOffset) offsetMultiplier = 3;
createInitBufferWithPredicate(m_testParams.m_discard, m_testParams.m_invert, offsetMultiplier);
m_testParams.m_testDepth ? createTargetDepthImageAndImageView() : createTargetColorImageAndImageView();
createResultBuffer(m_testParams.m_testDepth ? VK_FORMAT_D32_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM);
m_cmdPool = createCommandPool(m_vkd, m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
m_cmdBufferPrimary = allocateCommandBuffer(m_vkd, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
createRenderPass(m_testParams.m_testDepth ? VK_FORMAT_D32_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM, m_testParams.m_testDepth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
createFramebuffer(m_testParams.m_testDepth ? m_depthTargetView.get() : m_colorTargetView.get());
const VkConditionalRenderingBeginInfoEXT conditionalRenderingBeginInfo =
{
VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT, //VkStructureType sType;
DE_NULL, //const void* pNext;
m_conditionalRenderingBuffer->object(), //VkBuffer buffer;
sizeof(deUint32) * offsetMultiplier, //VkDeviceSize offset;
(m_testParams.m_invert ? (VkConditionalRenderingFlagsEXT) VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT : (VkConditionalRenderingFlagsEXT) 0) //VkConditionalRenderingFlagsEXT flags;
};
beginCommandBuffer(m_vkd, *m_cmdBufferPrimary);
imageMemoryBarrier(m_testParams.m_testDepth ? m_depthTargetImage->object() : m_colorTargetImage->object(), //VkImage image
0u, //VkAccessFlags srcAccessMask
VK_ACCESS_TRANSFER_WRITE_BIT, //VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_UNDEFINED, //VkImageLayout oldLayout
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, //VkImageLayout newLayout
VK_PIPELINE_STAGE_TRANSFER_BIT, //VkPipelineStageFlags srcStageMask
VK_PIPELINE_STAGE_TRANSFER_BIT, //VkPipelineStageFlags dstStageMask
m_testParams.m_testDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT); //VkImageAspectFlags flags
m_testParams.m_testDepth ? clearWithClearDepthStencilImage(clearDepthValueInitial)
: clearWithClearColorImage(clearColorInitial);
imageMemoryBarrier(m_testParams.m_testDepth ? m_depthTargetImage->object() : m_colorTargetImage->object(), //VkImage image
VK_ACCESS_TRANSFER_WRITE_BIT, //VkAccessFlags srcAccessMask
m_testParams.m_testDepth ? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT : VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, //VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, //VkImageLayout oldLayout
m_testParams.m_testDepth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, //VkImageLayout newLayout
VK_PIPELINE_STAGE_TRANSFER_BIT, //VkPipelineStageFlags srcStageMask
m_testParams.m_testDepth ? VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT : VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags dstStageMask
m_testParams.m_testDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT); //VkImageAspectFlags flags
if (m_testParams.m_clearAttachmentTwice)
{
beginRenderPass(m_vkd, *m_cmdBufferPrimary, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT));
m_testParams.m_testDepth ? clearDepthWithClearAttachments(clearDepthValueMiddle, m_testParams.m_partialClear)
: clearColorWithClearAttachments(clearColorMiddle, m_testParams.m_partialClear);
m_vkd.cmdBeginConditionalRenderingEXT(*m_cmdBufferPrimary, &conditionalRenderingBeginInfo);
m_testParams.m_testDepth ? clearDepthWithClearAttachments(clearDepthValueFinal, m_testParams.m_partialClear)
: clearColorWithClearAttachments(clearColorFinal, m_testParams.m_partialClear);
m_vkd.cmdEndConditionalRenderingEXT(*m_cmdBufferPrimary);
endRenderPass(m_vkd, *m_cmdBufferPrimary);
}
else
{
m_vkd.cmdBeginConditionalRenderingEXT(*m_cmdBufferPrimary, &conditionalRenderingBeginInfo);
beginRenderPass(m_vkd, *m_cmdBufferPrimary, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT));
m_testParams.m_testDepth ? clearDepthWithClearAttachments(clearDepthValueFinal, m_testParams.m_partialClear)
: clearColorWithClearAttachments(clearColorFinal, m_testParams.m_partialClear);
endRenderPass(m_vkd, *m_cmdBufferPrimary);
m_vkd.cmdEndConditionalRenderingEXT(*m_cmdBufferPrimary);
}
imageMemoryBarrier(m_testParams.m_testDepth ? m_depthTargetImage->object() : m_colorTargetImage->object(), //VkImage image
m_testParams.m_testDepth ? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT : VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, //VkAccessFlags srcAccessMask
VK_ACCESS_TRANSFER_READ_BIT, //VkAccessFlags dstAccessMask
m_testParams.m_testDepth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, //VkImageLayout oldLayout
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, //VkImageLayout newLayout
m_testParams.m_testDepth ? VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT : VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags srcStageMask
VK_PIPELINE_STAGE_TRANSFER_BIT, //VkPipelineStageFlags dstStageMask
m_testParams.m_testDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT); //VkImageAspectFlags flags
copyResultImageToBuffer(m_testParams.m_testDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT, m_testParams.m_testDepth ? m_depthTargetImage->object() : m_colorTargetImage->object());
endCommandBuffer(m_vkd, *m_cmdBufferPrimary);
submitCommandsAndWait(m_vkd, m_device, m_queue, *m_cmdBufferPrimary);
tcu::ConstPixelBufferAccess result(mapVkFormat(m_testParams.m_testDepth ? VK_FORMAT_D32_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM), tcu::IVec3(WIDTH, HEIGHT, 1), m_resultBuffer->getBoundMemory().getHostPtr());
std::vector<float> referenceData((m_testParams.m_testDepth ? 1 : 4) * WIDTH * HEIGHT, 0);
tcu::PixelBufferAccess reference(mapVkFormat(m_testParams.m_testDepth ? VK_FORMAT_D32_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM), tcu::IVec3(WIDTH, HEIGHT, 1), referenceData.data());
if (!m_testParams.m_partialClear)
{
m_testParams.m_testDepth ? prepareReferenceImageOneDepth(reference, m_testParams.m_discard ? (m_testParams.m_clearAttachmentTwice ? clearDepthValueMiddle : clearDepthValueInitial) : clearDepthValueFinal)
: prepareReferenceImageOneColor(reference, m_testParams.m_discard ? (m_testParams.m_clearAttachmentTwice ? clearColorMiddle : clearColorInitial) : clearColorFinal);
}
else
{
m_testParams.m_testDepth ? prepareReferenceImageDepthClearPartial(reference, clearDepthValueInitial, m_testParams.m_discard ? (m_testParams.m_clearAttachmentTwice ? clearDepthValueMiddle : clearDepthValueInitial) : clearDepthValueFinal)
: prepareReferenceImageColorClearPartial(reference, clearColorInitial, m_testParams.m_discard ? (m_testParams.m_clearAttachmentTwice ? clearColorMiddle : clearColorInitial) : clearColorFinal);
}
if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Comparison", "Comparison", reference, result, tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR))
return tcu::TestStatus::fail("Fail");
return tcu::TestStatus::pass("Pass");
}
ConditionalRenderingDrawTestInstance::ConditionalRenderingDrawTestInstance (Context& context, const DrawTestParams& testParams)
: ConditionalRenderingBaseTestInstance (context)
, m_testParams (testParams)
{}
tcu::TestStatus ConditionalRenderingDrawTestInstance::iterate (void)
{
const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
VkClearColorValue clearColorInitial = { { 0.0f, 0.0f, 1.0f, 1.0f } };
deUint32 offsetMultiplier = 0;
if (m_testParams.m_useOffset) offsetMultiplier = 3;
VkBufferUsageFlagBits bufferUsageExtraFlags = (VkBufferUsageFlagBits)0;
if (m_testParams.m_togglePredicate)
bufferUsageExtraFlags = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
createInitBufferWithPredicate(m_testParams.m_discard, m_testParams.m_invert, offsetMultiplier, bufferUsageExtraFlags);
if (m_testParams.m_toggleMode == COPY)
{
//we need another buffer to copy from, with toggled predicate value
m_conditionalRenderingBufferForCopy.swap(m_conditionalRenderingBuffer);
createInitBufferWithPredicate(!m_testParams.m_discard, m_testParams.m_invert, offsetMultiplier, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
m_conditionalRenderingBufferForCopy.swap(m_conditionalRenderingBuffer);
}
createTargetColorImageAndImageView();
createResultBuffer(VK_FORMAT_R8G8B8A8_UNORM);
createVertexBuffer();
m_cmdPool = createCommandPool(m_vkd, m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
m_cmdBufferPrimary = allocateCommandBuffer(m_vkd, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
createRenderPass(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
createFramebuffer(m_colorTargetView.get());
DescriptorSetLayoutBuilder builder;
builder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
m_descriptorSetLayout = builder.build(m_vkd, m_device, (VkDescriptorSetLayoutCreateFlags)0);
m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
.build(m_vkd, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
createPipelineLayout();
createAndUpdateDescriptorSet();
m_vertexShaderModule = createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("position_only.vert"), 0);
m_fragmentShaderModule = createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("only_color_out.frag"), 0);
createPipeline();
VkConditionalRenderingBeginInfoEXT conditionalRenderingBeginInfo =
{
VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT, //VkStructureType sType;
DE_NULL, //const void* pNext;
m_conditionalRenderingBuffer->object(), //VkBuffer buffer;
sizeof(deUint32) * offsetMultiplier, //VkDeviceSize offset;
(m_testParams.m_invert ? (VkConditionalRenderingFlagsEXT)VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT
: (VkConditionalRenderingFlagsEXT)0) //VkConditionalRenderingFlagsEXT flags;
};
beginCommandBuffer(m_vkd, *m_cmdBufferPrimary);
imageMemoryBarrier(m_colorTargetImage->object(), //VkImage image
0u, //VkAccessFlags srcAccessMask
VK_ACCESS_TRANSFER_WRITE_BIT, //VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_UNDEFINED, //VkImageLayout oldLayout
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, //VkImageLayout newLayout
VK_PIPELINE_STAGE_TRANSFER_BIT, //VkPipelineStageFlags srcStageMask
VK_PIPELINE_STAGE_TRANSFER_BIT, //VkPipelineStageFlags dstStageMask
VK_IMAGE_ASPECT_COLOR_BIT); //VkImageAspectFlags flags
clearWithClearColorImage(clearColorInitial);
imageMemoryBarrier(m_colorTargetImage->object(), //VkImage image
VK_ACCESS_TRANSFER_WRITE_BIT, //VkAccessFlags srcAccessMask
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, //VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, //VkImageLayout oldLayout
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, //VkImageLayout newLayout
VK_PIPELINE_STAGE_TRANSFER_BIT, //VkPipelineStageFlags srcStageMask
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags dstStageMask
VK_IMAGE_ASPECT_COLOR_BIT); //VkImageAspectFlags flags
m_vkd.cmdBindPipeline(*m_cmdBufferPrimary, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
m_vkd.cmdBindDescriptorSets(*m_cmdBufferPrimary, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &(*m_descriptorSet), 0, DE_NULL);
if (m_testParams.m_togglePredicate)
{
if (m_testParams.m_toggleMode == FILL)
{
m_testParams.m_discard = !m_testParams.m_discard;
deUint32 predicate = m_testParams.m_discard ? m_testParams.m_invert : !m_testParams.m_invert;
m_vkd.cmdFillBuffer(*m_cmdBufferPrimary, m_conditionalRenderingBuffer->object(), m_conditionalRenderingBufferOffset, sizeof(predicate), predicate);
bufferMemoryBarrier(m_conditionalRenderingBuffer->object(), m_conditionalRenderingBufferOffset, sizeof(predicate), VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT,
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT);
}
if (m_testParams.m_toggleMode == COPY)
{
VkBufferCopy region =
{
m_conditionalRenderingBufferOffset, //VkDeviceSize srcOffset;
m_conditionalRenderingBufferOffset, //VkDeviceSize dstOffset;
sizeof(deUint32) //VkDeviceSize size;
};
m_vkd.cmdCopyBuffer(*m_cmdBufferPrimary, m_conditionalRenderingBufferForCopy->object(), m_conditionalRenderingBuffer->object(), 1, &region);
bufferMemoryBarrier(m_conditionalRenderingBuffer->object(), m_conditionalRenderingBufferOffset, sizeof(deUint32), VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT,
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT);
}
}
beginRenderPass(m_vkd, *m_cmdBufferPrimary, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT));
deInt32 data[4] = { -1, -1, -1, -1 };
void* dataPtr = data;
for (int drawNdx = 0; drawNdx < 4; drawNdx++)
{
data[0] = drawNdx;
m_vkd.cmdPushConstants(*m_cmdBufferPrimary, *m_pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, dataPtr);
if (isBitSet(m_testParams.m_beginSequenceBits, drawNdx))
m_vkd.cmdBeginConditionalRenderingEXT(*m_cmdBufferPrimary, &conditionalRenderingBeginInfo);
draw();
if (isBitSet(m_testParams.m_endSequenceBits, drawNdx))
m_vkd.cmdEndConditionalRenderingEXT(*m_cmdBufferPrimary);
}
endRenderPass(m_vkd, *m_cmdBufferPrimary);
imageMemoryBarrier(m_colorTargetImage->object(), //VkImage image
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, //VkAccessFlags srcAccessMask
VK_ACCESS_TRANSFER_READ_BIT, //VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, //VkImageLayout oldLayout
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, //VkImageLayout newLayout
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags srcStageMask
VK_PIPELINE_STAGE_TRANSFER_BIT, //VkPipelineStageFlags dstStageMask
VK_IMAGE_ASPECT_COLOR_BIT); //VkImageAspectFlags flags
copyResultImageToBuffer(VK_IMAGE_ASPECT_COLOR_BIT, m_colorTargetImage->object());
endCommandBuffer(m_vkd, *m_cmdBufferPrimary);
submitCommandsAndWait(m_vkd, m_device, m_queue, *m_cmdBufferPrimary);
tcu::ConstPixelBufferAccess result(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), tcu::IVec3(WIDTH, HEIGHT, 1), m_resultBuffer->getBoundMemory().getHostPtr());
std::vector<float> referenceData(4 * WIDTH * HEIGHT, 0.5f);
tcu::PixelBufferAccess reference(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), tcu::IVec3(WIDTH, HEIGHT, 1), referenceData.data());
prepareReferenceImage(reference, clearColorInitial, m_testParams.m_resultBits);
if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Comparison", "Comparison", reference, result, tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR))
return tcu::TestStatus::fail("Fail");
return tcu::TestStatus::pass("Pass");
}
void ConditionalRenderingDrawTestInstance::createPipelineLayout (void)
{
const VkPushConstantRange pushConstantRange =
{
VK_SHADER_STAGE_FRAGMENT_BIT, //VkShaderStageFlags stageFlags;
0, //deUint32 offset;
16 //deUint32 size;
};
const VkPipelineLayoutCreateInfo pipelineLayoutParams =
{
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, //VkStructureType sType
DE_NULL, //const void* pNext
(VkPipelineLayoutCreateFlags)0, //VkPipelineLayoutCreateFlags flags
1u, //deUint32 descriptorSetCount
&(m_descriptorSetLayout.get()), //const VkDescriptorSetLayout* pSetLayouts
1u, //deUint32 pushConstantRangeCount
&pushConstantRange //const VkPushConstantRange* pPushConstantRanges
};
m_pipelineLayout = vk::createPipelineLayout(m_vkd, m_device, &pipelineLayoutParams);
}
void ConditionalRenderingDrawTestInstance::prepareReferenceImage (tcu::PixelBufferAccess& reference, const VkClearColorValue& clearColor, deUint32 resultBits)
{
for (int w = 0; w < WIDTH; w++)
for (int h = 0; h < HEIGHT; h++)
reference.setPixel(tcu::Vec4(clearColor.float32), w, h);
int step = (HEIGHT / 4);
for (int w = 0; w < WIDTH; w++)
for (int h = 0; h < HEIGHT; h++)
{
if (h < step && isBitSet(resultBits, 0)) reference.setPixel(tcu::Vec4(0, 1, 0, 1), w, h);
if (h >= step && h < (step * 2) && isBitSet(resultBits, 1)) reference.setPixel(tcu::Vec4(0, 1, 0, 1), w, h);
if (h >= (step * 2) && h < (step * 3) && isBitSet(resultBits, 2)) reference.setPixel(tcu::Vec4(0, 1, 0, 1), w, h);
if (h >= (step * 3) && isBitSet(resultBits, 3)) reference.setPixel(tcu::Vec4(0, 1, 0, 1), w, h);
}
}
ConditionalRenderingUpdateBufferWithDrawTestInstance::ConditionalRenderingUpdateBufferWithDrawTestInstance (Context& context, bool testParams)
: ConditionalRenderingBaseTestInstance (context)
, m_testParams (testParams)
{}
void ConditionalRenderingUpdateBufferWithDrawTestInstance::createAndUpdateDescriptorSets (void)
{
//the same descriptor set layout can be used for the creation of both descriptor sets
const VkDescriptorSetAllocateInfo allocInfo =
{
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, //VkStructureType sType
DE_NULL, //const void* pNext
*m_descriptorPool, //VkDescriptorPool descriptorPool
1u, //deUint32 setLayoutCount
&(m_descriptorSetLayout.get()) //const VkDescriptorSetLayout* pSetLayouts
};
m_descriptorSet = allocateDescriptorSet(m_vkd, m_device, &allocInfo);
VkDescriptorBufferInfo descriptorInfo = makeDescriptorBufferInfo(m_vertexBuffer->object(), (VkDeviceSize)0u, sizeof(float) * 16);
DescriptorSetUpdateBuilder()
.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
.update(m_vkd, m_device);
m_descriptorSetUpdate = allocateDescriptorSet(m_vkd, m_device, &allocInfo);
VkDescriptorBufferInfo descriptorInfoUpdate = makeDescriptorBufferInfo(m_conditionalRenderingBuffer->object(), (VkDeviceSize)0u, sizeof(deUint32));
DescriptorSetUpdateBuilder()
.writeSingle(*m_descriptorSetUpdate, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfoUpdate)
.update(m_vkd, m_device);
}
void ConditionalRenderingUpdateBufferWithDrawTestInstance::createPipelines (void)
{
const std::vector<VkViewport> viewports(1, makeViewport(tcu::UVec2(WIDTH, HEIGHT)));
const std::vector<VkRect2D> scissors(1, makeRect2D(tcu::UVec2(WIDTH, HEIGHT)));
const VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
{
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, //VkStructureType sType
DE_NULL, //const void* pNext
0u, //vkPipelineVertexInputStateCreateFlags flags
0u, //deUint32 bindingCount
DE_NULL, //const VkVertexInputBindingDescription* pVertexBindingDescriptions
0u, //deUint32 attributeCount
DE_NULL, //const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
};
m_pipelineDraw = makeGraphicsPipeline(m_vkd, //const DeviceInterface& vk
m_device, //const VkDevice device
*m_pipelineLayout, //const VkPipelineLayout pipelineLayout
*m_vertexShaderModuleDraw, //const VkShaderModule vertexShaderModule
DE_NULL, //const VkShaderModule tessellationControlShaderModule
DE_NULL, //const VkShaderModule tessellationEvalShaderModule
DE_NULL, //const VkShaderModule geometryShaderModule
*m_fragmentShaderModuleDraw, //const VkShaderModule fragmentShaderModule
*m_renderPass, //const VkRenderPass renderPass
viewports, //const std::vector<VkViewport>& viewports
scissors, //const std::vector<VkRect2D>& scissors
topology, //const VkPrimitiveTopology topology
0u, //const deUint32 subpass
0u, //const deUint32 patchControlPoints
&vertexInputStateParams); //const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
m_pipelineUpdate = makeGraphicsPipeline(m_vkd, //const DeviceInterface& vk
m_device, //const VkDevice device
*m_pipelineLayout, //const VkPipelineLayout pipelineLayout
*m_vertexShaderModuleUpdate, //const VkShaderModule vertexShaderModule
DE_NULL, //const VkShaderModule tessellationControlShaderModule
DE_NULL, //const VkShaderModule tessellationEvalShaderModule
DE_NULL, //const VkShaderModule geometryShaderModule
*m_fragmentShaderModuleDiscard, //const VkShaderModule fragmentShaderModule
*m_renderPass, //const VkRenderPass renderPass
viewports, //const std::vector<VkViewport>& viewports
scissors, //const std::vector<VkRect2D>& scissors
topology, //const VkPrimitiveTopology topology
0u, //const deUint32 subpass
0u, //const deUint32 patchControlPoints
&vertexInputStateParams); //const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
}
void ConditionalRenderingUpdateBufferWithDrawTestInstance::createRenderPass (VkFormat format, VkImageLayout layout)
{
RenderPassCreateInfo renderPassCreateInfo;
renderPassCreateInfo.addAttachment(AttachmentDescription(format,
VK_SAMPLE_COUNT_1_BIT,
VK_ATTACHMENT_LOAD_OP_LOAD,
VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE,
VK_ATTACHMENT_STORE_OP_STORE,
isDepthStencilFormat(format) ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
isDepthStencilFormat(format) ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
const VkAttachmentReference attachmentReference =
{
0u, // deUint32 attachment
layout // VkImageLayout layout
};
renderPassCreateInfo.addSubpass(SubpassDescription(VK_PIPELINE_BIND_POINT_GRAPHICS,
0,
0,
DE_NULL,
isDepthStencilFormat(format) ? 0 : 1,
isDepthStencilFormat(format) ? DE_NULL : &attachmentReference,
DE_NULL,
isDepthStencilFormat(format) ? attachmentReference : AttachmentReference(),
0,
DE_NULL));
VkSubpassDependency dependency =
{
0, //deUint32 srcSubpass;
0, //deUint32 dstSubpass;
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, //VkPipelineStageFlags srcStageMask;
VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT, //VkPipelineStageFlags dstStageMask;
VK_ACCESS_SHADER_WRITE_BIT, //VkAccessFlags srcAccessMask;
VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT, //VkAccessFlags dstAccessMask;
(VkDependencyFlags)0 //VkDependencyFlags dependencyFlags;
};
renderPassCreateInfo.addDependency(dependency);
m_renderPass = vk::createRenderPass(m_vkd, m_device, &renderPassCreateInfo);
}
tcu::TestStatus ConditionalRenderingUpdateBufferWithDrawTestInstance::iterate (void)
{
const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
VkClearColorValue clearColorInitial = { { 0.0f, 0.0f, 1.0f, 1.0f } };
createInitBufferWithPredicate(m_testParams, true, 0, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
createTargetColorImageAndImageView();
createResultBuffer(VK_FORMAT_R8G8B8A8_UNORM);
createVertexBuffer();
m_cmdPool = createCommandPool(m_vkd, m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
m_cmdBufferPrimary = allocateCommandBuffer(m_vkd, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
createRenderPass(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
createFramebuffer(m_colorTargetView.get());
DescriptorSetLayoutBuilder builder;
builder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
m_descriptorSetLayout = builder.build(m_vkd, m_device, (VkDescriptorSetLayoutCreateFlags)0);
m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2)
.build(m_vkd, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u);
createPipelineLayout();
createAndUpdateDescriptorSets();
m_vertexShaderModuleDraw = createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("position_only.vert"), 0);
m_fragmentShaderModuleDraw = createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("only_color_out.frag"), 0);
m_vertexShaderModuleUpdate = createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("update.vert"), 0);
m_fragmentShaderModuleDiscard = createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("discard.frag"), 0);
createPipelines();
VkConditionalRenderingBeginInfoEXT conditionalRenderingBeginInfo =
{
VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT, //VkStructureType sType;
DE_NULL, //const void* pNext;
m_conditionalRenderingBuffer->object(), //VkBuffer buffer;
0, //VkDeviceSize offset;
VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT //VkConditionalRenderingFlagsEXT flags;
};
beginCommandBuffer(m_vkd, *m_cmdBufferPrimary);
imageMemoryBarrier(m_colorTargetImage->object(), //VkImage image
0u, //VkAccessFlags srcAccessMask
VK_ACCESS_TRANSFER_WRITE_BIT, //VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_UNDEFINED, //VkImageLayout oldLayout
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, //VkImageLayout newLayout
VK_PIPELINE_STAGE_TRANSFER_BIT, //VkPipelineStageFlags srcStageMask
VK_PIPELINE_STAGE_TRANSFER_BIT, //VkPipelineStageFlags dstStageMask
VK_IMAGE_ASPECT_COLOR_BIT); //VkImageAspectFlags flags
clearWithClearColorImage(clearColorInitial);
imageMemoryBarrier(m_colorTargetImage->object(), //VkImage image
VK_ACCESS_TRANSFER_WRITE_BIT, //VkAccessFlags srcAccessMask
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, //VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, //VkImageLayout oldLayout
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, //VkImageLayout newLayout
VK_PIPELINE_STAGE_TRANSFER_BIT, //VkPipelineStageFlags srcStageMask
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags dstStageMask
VK_IMAGE_ASPECT_COLOR_BIT); //VkImageAspectFlags flags
beginRenderPass(m_vkd, *m_cmdBufferPrimary, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT));
m_vkd.cmdBindPipeline(*m_cmdBufferPrimary, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineUpdate);
m_vkd.cmdBindDescriptorSets(*m_cmdBufferPrimary, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &(*m_descriptorSetUpdate), 0, DE_NULL);
draw();
bufferMemoryBarrier(m_conditionalRenderingBuffer->object(), m_conditionalRenderingBufferOffset, sizeof(deUint32), VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT,
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT);
m_vkd.cmdBindPipeline(*m_cmdBufferPrimary, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineDraw);
m_vkd.cmdBindDescriptorSets(*m_cmdBufferPrimary, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &(*m_descriptorSet), 0, DE_NULL);
m_vkd.cmdBeginConditionalRenderingEXT(*m_cmdBufferPrimary, &conditionalRenderingBeginInfo);
draw();
m_vkd.cmdEndConditionalRenderingEXT(*m_cmdBufferPrimary);
endRenderPass(m_vkd, *m_cmdBufferPrimary);
imageMemoryBarrier(m_colorTargetImage->object(), //VkImage image
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, //VkAccessFlags srcAccessMask
VK_ACCESS_TRANSFER_READ_BIT, //VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, //VkImageLayout oldLayout
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, //VkImageLayout newLayout
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags srcStageMask
VK_PIPELINE_STAGE_TRANSFER_BIT, //VkPipelineStageFlags dstStageMask
VK_IMAGE_ASPECT_COLOR_BIT); //VkImageAspectFlags flags
copyResultImageToBuffer(VK_IMAGE_ASPECT_COLOR_BIT, m_colorTargetImage->object());
endCommandBuffer(m_vkd, *m_cmdBufferPrimary);
submitCommandsAndWait(m_vkd, m_device, m_queue, *m_cmdBufferPrimary);
tcu::ConstPixelBufferAccess result(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), tcu::IVec3(WIDTH, HEIGHT, 1), m_resultBuffer->getBoundMemory().getHostPtr());
std::vector<float> referenceData(4 * WIDTH * HEIGHT, 0.0f);
tcu::PixelBufferAccess reference(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), tcu::IVec3(WIDTH, HEIGHT, 1), referenceData.data());
m_testParams ? prepareReferenceImageOneColor(reference, tcu::Vec4(0,1,0,1)) : prepareReferenceImageOneColor(reference, clearColorInitial);
flushMappedMemoryRange(m_vkd, m_device, m_conditionalRenderingBuffer->getBoundMemory().getMemory(), m_conditionalRenderingBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Comparison", "Comparison", reference, result, tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR))
return tcu::TestStatus::fail("Fail");
return tcu::TestStatus::pass("Pass");
}
struct AddProgramsDraw
{
void init (SourceCollections& sources, DrawTestParams testParams) const
{
DE_UNREF(testParams);
const char* const vertexShader =
"#version 430\n"
"layout(std430, binding = 0) buffer BufferPos {\n"
"vec4 p[100];\n"
"} pos;\n"
"out gl_PerVertex{\n"
"vec4 gl_Position;\n"
"};\n"
"void main() {\n"
"gl_Position = pos.p[gl_VertexIndex];\n"
"}\n";
sources.glslSources.add("position_only.vert") << glu::VertexSource(vertexShader);
const char* const fragmentShader =
"#version 430\n"
"layout(location = 0) out vec4 my_FragColor;\n"
"layout (push_constant) uniform AreaSelect {\n"
" ivec4 number;\n"
"} Area;\n"
"void main() {\n"
" if((gl_FragCoord.y < 64) && (Area.number.x != 0)) discard;\n"
" if((gl_FragCoord.y >= 64) && (gl_FragCoord.y < 128) && (Area.number.x != 1)) discard;\n"
" if((gl_FragCoord.y >= 128) && (gl_FragCoord.y < 192) && (Area.number.x != 2)) discard;\n"
" if((gl_FragCoord.y >= 192) && (Area.number.x != 3)) discard;\n"
" my_FragColor = vec4(0,1,0,1);\n"
"}\n";
sources.glslSources.add("only_color_out.frag") << glu::FragmentSource(fragmentShader);
}
};
struct AddProgramsUpdateBufferUsingRendering
{
void init (SourceCollections& sources, bool testParams) const
{
std::string atomicOperation = (testParams ? "atomicMin(predicate.p, 0);" : "atomicMax(predicate.p, 1);");
std::string vertexShaderUpdate =
"#version 430\n"
"layout(std430, binding = 0) buffer Predicate {\n"
"uint p;\n"
"} predicate;\n"
"out gl_PerVertex{\n"
"vec4 gl_Position;\n"
"};\n"
"void main() {\n" +
atomicOperation +
"gl_Position = vec4(1.0);\n"
"}\n";
sources.glslSources.add("update.vert") << glu::VertexSource(vertexShaderUpdate);
const char* const vertexShaderDraw =
"#version 430\n"
"layout(std430, binding = 0) buffer BufferPos {\n"
"vec4 p[100];\n"
"} pos;\n"
"out gl_PerVertex{\n"
"vec4 gl_Position;\n"
"};\n"
"void main() {\n"
"gl_Position = pos.p[gl_VertexIndex];\n"
"}\n";
sources.glslSources.add("position_only.vert") << glu::VertexSource(vertexShaderDraw);
const char* const fragmentShaderDiscard =
"#version 430\n"
"layout(location = 0) out vec4 my_FragColor;\n"
"void main() {\n"
" discard;\n"
"}\n";
sources.glslSources.add("discard.frag")
<< glu::FragmentSource(fragmentShaderDiscard);
const char* const fragmentShaderDraw =
"#version 430\n"
"layout(location = 0) out vec4 my_FragColor;\n"
"void main() {\n"
" my_FragColor = vec4(0,1,0,1);\n"
"}\n";
sources.glslSources.add("only_color_out.frag") << glu::FragmentSource(fragmentShaderDraw);
}
};
void checkSupport (Context& context)
{
context.requireDeviceFunctionality("VK_EXT_conditional_rendering");
}
} // unnamed namespace
ConditionalRenderingDrawAndClearTests::ConditionalRenderingDrawAndClearTests (tcu::TestContext &testCtx)
: TestCaseGroup (testCtx, "draw_clear", "VK_EXT_conditional_rendering extension tests")
{
/* Left blank on purpose */
}
void ConditionalRenderingDrawAndClearTests::init (void)
{
tcu::TestCaseGroup* clear = new tcu::TestCaseGroup(m_testCtx, "clear", "Tests using vkCmdClearAttachments.");
tcu::TestCaseGroup* color = new tcu::TestCaseGroup(m_testCtx, "color", "Test color clear.");
tcu::TestCaseGroup* depth = new tcu::TestCaseGroup(m_testCtx, "depth", "Test depth clear.");
tcu::TestCaseGroup* draw = new tcu::TestCaseGroup(m_testCtx, "draw", "Test drawing.");
for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(clearColorTestGrid); testNdx++)
color->addChild(new InstanceFactory1WithSupport<ConditionalRenderingClearAttachmentsTestInstance, ClearTestParams, FunctionSupport0>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, generateClearTestName(clearColorTestGrid[testNdx]), "Color clear test.", clearColorTestGrid[testNdx], checkSupport));
for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(clearDepthTestGrid); testNdx++)
depth->addChild(new InstanceFactory1WithSupport<ConditionalRenderingClearAttachmentsTestInstance, ClearTestParams, FunctionSupport0>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, generateClearTestName(clearDepthTestGrid[testNdx]), "Depth clear test.", clearDepthTestGrid[testNdx], checkSupport));
for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(clearColorTwiceGrid); testNdx++)
color->addChild(new InstanceFactory1WithSupport<ConditionalRenderingClearAttachmentsTestInstance, ClearTestParams, FunctionSupport0>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, "clear_attachment_twice_" + generateClearTestName(clearColorTwiceGrid[testNdx]), "Color clear test.", clearColorTwiceGrid[testNdx], checkSupport));
for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(clearDepthTwiceGrid); testNdx++)
depth->addChild(new InstanceFactory1WithSupport<ConditionalRenderingClearAttachmentsTestInstance, ClearTestParams, FunctionSupport0>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, "clear_attachment_twice_" + generateClearTestName(clearDepthTwiceGrid[testNdx]), "Depth clear test.", clearDepthTwiceGrid[testNdx], checkSupport));
for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(drawTestGrid); testNdx++)
draw->addChild(new InstanceFactory1WithSupport<ConditionalRenderingDrawTestInstance, DrawTestParams, FunctionSupport0, AddProgramsDraw>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, "case_" + de::toString(testNdx), "Draw test.", AddProgramsDraw(), drawTestGrid[testNdx], checkSupport));
draw->addChild(new InstanceFactory1WithSupport<ConditionalRenderingUpdateBufferWithDrawTestInstance, bool, FunctionSupport0, AddProgramsUpdateBufferUsingRendering>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, "update_with_rendering_no_discard", "Draw test.", AddProgramsUpdateBufferUsingRendering(), true, checkSupport));
draw->addChild(new InstanceFactory1WithSupport<ConditionalRenderingUpdateBufferWithDrawTestInstance, bool, FunctionSupport0, AddProgramsUpdateBufferUsingRendering>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, "update_with_rendering_discard", "Draw test.", AddProgramsUpdateBufferUsingRendering(), false, checkSupport));
clear->addChild(color);
clear->addChild(depth);
addChild(clear);
addChild(draw);
}
} // Draw
} // vkt