INTERPOLATIONFLAGS_FLATSHADE = (1 << 2),
};
+enum ResolutionValues
+{
+ RESOLUTION_POT = 256,
+ RESOLUTION_NPOT = 258
+};
+
enum PrimitiveWideness
{
PRIMITIVEWIDENESS_NARROW = 0,
class BaseRenderingTestInstance : public TestInstance
{
public:
- enum {
- DEFAULT_RENDER_SIZE = 256
- };
-
- BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deUint32 renderSize = DEFAULT_RENDER_SIZE, VkFormat imageFormat = VK_FORMAT_R8G8B8A8_UNORM);
+ BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deUint32 renderSize = RESOLUTION_POT, VkFormat imageFormat = VK_FORMAT_R8G8B8A8_UNORM, deUint32 additionalRenderSize = 0);
~BaseRenderingTestInstance (void);
protected:
void addImageTransitionBarrier (VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const;
void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology);
void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, const std::vector<tcu::Vec4>& coloDrata, VkPrimitiveTopology primitiveTopology);
+ void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology,
+ VkImage image, VkImage resolvedImage, VkFramebuffer frameBuffer, const deUint32 renderSize, VkBuffer resultBuffer, const Allocation& resultBufferMemory);
virtual float getLineWidth (void) const;
virtual float getPointSize (void) const;
virtual bool getLineStippleDynamic (void) const { return false; };
Move<VkBuffer> m_resultBuffer;
de::MovePtr<Allocation> m_resultBufferMemory;
const VkDeviceSize m_resultBufferSize;
+
+ const deUint32 m_additionalRenderSize;
+ const VkDeviceSize m_additionalResultBufferSize;
};
-BaseRenderingTestInstance::BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount, deUint32 renderSize, VkFormat imageFormat)
+BaseRenderingTestInstance::BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount, deUint32 renderSize, VkFormat imageFormat, deUint32 additionalRenderSize)
: TestInstance (context)
, m_renderSize (renderSize)
, m_sampleCount (sampleCount)
, m_textureFormat (vk::mapVkFormat(m_imageFormat))
, m_uniformBufferSize (sizeof(float))
, m_resultBufferSize (renderSize * renderSize * m_textureFormat.getPixelSize())
+ , m_additionalRenderSize(additionalRenderSize)
+ , m_additionalResultBufferSize(additionalRenderSize * additionalRenderSize * m_textureFormat.getPixelSize())
{
const DeviceInterface& vkd = m_context.getDeviceInterface();
const VkDevice vkDevice = m_context.getDevice();
void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology)
{
+ drawPrimitives(result, positionData, colorData, primitiveTopology, *m_image, *m_resolvedImage, *m_frameBuffer, m_renderSize, *m_resultBuffer, *m_resultBufferMemory);
+}
+void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology,
+ VkImage image, VkImage resolvedImage, VkFramebuffer frameBuffer, const deUint32 renderSize, VkBuffer resultBuffer, const Allocation& resultBufferMemory)
+{
const DeviceInterface& vkd = m_context.getDeviceInterface();
const VkDevice vkDevice = m_context.getDevice();
const VkQueue queue = m_context.getUniversalQueue();
vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
};
- const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(m_renderSize)));
- const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(m_renderSize)));
+ const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(renderSize)));
+ const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(renderSize)));
const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
{
// Begin Command Buffer
beginCommandBuffer(vkd, *commandBuffer);
- addImageTransitionBarrier(*commandBuffer, *m_image,
+ addImageTransitionBarrier(*commandBuffer, image,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
0, // VkAccessFlags srcAccessMask
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
if (m_multisampling) {
- addImageTransitionBarrier(*commandBuffer, *m_resolvedImage,
+ addImageTransitionBarrier(*commandBuffer, resolvedImage,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
0, // VkAccessFlags srcAccessMask
}
// Begin Render Pass
- beginRenderPass(vkd, *commandBuffer, *m_renderPass, *m_frameBuffer, vk::makeRect2D(0, 0, m_renderSize, m_renderSize), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+ beginRenderPass(vkd, *commandBuffer, *m_renderPass, frameBuffer, vk::makeRect2D(0, 0, renderSize, renderSize), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
const VkDeviceSize vertexBufferOffset = 0;
endRenderPass(vkd, *commandBuffer);
// Copy Image
- copyImageToBuffer(vkd, *commandBuffer, m_multisampling ? *m_resolvedImage : *m_image, *m_resultBuffer, tcu::IVec2(m_renderSize, m_renderSize));
+ copyImageToBuffer(vkd, *commandBuffer, m_multisampling ? resolvedImage : image, resultBuffer, tcu::IVec2(renderSize, renderSize));
endCommandBuffer(vkd, *commandBuffer);
// Submit
submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());
- invalidateAlloc(vkd, vkDevice, *m_resultBufferMemory);
- tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderSize, m_renderSize, 1), m_resultBufferMemory->getHostPtr()));
+ invalidateAlloc(vkd, vkDevice, resultBufferMemory);
+ tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(renderSize, renderSize, 1), resultBufferMemory.getHostPtr()));
}
float BaseRenderingTestInstance::getLineWidth (void) const
PrimitiveWideness wideness,
VkSampleCountFlagBits sampleCount,
LineStipple stipple,
- VkLineRasterizationModeEXT lineRasterizationMode);
+ VkLineRasterizationModeEXT lineRasterizationMode,
+ const deUint32 additionalRenderSize = 0);
virtual tcu::TestStatus iterate (void);
virtual float getLineWidth (void) const;
bool getLineStippleEnable (void) const { return m_stipple != LINESTIPPLE_DISABLED; }
private:
virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines) = DE_NULL;
+ bool resultHasAlpha (tcu::Surface& result);
+
int m_iteration;
const int m_iterationCount;
VkPrimitiveTopology m_primitiveTopology;
std::vector<float> m_lineWidths;
LineStipple m_stipple;
VkLineRasterizationModeEXT m_lineRasterizationMode;
+ Move<VkImage> m_additionalImage;
+ de::MovePtr<Allocation> m_additionalImageMemory;
+ Move<VkImageView> m_additionalImageView;
+ Move<VkImage> m_additionalResolvedImage;
+ de::MovePtr<Allocation> m_additionalResolvedImageMemory;
+ Move<VkImageView> m_additionalResolvedImageView;
+ Move<VkFramebuffer> m_additionalFrameBuffer;
+ Move<VkBuffer> m_additionalResultBuffer;
+ de::MovePtr<Allocation> m_additionalResultBufferMemory;
};
BaseLineTestInstance::BaseLineTestInstance (Context& context,
PrimitiveWideness wideness,
VkSampleCountFlagBits sampleCount,
LineStipple stipple,
- VkLineRasterizationModeEXT lineRasterizationMode)
- : BaseRenderingTestInstance (context, sampleCount)
+ VkLineRasterizationModeEXT lineRasterizationMode,
+ const deUint32 additionalRenderSize)
+ : BaseRenderingTestInstance (context, sampleCount, RESOLUTION_POT, VK_FORMAT_R8G8B8A8_UNORM, additionalRenderSize)
, m_iteration (0)
, m_iterationCount (3)
, m_primitiveTopology (primitiveTopology)
}
else
DE_ASSERT(false);
+
+ // Create image, image view and frame buffer for testing at an additional resolution if required.
+ if (m_additionalRenderSize != 0)
+ {
+ const DeviceInterface& vkd = m_context.getDeviceInterface();
+ const VkDevice vkDevice = m_context.getDevice();
+ const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
+ Allocator& allocator = m_context.getDefaultAllocator();
+ DescriptorPoolBuilder descriptorPoolBuilder;
+ DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
+ {
+ const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+ const VkImageCreateInfo imageCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkImageCreateFlags flags;
+ VK_IMAGE_TYPE_2D, // VkImageType imageType;
+ m_imageFormat, // VkFormat format;
+ { m_additionalRenderSize, m_additionalRenderSize, 1u }, // VkExtent3D extent;
+ 1u, // deUint32 mipLevels;
+ 1u, // deUint32 arrayLayers;
+ m_sampleCount, // VkSampleCountFlagBits samples;
+ VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
+ imageUsage, // VkImageUsageFlags usage;
+ VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
+ 1u, // deUint32 queueFamilyIndexCount;
+ &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
+ VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
+ };
+
+ m_additionalImage = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
+
+ m_additionalImageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_additionalImage), MemoryRequirement::Any);
+ VK_CHECK(vkd.bindImageMemory(vkDevice, *m_additionalImage, m_additionalImageMemory->getMemory(), m_additionalImageMemory->getOffset()));
+ }
+
+ // Image View
+ {
+ const VkImageViewCreateInfo imageViewCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkImageViewCreateFlags flags;
+ *m_additionalImage, // VkImage image;
+ VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
+ m_imageFormat, // VkFormat format;
+ makeComponentMappingRGBA(), // VkComponentMapping components;
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // deUint32 baseMipLevel;
+ 1u, // deUint32 mipLevels;
+ 0u, // deUint32 baseArrayLayer;
+ 1u, // deUint32 arraySize;
+ }, // VkImageSubresourceRange subresourceRange;
+ };
+
+ m_additionalImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
+ }
+
+ if (m_multisampling)
+ {
+ {
+ const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+ const VkImageCreateInfo imageCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkImageCreateFlags flags;
+ VK_IMAGE_TYPE_2D, // VkImageType imageType;
+ m_imageFormat, // VkFormat format;
+ { m_additionalRenderSize, m_additionalRenderSize, 1u }, // VkExtent3D extent;
+ 1u, // deUint32 mipLevels;
+ 1u, // deUint32 arrayLayers;
+ VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
+ VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
+ imageUsage, // VkImageUsageFlags usage;
+ VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
+ 1u, // deUint32 queueFamilyIndexCount;
+ &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
+ VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
+ };
+
+ m_additionalResolvedImage = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
+ m_additionalResolvedImageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_additionalResolvedImage), MemoryRequirement::Any);
+ VK_CHECK(vkd.bindImageMemory(vkDevice, *m_additionalResolvedImage, m_additionalResolvedImageMemory->getMemory(), m_additionalResolvedImageMemory->getOffset()));
+ }
+
+ // Image view
+ {
+ const VkImageViewCreateInfo imageViewCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkImageViewCreateFlags flags;
+ *m_additionalResolvedImage, // VkImage image;
+ VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
+ m_imageFormat, // VkFormat format;
+ makeComponentMappingRGBA(), // VkComponentMapping components;
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // deUint32 baseMipLevel;
+ 1u, // deUint32 mipLevels;
+ 0u, // deUint32 baseArrayLayer;
+ 1u, // deUint32 arraySize;
+ }, // VkImageSubresourceRange subresourceRange;
+ };
+ m_additionalResolvedImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
+ }
+ }
+
+ {
+ const VkImageView attachments[] =
+ {
+ *m_additionalImageView,
+ *m_additionalResolvedImageView
+ };
+
+ const VkFramebufferCreateInfo framebufferCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkFramebufferCreateFlags flags;
+ *m_renderPass, // VkRenderPass renderPass;
+ m_multisampling ? 2u : 1u, // deUint32 attachmentCount;
+ attachments, // const VkImageView* pAttachments;
+ m_additionalRenderSize, // deUint32 width;
+ m_additionalRenderSize, // deUint32 height;
+ 1u, // deUint32 layers;
+ };
+ m_additionalFrameBuffer = createFramebuffer(vkd, vkDevice, &framebufferCreateInfo, DE_NULL);
+ }
+
+ // Framebuffer
+ {
+ const VkBufferCreateInfo bufferCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkBufferCreateFlags flags;
+ m_additionalResultBufferSize, // VkDeviceSize size;
+ VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
+ VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
+ 1u, // deUint32 queueFamilyIndexCount;
+ &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
+ };
+
+ m_additionalResultBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo);
+ m_additionalResultBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_additionalResultBuffer), MemoryRequirement::HostVisible);
+
+ VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_additionalResultBuffer, m_additionalResultBufferMemory->getMemory(), m_additionalResultBufferMemory->getOffset()));
+ }
+ }
+}
+
+bool BaseLineTestInstance::resultHasAlpha(tcu::Surface& resultImage)
+{
+ bool hasAlpha = false;
+ for (int y = 0; y < resultImage.getHeight() && !hasAlpha; ++y)
+ for (int x = 0; x < resultImage.getWidth(); ++x)
+ {
+ const tcu::RGBA color = resultImage.getPixel(x, y);
+ if (color.getAlpha() > 0 && color.getAlpha() < 0xFF)
+ {
+ hasAlpha = true;
+ break;
+ }
+ }
+ return hasAlpha;
}
tcu::TestStatus BaseLineTestInstance::iterate (void)
const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
const float lineWidth = getLineWidth();
tcu::Surface resultImage (m_renderSize, m_renderSize);
+ tcu::Surface additionalResultImage (m_additionalRenderSize, m_additionalRenderSize);
std::vector<tcu::Vec4> drawBuffer;
std::vector<LineSceneSpec::SceneLine> lines;
drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
// compare
- {
- RasterizationArguments args;
- LineSceneSpec scene;
+ RasterizationArguments args;
+ LineSceneSpec scene;
+ tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
- tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
+ args.numSamples = m_multisampling ? 1 : 0;
+ args.subpixelBits = m_subpixelBits;
+ args.redBits = colorBits[0];
+ args.greenBits = colorBits[1];
+ args.blueBits = colorBits[2];
- args.numSamples = m_multisampling ? 1 : 0;
- args.subpixelBits = m_subpixelBits;
- args.redBits = colorBits[0];
- args.greenBits = colorBits[1];
- args.blueBits = colorBits[2];
+ scene.lines.swap(lines);
+ scene.lineWidth = lineWidth;
+ scene.stippleEnable = getLineStippleEnable();
+ scene.stippleFactor = getLineStippleEnable() ? lineStippleFactor : 1;
+ scene.stipplePattern = getLineStippleEnable() ? lineStipplePattern : 0xFFFF;
+ scene.isStrip = m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
+ scene.isSmooth = m_lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
+
+ // Choose verification mode. Smooth lines assume mostly over-rasterization (bloated lines with a falloff).
+ // Stippled lines lose some precision across segments in a strip, so need a weaker threshold than normal
+ // lines. For simple cases, check for an exact match (STRICT).
+ if (scene.isSmooth)
+ scene.verificationMode = tcu::VERIFICATIONMODE_SMOOTH;
+ else if (scene.stippleEnable)
+ scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
+ else
+ scene.verificationMode = tcu::VERIFICATIONMODE_STRICT;
- scene.lines.swap(lines);
- scene.lineWidth = lineWidth;
- scene.stippleEnable = getLineStippleEnable();
- scene.stippleFactor = getLineStippleEnable() ? lineStippleFactor : 1;
- scene.stipplePattern = getLineStippleEnable() ? lineStipplePattern : 0xFFFF;
- scene.isStrip = m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
- scene.isSmooth = m_lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
-
- // Choose verification mode. Smooth lines assume mostly over-rasterization (bloated lines with a falloff).
- // Stippled lines lose some precision across segments in a strip, so need a weaker threshold than normal
- // lines. For simple cases, check for an exact match (STRICT).
+ if (m_lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT)
+ {
+ // bresenham is "no AA" in GL, so set numSamples to zero.
+ args.numSamples = 0;
+ if (!verifyLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog()))
+ m_allIterationsPassed = false;
+ }
+ else
+ {
if (scene.isSmooth)
- scene.verificationMode = tcu::VERIFICATIONMODE_SMOOTH;
- else if (scene.stippleEnable)
- scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
- else
- scene.verificationMode = tcu::VERIFICATIONMODE_STRICT;
+ {
+ // Smooth lines get the fractional coverage multiplied into the alpha component,
+ // so do a sanity check to validate that there is at least one pixel in the image
+ // with a fractional opacity.
+ bool hasAlpha = resultHasAlpha(resultImage);
+ if (!hasAlpha)
+ {
+ m_context.getTestContext().getLog() << tcu::TestLog::Message << "Missing alpha transparency (failed)." << tcu::TestLog::EndMessage;
+ m_allIterationsPassed = false;
+ }
+ }
- if (m_lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT)
+ if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), (0 == m_multisampling)))
{
- // bresenham is "no AA" in GL, so set numSamples to zero.
- args.numSamples = 0;
- if (!verifyLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog()))
+ // Retry with weaker verification. If it passes, consider it a quality warning.
+ scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
+ if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog()))
m_allIterationsPassed = false;
+ else
+ m_qualityWarning = true;
}
- else
+
+ if (m_additionalRenderSize != 0)
{
+ const std::vector<tcu::Vec4> colorData(drawBuffer.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
+
if (scene.isSmooth)
- {
- // Smooth lines get the fractional coverage multiplied into the alpha component,
- // so do a sanity check to validate that there is at least one pixel in the image
- // with a fractional opacity.
- bool hasAlpha = false;
- for (int y = 0; y < resultImage.getHeight() && !hasAlpha; ++y)
- for (int x = 0; x < resultImage.getWidth(); ++x)
- {
- const tcu::RGBA color = resultImage.getPixel(x, y);
- if (color.getAlpha() > 0 && color.getAlpha() < 0xFF)
- {
- hasAlpha = true;
- break;
- }
- }
- if (!hasAlpha)
- {
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Missing alpha transparency (failed)." << tcu::TestLog::EndMessage;
- m_allIterationsPassed = false;
- }
- }
+ scene.verificationMode = tcu::VERIFICATIONMODE_SMOOTH;
+ else if (scene.stippleEnable)
+ scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
+ else
+ scene.verificationMode = tcu::VERIFICATIONMODE_STRICT;
- if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog()))
+ drawPrimitives(additionalResultImage, drawBuffer, colorData, m_primitiveTopology, *m_additionalImage, *m_additionalResolvedImage, *m_additionalFrameBuffer, m_additionalRenderSize, *m_additionalResultBuffer, *m_additionalResultBufferMemory);
+
+ // Compare
+ if (!verifyRelaxedLineGroupRasterization(additionalResultImage, scene, args, m_context.getTestContext().getLog(), (0 == m_multisampling)))
{
// Retry with weaker verification. If it passes, consider it a quality warning.
scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
- if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog()))
+ if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), (0 == m_multisampling)))
m_allIterationsPassed = false;
else
m_qualityWarning = true;
class PointTestInstance : public BaseRenderingTestInstance
{
public:
- PointTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount, /*ignored*/LineStipple stipple, /*ignored*/VkLineRasterizationModeEXT lineRasterizationMode);
+ PointTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount, /*ignored*/LineStipple stipple, /*ignored*/VkLineRasterizationModeEXT lineRasterizationMode, deUint32 renderSize);
virtual tcu::TestStatus iterate (void);
virtual float getPointSize (void) const;
std::vector<float> m_pointSizes;
};
-PointTestInstance::PointTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount, /*ignored*/LineStipple stipple, /*ignored*/VkLineRasterizationModeEXT lineRasterizationMode)
+PointTestInstance::PointTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount, /*ignored*/LineStipple stipple, /*ignored*/VkLineRasterizationModeEXT lineRasterizationMode, deUint32)
: BaseRenderingTestInstance (context, sampleCount)
, m_iteration (0)
, m_iterationCount (3)
class WidenessTestCase : public BaseRenderingTestCase
{
public:
- WidenessTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, PrimitiveWideness wideness, bool isLineTest, VkSampleCountFlagBits sampleCount, LineStipple stipple, VkLineRasterizationModeEXT lineRasterizationMode)
+ WidenessTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, PrimitiveWideness wideness, bool isLineTest, VkSampleCountFlagBits sampleCount, LineStipple stipple, VkLineRasterizationModeEXT lineRasterizationMode, deUint32 additionalRenderSize = 0)
: BaseRenderingTestCase(context, name, description, sampleCount)
- , m_wideness(wideness)
+ , m_wideness (wideness)
, m_isLineTest (isLineTest)
, m_stipple(stipple)
, m_lineRasterizationMode(lineRasterizationMode)
+ , m_additionalRenderSize (additionalRenderSize)
{}
virtual TestInstance* createInstance (Context& context) const
{
- return new ConcreteTestInstance(context, m_wideness, m_sampleCount, m_stipple, m_lineRasterizationMode);
+ return new ConcreteTestInstance(context, m_wideness, m_sampleCount, m_stipple, m_lineRasterizationMode, m_additionalRenderSize);
}
virtual void checkSupport (Context& context) const
virtual bool getLineStippleDynamic (void) const { return m_stipple == LINESTIPPLE_DYNAMIC; };
protected:
- const PrimitiveWideness m_wideness;
- const bool m_isLineTest;
+ const PrimitiveWideness m_wideness;
+ const bool m_isLineTest;
const LineStipple m_stipple;
const VkLineRasterizationModeEXT m_lineRasterizationMode;
+ const deUint32 m_additionalRenderSize;
};
class LinesTestInstance : public BaseLineTestInstance
{
public:
- LinesTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount, LineStipple stipple, VkLineRasterizationModeEXT lineRasterizationMode)
- : BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, wideness, sampleCount, stipple, lineRasterizationMode)
+ LinesTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount, LineStipple stipple, VkLineRasterizationModeEXT lineRasterizationMode, deUint32 additionalRenderSize = 0)
+ : BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, wideness, sampleCount, stipple, lineRasterizationMode, additionalRenderSize)
{}
virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
void LinesTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
{
- outData.resize(6);
+ outData.resize(8);
switch (iteration)
{
outData[3] = tcu::Vec4(-0.3f, 0.2f, 0.0f, 1.0f);
outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
outData[5] = tcu::Vec4( 0.1f, 0.5f, 0.0f, 1.0f);
+ outData[6] = tcu::Vec4( 0.75f, -0.4f, 0.0f, 1.0f);
+ outData[7] = tcu::Vec4( 0.3f, 0.8f, 0.0f, 1.0f);
break;
case 1:
outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
outData[5] = tcu::Vec4( 0.18f, -0.2f, 0.0f, 1.0f);
+ outData[6] = tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f);
+ outData[7] = tcu::Vec4( 0.0f, -1.0f, 0.0f, 1.0f);
break;
case 2:
outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
- outData[1] = tcu::Vec4( 0.9f, -0.9f, 0.0f, 1.0f);
+ outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
outData[5] = tcu::Vec4( 0.8f, -0.7f, 0.0f, 1.0f);
+ outData[6] = tcu::Vec4( 1.0f, 0.0f, 0.0f, 1.0f);
+ outData[7] = tcu::Vec4( -1.0f, 0.0f, 0.0f, 1.0f);
break;
}
- outLines.resize(3);
+ outLines.resize(4);
outLines[0].positions[0] = outData[0];
outLines[0].positions[1] = outData[1];
outLines[1].positions[0] = outData[2];
outLines[1].positions[1] = outData[3];
outLines[2].positions[0] = outData[4];
outLines[2].positions[1] = outData[5];
+ outLines[3].positions[0] = outData[6];
+ outLines[3].positions[1] = outData[7];
// log
m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outLines.size() << " lines(s): (width = " << getLineWidth() << ")" << tcu::TestLog::EndMessage;
class LineStripTestInstance : public BaseLineTestInstance
{
public:
- LineStripTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount, LineStipple stipple, VkLineRasterizationModeEXT lineRasterizationMode)
+ LineStripTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount, LineStipple stipple, VkLineRasterizationModeEXT lineRasterizationMode, deUint32)
: BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, wideness, sampleCount, stipple, lineRasterizationMode)
{}
int FillRuleTestInstance::getRenderSize (FillRuleCaseType type) const
{
if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
- return DEFAULT_RENDER_SIZE / 4;
+ return RESOLUTION_POT / 4;
else
- return DEFAULT_RENDER_SIZE;
+ return RESOLUTION_POT;
}
int FillRuleTestInstance::getNumIterations (FillRuleCaseType type) const
{
public:
CullingTestInstance (Context& context, VkCullModeFlags cullMode, VkPrimitiveTopology primitiveTopology, VkFrontFace frontFace, VkPolygonMode polygonMode)
- : BaseRenderingTestInstance (context, VK_SAMPLE_COUNT_1_BIT, DEFAULT_RENDER_SIZE)
+ : BaseRenderingTestInstance (context, VK_SAMPLE_COUNT_1_BIT, RESOLUTION_POT)
, m_cullMode (cullMode)
, m_primitiveTopology (primitiveTopology)
, m_frontFace (frontFace)
{
public:
DiscardTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, deBool queryFragmentShaderInvocations)
- : BaseRenderingTestInstance (context, VK_SAMPLE_COUNT_1_BIT, DEFAULT_RENDER_SIZE)
+ : BaseRenderingTestInstance (context, VK_SAMPLE_COUNT_1_BIT, RESOLUTION_POT)
, m_primitiveTopology (primitiveTopology)
, m_queryFragmentShaderInvocations (queryFragmentShaderInvocations)
{}
public:
TriangleInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, VkSampleCountFlagBits sampleCount)
- : BaseRenderingTestInstance (context, sampleCount, DEFAULT_RENDER_SIZE)
+ : BaseRenderingTestInstance (context, sampleCount, RESOLUTION_POT)
, m_primitiveTopology (primitiveTopology)
, m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
, m_iterationCount (3)
LineStipple stipple = (LineStipple)i;
- g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
+ g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, i == 0 ? RESOLUTION_NPOT : 0));
g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "line_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result", PRIMITIVEWIDENESS_NARROW, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "line_strip_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
LineStipple stipple = (LineStipple)i;
- g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
+ g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, i == 0 ? RESOLUTION_NPOT : 0));
g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "line_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result", PRIMITIVEWIDENESS_NARROW, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "line_strip_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
#include "vkAllocationCallbackUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
+#include "vkBarrierUtil.hpp"
#include "tcuCommandLine.hpp"
#include "tcuTestLog.hpp"
const VkDevice device,
Allocator& allocator,
const BinaryCollection& binaryRegistry,
+ bool explicitLayoutTransitions,
const vector<VkImage> swapchainImages,
+ const vector<VkImage> aliasImages,
const VkFormat framebufferFormat,
const UVec2& renderSize);
~TriangleRenderer (void);
private:
static Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
const VkDevice device,
- const VkFormat colorAttachmentFormat);
+ const VkFormat colorAttachmentFormat,
+ const bool explicitLayoutTransitions);
static Move<VkPipelineLayout> createPipelineLayout(const DeviceInterface& vkd,
VkDevice device);
static Move<VkPipeline> createPipeline (const DeviceInterface& vkd,
const DeviceInterface& m_vkd;
+ const bool m_explicitLayoutTransitions;
const vector<VkImage> m_swapchainImages;
+ const vector<VkImage> m_aliasImages;
const tcu::UVec2 m_renderSize;
const Unique<VkRenderPass> m_renderPass;
const UniquePtr<Allocation> m_vertexBufferMemory;
vector<ImageViewSp> m_attachmentViews;
+ mutable vector<VkImageLayout> m_attachmentLayouts;
vector<FramebufferSp> m_framebuffers;
};
Move<VkRenderPass> TriangleRenderer::createRenderPass (const DeviceInterface& vkd,
const VkDevice device,
- const VkFormat colorAttachmentFormat)
+ const VkFormat colorAttachmentFormat,
+ const bool explicitLayoutTransitions)
{
const VkAttachmentDescription colorAttDesc =
{
VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE,
VK_ATTACHMENT_STORE_OP_DONT_CARE,
- VK_IMAGE_LAYOUT_UNDEFINED,
- VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+ (explicitLayoutTransitions) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+ (explicitLayoutTransitions) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
};
const VkAttachmentReference colorAttRef =
{
const VkDevice device,
Allocator& allocator,
const BinaryCollection& binaryRegistry,
+ bool explicitLayoutTransitions,
const vector<VkImage> swapchainImages,
+ const vector<VkImage> aliasImages,
const VkFormat framebufferFormat,
const UVec2& renderSize)
- : m_vkd (vkd)
- , m_swapchainImages (swapchainImages)
- , m_renderSize (renderSize)
- , m_renderPass (createRenderPass(vkd, device, framebufferFormat))
- , m_pipelineLayout (createPipelineLayout(vkd, device))
- , m_pipeline (createPipeline(vkd, device, *m_renderPass, *m_pipelineLayout, binaryRegistry, renderSize))
- , m_vertexBuffer (createBuffer(vkd, device, (VkDeviceSize)(sizeof(float)*4*3), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))
- , m_vertexBufferMemory (allocator.allocate(getBufferMemoryRequirements(vkd, device, *m_vertexBuffer),
- MemoryRequirement::HostVisible))
+ : m_vkd (vkd)
+ , m_explicitLayoutTransitions (explicitLayoutTransitions)
+ , m_swapchainImages (swapchainImages)
+ , m_aliasImages (aliasImages)
+ , m_renderSize (renderSize)
+ , m_renderPass (createRenderPass(vkd, device, framebufferFormat, m_explicitLayoutTransitions))
+ , m_pipelineLayout (createPipelineLayout(vkd, device))
+ , m_pipeline (createPipeline(vkd, device, *m_renderPass, *m_pipelineLayout, binaryRegistry, renderSize))
+ , m_vertexBuffer (createBuffer(vkd, device, (VkDeviceSize)(sizeof(float)*4*3), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))
+ , m_vertexBufferMemory (allocator.allocate(getBufferMemoryRequirements(vkd, device, *m_vertexBuffer),
+ MemoryRequirement::HostVisible))
{
m_attachmentViews.resize(swapchainImages.size());
+ m_attachmentLayouts.resize(swapchainImages.size());
m_framebuffers.resize(swapchainImages.size());
for (size_t imageNdx = 0; imageNdx < swapchainImages.size(); ++imageNdx)
{
- m_attachmentViews[imageNdx] = ImageViewSp(new Unique<VkImageView>(createAttachmentView(vkd, device, swapchainImages[imageNdx], framebufferFormat)));
- m_framebuffers[imageNdx] = FramebufferSp(new Unique<VkFramebuffer>(createFramebuffer(vkd, device, *m_renderPass, **m_attachmentViews[imageNdx], renderSize)));
+ m_attachmentViews[imageNdx] = ImageViewSp(new Unique<VkImageView>(createAttachmentView(vkd, device, swapchainImages[imageNdx], framebufferFormat)));
+ m_attachmentLayouts[imageNdx] = VK_IMAGE_LAYOUT_UNDEFINED;
+ m_framebuffers[imageNdx] = FramebufferSp(new Unique<VkFramebuffer>(createFramebuffer(vkd, device, *m_renderPass, **m_attachmentViews[imageNdx], renderSize)));
}
VK_CHECK(vkd.bindBufferMemory(device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset()));
beginCommandBuffer(m_vkd, cmdBuffer, 0u);
+ if (m_explicitLayoutTransitions || m_attachmentLayouts[imageNdx] == VK_IMAGE_LAYOUT_UNDEFINED)
+ {
+ VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
+ const VkImageMemoryBarrier barrier = makeImageMemoryBarrier (0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ m_attachmentLayouts[imageNdx], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ m_aliasImages[imageNdx], range);
+ m_vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
+ m_attachmentLayouts[imageNdx] = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ }
+
beginRenderPass(m_vkd, cmdBuffer, *m_renderPass, curFramebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), tcu::Vec4(0.125f, 0.25f, 0.75f, 1.0f));
m_vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
m_vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
endRenderPass(m_vkd, cmdBuffer);
+ if (m_explicitLayoutTransitions)
+ {
+ VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
+ const VkImageMemoryBarrier barrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0,
+ m_attachmentLayouts[imageNdx], VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+ m_aliasImages[imageNdx], range);
+ m_vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
+ m_attachmentLayouts[imageNdx] = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+ }
+
endCommandBuffer(m_vkd, cmdBuffer);
}
beginCommandBuffer(m_vkd, cmdBuffer, 0u);
+ if (m_explicitLayoutTransitions || m_attachmentLayouts[imageNdx] == VK_IMAGE_LAYOUT_UNDEFINED)
+ {
+ VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
+ const VkImageMemoryBarrier barrier = makeImageMemoryBarrier (0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ m_attachmentLayouts[imageNdx], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ m_aliasImages[imageNdx], range);
+ m_vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
+ m_attachmentLayouts[imageNdx] = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ }
+
// begin renderpass
{
const VkClearValue clearValue = makeClearValueColorF32(0.125f, 0.25f, 0.75f, 1.0f);
m_vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
endRenderPass(m_vkd, cmdBuffer);
+ if (m_explicitLayoutTransitions)
+ {
+ VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
+ const VkImageMemoryBarrier barrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0,
+ m_attachmentLayouts[imageNdx], VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+ m_aliasImages[imageNdx], range);
+ m_vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
+ m_attachmentLayouts[imageNdx] = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+ }
+
endCommandBuffer(m_vkd, cmdBuffer);
}
device,
allocator,
context.getBinaryCollection(),
+ false,
+ swapchainImages,
swapchainImages,
swapchainInfo.imageFormat,
tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));
*groupDevice,
allocator,
context.getBinaryCollection(),
+ false,
+ swapchainImages,
swapchainImages,
swapchainInfo.imageFormat,
tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));
{
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
&imageSwapchainCreateInfo,
- VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR, // flags
+ VK_IMAGE_CREATE_ALIAS_BIT |
+ VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR, // flags
VK_IMAGE_TYPE_2D, // imageType
formats[0].format, // format
{ // extent
typedef de::SharedPtr<UniqueImage> ImageSp;
vector<ImageSp> images (numImages);
- vector<VkImage> rawSwapchainImages (numImages);
- vector<VkBindImageMemorySwapchainInfoKHR> bindImageMemorySwapchainInfo (numImages);
- vector<VkBindImageMemoryDeviceGroupInfo > bindImageMemoryDeviceGroupInfo (numImages);
- vector<VkBindImageMemoryInfo> bindImageMemoryInfos (numImages);
+ vector<VkImage> rawImages (numImages);
+ vector<ImageSp> imagesSfr (numImages);
+ vector<VkImage> rawImagesSfr (numImages);
- for (deUint32 idx = 0; idx < numImages; ++idx)
+ // Create non-SFR image aliases for image layout transition
{
- // Create image
- images[idx] = ImageSp(new UniqueImage(createImage(vkd, *groupDevice, &imageCreateInfo)));
+ vector<VkBindImageMemorySwapchainInfoKHR> bindImageMemorySwapchainInfo (numImages);
+ vector<VkBindImageMemoryDeviceGroupInfo > bindImageMemoryDeviceGroupInfo (numImages);
+ vector<VkBindImageMemoryInfo> bindImageMemoryInfos (numImages);
- VkBindImageMemorySwapchainInfoKHR bimsInfo =
+ for (deUint32 idx = 0; idx < numImages; ++idx)
{
- VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR,
- DE_NULL,
- *swapchain,
- idx
- };
- bindImageMemorySwapchainInfo[idx] = bimsInfo;
+ // Create image
+ images[idx] = ImageSp(new UniqueImage(createImage(vkd, *groupDevice, &imageCreateInfo)));
- // Split into 2 vertical halves
- // NOTE: the same split has to be done also in TriangleRenderer::recordDeviceGroupFrame
- const deUint32 halfWidth = desiredSize.x() / 2;
- const deUint32 height = desiredSize.y();
- const VkRect2D sfrRects[] =
- {
- { { 0, 0 }, { halfWidth, height } }, // offset, extent
- { { (deInt32)halfWidth, 0 }, { halfWidth, height } } // offset, extent
- };
+ VkBindImageMemoryInfo bimInfo =
+ {
+ VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
+ DE_NULL,
+ **images[idx],
+ DE_NULL, // If the pNext chain includes an instance of VkBindImageMemorySwapchainInfoKHR, memory must be VK_NULL_HANDLE
+ 0u // If swapchain <in VkBindImageMemorySwapchainInfoKHR> is not NULL, the swapchain and imageIndex are used to determine the memory that the image is bound to, instead of memory and memoryOffset.
+ };
+ bindImageMemoryInfos[idx] = bimInfo;
+ rawImages[idx] = **images[idx];
+ }
- VkBindImageMemoryDeviceGroupInfo bimdgInfo =
- {
- VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO,
- &bindImageMemorySwapchainInfo[idx],
- DE_LENGTH_OF_ARRAY(deviceIndices),
- deviceIndices,
- DE_LENGTH_OF_ARRAY(sfrRects),
- sfrRects
- };
- bindImageMemoryDeviceGroupInfo[idx] = bimdgInfo;
+ VK_CHECK(vkd.bindImageMemory2(*groupDevice, numImages, &bindImageMemoryInfos[0]));
+ }
- VkBindImageMemoryInfo bimInfo =
+ // Create the SFR images
+ {
+ vector<VkBindImageMemorySwapchainInfoKHR> bindImageMemorySwapchainInfo (numImages);
+ vector<VkBindImageMemoryDeviceGroupInfo > bindImageMemoryDeviceGroupInfo (numImages);
+ vector<VkBindImageMemoryInfo> bindImageMemoryInfos (numImages);
+ for (deUint32 idx = 0; idx < numImages; ++idx)
{
- VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
- &bindImageMemoryDeviceGroupInfo[idx],
- **images[idx],
- DE_NULL, // If the pNext chain includes an instance of VkBindImageMemorySwapchainInfoKHR, memory must be VK_NULL_HANDLE
- 0u // If swapchain <in VkBindImageMemorySwapchainInfoKHR> is not NULL, the swapchain and imageIndex are used to determine the memory that the image is bound to, instead of memory and memoryOffset.
- };
- bindImageMemoryInfos[idx] = bimInfo;
- rawSwapchainImages[idx] = **images[idx];
+ // Create image
+ imagesSfr[idx] = ImageSp(new UniqueImage(createImage(vkd, *groupDevice, &imageCreateInfo)));
+
+ VkBindImageMemorySwapchainInfoKHR bimsInfo =
+ {
+ VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR,
+ DE_NULL,
+ *swapchain,
+ idx
+ };
+ bindImageMemorySwapchainInfo[idx] = bimsInfo;
+
+ // Split into 2 vertical halves
+ // NOTE: the same split has to be done also in TriangleRenderer::recordDeviceGroupFrame
+ const deUint32 halfWidth = desiredSize.x() / 2;
+ const deUint32 height = desiredSize.y();
+ const VkRect2D sfrRects[] =
+ {
+ { { 0, 0 }, { halfWidth, height } }, // offset, extent
+ { { (deInt32)halfWidth, 0 }, { halfWidth, height } }, // offset, extent
+ { { 0, 0 }, { halfWidth, height } }, // offset, extent
+ { { (deInt32)halfWidth, 0 }, { halfWidth, height } } // offset, extent
+ };
+
+ VkBindImageMemoryDeviceGroupInfo bimdgInfo =
+ {
+ VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO,
+ &bindImageMemorySwapchainInfo[idx],
+ DE_LENGTH_OF_ARRAY(deviceIndices),
+ deviceIndices,
+ DE_LENGTH_OF_ARRAY(sfrRects),
+ sfrRects
+ };
+ bindImageMemoryDeviceGroupInfo[idx] = bimdgInfo;
+
+ VkBindImageMemoryInfo bimInfo =
+ {
+ VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
+ &bindImageMemoryDeviceGroupInfo[idx],
+ **imagesSfr[idx],
+ DE_NULL, // If the pNext chain includes an instance of VkBindImageMemorySwapchainInfoKHR, memory must be VK_NULL_HANDLE
+ 0u // If swapchain <in VkBindImageMemorySwapchainInfoKHR> is not NULL, the swapchain and imageIndex are used to determine the memory that the image is bound to, instead of memory and memoryOffset.
+ };
+ bindImageMemoryInfos[idx] = bimInfo;
+ rawImagesSfr[idx] = **imagesSfr[idx];
+ }
+
+ VK_CHECK(vkd.bindImageMemory2(*groupDevice, numImages, &bindImageMemoryInfos[0]));
}
- VK_CHECK(vkd.bindImageMemory2(*groupDevice, numImages, &bindImageMemoryInfos[0]));
+ VkPeerMemoryFeatureFlags peerMemoryFeatures = 0u;
+ vkd.getDeviceGroupPeerMemoryFeatures(*groupDevice, 0, firstDeviceID, secondDeviceID, &peerMemoryFeatures);
+ bool explicitLayoutTransitions = !(peerMemoryFeatures & VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT) ||
+ !(peerMemoryFeatures & VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT);
const TriangleRenderer renderer (vkd,
*groupDevice,
allocator,
context.getBinaryCollection(),
- rawSwapchainImages,
+ explicitLayoutTransitions,
+ rawImagesSfr,
+ rawImages,
swapchainInfo.imageFormat,
tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));
const Unique<VkCommandPool> commandPool (createCommandPool(vkd, *groupDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
- const size_t maxQueuedFrames = rawSwapchainImages.size()*2;
+ const size_t maxQueuedFrames = rawImagesSfr.size()*2;
// We need to keep hold of fences from vkAcquireNextImage2KHR
// to actually limit number of frames we allow to be queued.
VK_CHECK(acquireResult);
}
- TCU_CHECK((size_t)imageNdx < rawSwapchainImages.size());
+ TCU_CHECK((size_t)imageNdx < rawImagesSfr.size());
{
const VkSemaphore renderingCompleteSemaphore = **renderingCompleteSemaphores[frameNdx%renderingCompleteSemaphores.size()];
device,
allocator,
context.getBinaryCollection(),
+ false,
+ swapchainImages,
swapchainImages,
swapchainInfo.imageFormat,
tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));