Check conditional rendering with non-zero memory offset
authorRicardo Garcia <rgarcia@igalia.com>
Wed, 6 Apr 2022 08:43:27 +0000 (10:43 +0200)
committerMatthew Netsch <mnetsch@qti.qualcomm.com>
Fri, 8 Apr 2022 20:49:39 +0000 (20:49 +0000)
This commit adds a new set of tests that check the conditional rendering
buffer works properly when the allocation is bound with a non-zero
offset to the buffer.

New tests:
dEQP-VK.conditional_rendering.dispatch.alloc_offset.*

Affected tests:
dEQP-VK.conditional_rendering.*

VK-GL-CTS issue: 3591
Components: Vulkan

Change-Id: I6485e6dc96f625d17b96c4771121ea540cab8d6a

android/cts/main/vk-master-2022-03-01/conditional-rendering.txt
android/cts/main/vk-master/conditional-rendering.txt
external/vulkancts/modules/vulkan/conditional_rendering/vktConditionalClearAttachmentTests.cpp
external/vulkancts/modules/vulkan/conditional_rendering/vktConditionalDispatchTests.cpp
external/vulkancts/modules/vulkan/conditional_rendering/vktConditionalDrawTests.cpp
external/vulkancts/modules/vulkan/conditional_rendering/vktConditionalRenderingTestUtil.cpp
external/vulkancts/modules/vulkan/conditional_rendering/vktConditionalRenderingTestUtil.hpp
external/vulkancts/modules/vulkan/draw/vktDrawBufferObjectUtil.cpp
external/vulkancts/modules/vulkan/draw/vktDrawBufferObjectUtil.hpp
external/vulkancts/mustpass/main/vk-default/conditional-rendering.txt

index 66ff8be..d8bc662 100644 (file)
@@ -115,6 +115,22 @@ dEQP-VK.conditional_rendering.dispatch.condition_local_memory_secondary_buffer_e
 dEQP-VK.conditional_rendering.dispatch.no_condition_local_memory_secondary_buffer_inherited_expect_execution.dispatch
 dEQP-VK.conditional_rendering.dispatch.no_condition_local_memory_secondary_buffer_inherited_expect_execution.dispatch_indirect
 dEQP-VK.conditional_rendering.dispatch.no_condition_local_memory_secondary_buffer_inherited_expect_execution.dispatch_base
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.primary.zero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.primary.zero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.primary.nonzero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.primary.nonzero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.inherited.zero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.inherited.zero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.inherited.nonzero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.inherited.nonzero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary.zero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary.zero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary.nonzero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary.nonzero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary_inherited.zero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary_inherited.zero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary_inherited.nonzero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary_inherited.nonzero.host_visible
 dEQP-VK.conditional_rendering.clear_attachments.condition_local_memory_expect_execution.clear_attachments
 dEQP-VK.conditional_rendering.clear_attachments.condition_local_memory_expect_noop.clear_attachments
 dEQP-VK.conditional_rendering.clear_attachments.condition_local_memory_expect_execution_inverted.clear_attachments
index 5ed374a..9ac2d5c 100644 (file)
@@ -324,6 +324,22 @@ dEQP-VK.conditional_rendering.dispatch.condition_size.secondary_inherited.second
 dEQP-VK.conditional_rendering.dispatch.condition_size.secondary_inherited.third_byte
 dEQP-VK.conditional_rendering.dispatch.condition_size.secondary_inherited.fourth_byte
 dEQP-VK.conditional_rendering.dispatch.condition_size.secondary_inherited.padded_zero
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.primary.zero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.primary.zero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.primary.nonzero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.primary.nonzero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.inherited.zero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.inherited.zero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.inherited.nonzero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.inherited.nonzero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary.zero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary.zero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary.nonzero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary.nonzero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary_inherited.zero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary_inherited.zero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary_inherited.nonzero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary_inherited.nonzero.host_visible
 dEQP-VK.conditional_rendering.clear_attachments.condition_host_memory_expect_execution.clear_attachments
 dEQP-VK.conditional_rendering.clear_attachments.condition_host_memory_expect_noop.clear_attachments
 dEQP-VK.conditional_rendering.clear_attachments.condition_host_memory_expect_execution_inverted.clear_attachments
index 293aa96..f2326ed 100644 (file)
@@ -145,7 +145,7 @@ tcu::TestStatus ConditionalClearAttachmentTest::iterate (void)
                1u,                                                             // uint32_t    layerCount;
        };
 
-       m_conditionalBuffer = createConditionalRenderingBuffer(m_context, m_conditionalData, *m_cmdPool);
+       m_conditionalBuffer = createConditionalRenderingBuffer(m_context, m_conditionalData);
 
        if (m_conditionalData.conditionInSecondaryCommandBuffer)
        {
index 54f5caa..c76fa2f 100644 (file)
@@ -284,7 +284,7 @@ tcu::TestStatus ConditionalDispatchTestInstance::iterate (void)
        vk.cmdBindPipeline(targetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
        vk.cmdBindDescriptorSets(targetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
 
-       de::SharedPtr<Draw::Buffer> conditionalBuffer = createConditionalRenderingBuffer(m_context, m_conditionalData, *cmdPool);
+       de::SharedPtr<Draw::Buffer> conditionalBuffer = createConditionalRenderingBuffer(m_context, m_conditionalData);
 
        if (m_conditionalData.conditionInSecondaryCommandBuffer)
        {
@@ -389,6 +389,14 @@ void ConditionalDispatchTests::init (void)
                addChild(conditionalDrawRootGroup.release());
        }
 
+       enum class ConditionLocation
+       {
+               PRIMARY_FLAT = 0,
+               PRIMARY_WITH_SECONDARY,
+               SECONDARY_NORMAL,
+               SECONDARY_INHERITED,
+       };
+
        // Tests verifying the condition is interpreted as a 32-bit value.
        {
                de::MovePtr<tcu::TestCaseGroup> conditionSizeGroup(new tcu::TestCaseGroup(m_testCtx, "condition_size", "Tests verifying the condition is being read as a 32-bit value"));
@@ -410,58 +418,50 @@ void ConditionalDispatchTests::init (void)
                        {       0u,                             true,   false,  "padded_zero"   },
                };
 
-               enum class ConditionSizeSubcaseType
-               {
-                       PRIMARY_FLAT = 0,
-                       PRIMARY_WITH_SECONDARY,
-                       SECONDARY_NORMAL,
-                       SECONDARY_INHERITED,
-               };
-
-               struct ConditionSizeSubcase
+               struct ConditionLocationSubcase
                {
-                       ConditionSizeSubcaseType        type;
-                       const char*                                     name;
+                       ConditionLocation       location;
+                       const char*                     name;
                };
 
-               const ConditionSizeSubcase kConditionSizeSubcase[] =
+               const ConditionLocationSubcase kConditionLocationSubcase[] =
                {
-                       { ConditionSizeSubcaseType::PRIMARY_FLAT,                               "primary"                               },
-                       { ConditionSizeSubcaseType::PRIMARY_WITH_SECONDARY,             "inherited"                             },
-                       { ConditionSizeSubcaseType::SECONDARY_NORMAL,                   "secondary"                             },
-                       { ConditionSizeSubcaseType::SECONDARY_INHERITED,                "secondary_inherited"   },
+                       { ConditionLocation::PRIMARY_FLAT,                              "primary"                               },
+                       { ConditionLocation::PRIMARY_WITH_SECONDARY,    "inherited"                             },
+                       { ConditionLocation::SECONDARY_NORMAL,                  "secondary"                             },
+                       { ConditionLocation::SECONDARY_INHERITED,               "secondary_inherited"   },
                };
 
-               for (int subcaseNdx = 0; subcaseNdx < DE_LENGTH_OF_ARRAY(kConditionSizeSubcase); ++subcaseNdx)
+               for (int subcaseNdx = 0; subcaseNdx < DE_LENGTH_OF_ARRAY(kConditionLocationSubcase); ++subcaseNdx)
                {
-                       const auto& subcase = kConditionSizeSubcase[subcaseNdx];
+                       const auto& subcase = kConditionLocationSubcase[subcaseNdx];
 
                        de::MovePtr<tcu::TestCaseGroup> subcaseGroup(new tcu::TestCaseGroup(m_testCtx, subcase.name, ""));
 
                        ConditionalData conditionalData         = {};
                        conditionalData.conditionInverted       = false;
 
-                       switch (subcase.type)
+                       switch (subcase.location)
                        {
-                               case ConditionSizeSubcaseType::PRIMARY_FLAT:
+                               case ConditionLocation::PRIMARY_FLAT:
                                        conditionalData.conditionInPrimaryCommandBuffer         = true;
                                        conditionalData.conditionInSecondaryCommandBuffer       = false;
                                        conditionalData.conditionInherited                                      = false;
                                        break;
 
-                               case ConditionSizeSubcaseType::PRIMARY_WITH_SECONDARY:
+                               case ConditionLocation::PRIMARY_WITH_SECONDARY:
                                        conditionalData.conditionInPrimaryCommandBuffer         = true;
                                        conditionalData.conditionInSecondaryCommandBuffer       = false;
                                        conditionalData.conditionInherited                                      = true;
                                        break;
 
-                               case ConditionSizeSubcaseType::SECONDARY_NORMAL:
+                               case ConditionLocation::SECONDARY_NORMAL:
                                        conditionalData.conditionInPrimaryCommandBuffer         = false;
                                        conditionalData.conditionInSecondaryCommandBuffer       = true;
                                        conditionalData.conditionInherited                                      = false;
                                        break;
 
-                               case ConditionSizeSubcaseType::SECONDARY_INHERITED:
+                               case ConditionLocation::SECONDARY_INHERITED:
                                        conditionalData.conditionInPrimaryCommandBuffer         = false;
                                        conditionalData.conditionInSecondaryCommandBuffer       = true;
                                        conditionalData.conditionInherited                                      = true;
@@ -493,6 +493,118 @@ void ConditionalDispatchTests::init (void)
 
                addChild(conditionSizeGroup.release());
        }
+
+       // Tests checking the buffer allocation offset is applied correctly when reading the condition.
+       {
+               de::MovePtr<tcu::TestCaseGroup> allocOffsetGroup(new tcu::TestCaseGroup(m_testCtx, "alloc_offset", "Tests verifying the buffer allocation offset is applied correctly"));
+
+               const struct
+               {
+                       ConditionLocation       location;
+                       const char*                     name;
+               } kLocationCases[] =
+               {
+                       { ConditionLocation::PRIMARY_FLAT,                              "primary"                               },
+                       { ConditionLocation::PRIMARY_WITH_SECONDARY,    "inherited"                             },
+                       { ConditionLocation::SECONDARY_NORMAL,                  "secondary"                             },
+                       { ConditionLocation::SECONDARY_INHERITED,               "secondary_inherited"   },
+               };
+
+               const struct
+               {
+                       bool            active;
+                       const char*     name;
+               } kActiveCases[] =
+               {
+                       { false,        "zero"          },
+                       { true,         "nonzero"       },
+               };
+
+               const struct
+               {
+                       ConditionalBufferMemory         memoryType;
+                       const char*                                     name;
+               } kMemoryTypeCases[] =
+               {
+                       { LOCAL,        "device_local"  },
+                       { HOST,         "host_visible"  },
+               };
+
+               for (const auto& locationCase : kLocationCases)
+               {
+                       de::MovePtr<tcu::TestCaseGroup> locationSubGroup(new tcu::TestCaseGroup(m_testCtx, locationCase.name, ""));
+
+                       for (const auto& activeCase : kActiveCases)
+                       {
+                               de::MovePtr<tcu::TestCaseGroup> activeSubGroup(new tcu::TestCaseGroup(m_testCtx, activeCase.name, ""));
+
+                               for (const auto& memoryTypeCase : kMemoryTypeCases)
+                               {
+                                       ConditionalData conditionalData =
+                                       {
+                                               false,                                          //      bool                                    conditionInPrimaryCommandBuffer;
+                                               false,                                          //      bool                                    conditionInSecondaryCommandBuffer;
+                                               false,                                          //      bool                                    conditionInverted;
+                                               false,                                          //      bool                                    conditionInherited;
+                                               0u,                                                     //      deUint32                                conditionValue;
+                                               false,                                          //      bool                                    padConditionValue;
+                                               true,                                           //      bool                                    allocationOffset;
+                                               false,                                          //      bool                                    expectCommandExecution;
+                                               memoryTypeCase.memoryType,      //      ConditionalBufferMemory memoryType;
+                                       };
+
+                                       switch (locationCase.location)
+                                       {
+                                               case ConditionLocation::PRIMARY_FLAT:
+                                                       conditionalData.conditionInPrimaryCommandBuffer         = true;
+                                                       conditionalData.conditionInSecondaryCommandBuffer       = false;
+                                                       conditionalData.conditionInherited                                      = false;
+                                                       break;
+
+                                               case ConditionLocation::PRIMARY_WITH_SECONDARY:
+                                                       conditionalData.conditionInPrimaryCommandBuffer         = true;
+                                                       conditionalData.conditionInSecondaryCommandBuffer       = false;
+                                                       conditionalData.conditionInherited                                      = true;
+                                                       break;
+
+                                               case ConditionLocation::SECONDARY_NORMAL:
+                                                       conditionalData.conditionInPrimaryCommandBuffer         = false;
+                                                       conditionalData.conditionInSecondaryCommandBuffer       = true;
+                                                       conditionalData.conditionInherited                                      = false;
+                                                       break;
+
+                                               case ConditionLocation::SECONDARY_INHERITED:
+                                                       conditionalData.conditionInPrimaryCommandBuffer         = false;
+                                                       conditionalData.conditionInSecondaryCommandBuffer       = true;
+                                                       conditionalData.conditionInherited                                      = true;
+                                                       break;
+
+                                               default:
+                                                       DE_ASSERT(false);
+                                                       break;
+                                       }
+
+                                       conditionalData.conditionValue                  = (activeCase.active ? 1u : 0u);
+                                       conditionalData.expectCommandExecution  = activeCase.active;
+
+                                       const ConditionalTestSpec spec =
+                                       {
+                                               DISPATCH_COMMAND_TYPE_DISPATCH, //      DispatchCommandType     command;
+                                               1,                                                              //      int                                     numCalls;
+                                               conditionalData,                                //      ConditionalData         conditionalData;
+                                       };
+
+                                       activeSubGroup->addChild(new ConditionalDispatchTest(m_testCtx, memoryTypeCase.name, "", spec));
+                               }
+
+                               locationSubGroup->addChild(activeSubGroup.release());
+                       }
+
+                       allocOffsetGroup->addChild(locationSubGroup.release());
+               }
+
+               addChild(allocOffsetGroup.release());
+       }
 }
 
 }      // conditional
index 56799c6..a40e404 100644 (file)
@@ -416,7 +416,7 @@ tcu::TestStatus ConditionalDraw::iterate (void)
 
        m_vk.cmdBindPipeline(targetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
 
-       m_conditionalBuffer = createConditionalRenderingBuffer(m_context, m_conditionalData, *m_cmdPool);
+       m_conditionalBuffer = createConditionalRenderingBuffer(m_context, m_conditionalData);
 
        if (m_conditionalData.conditionInSecondaryCommandBuffer)
        {
index 9d6d25d..9b5e306 100644 (file)
@@ -25,6 +25,8 @@
 #include "vktConditionalRenderingTestUtil.hpp"
 #include "vktDrawCreateInfoUtil.hpp"
 #include "vkQueryUtil.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkTypeUtil.hpp"
 
 namespace vkt
 {
@@ -44,79 +46,56 @@ void checkConditionalRenderingCapabilities (vkt::Context& context, const Conditi
                TCU_THROW(NotSupportedError, "Device does not support inherited conditional rendering");
 }
 
-de::SharedPtr<Draw::Buffer>    createConditionalRenderingBuffer (vkt::Context& context, const ConditionalData& data, vk::VkCommandPool cmdPool)
+de::SharedPtr<Draw::Buffer>    createConditionalRenderingBuffer (vkt::Context& context, const ConditionalData& data)
 {
+       const auto&     vk                      = context.getDeviceInterface();
+       const auto      device          = context.getDevice();
+       const auto      queueIndex      = context.getUniversalQueueFamilyIndex();
+       const auto      queue           = context.getUniversalQueue();
+       auto&           alloc           = context.getDefaultAllocator();
+
        // When padding the condition value, it will be surounded by two additional values with nonzero bytes in them.
+       // When choosing to apply an offset to the allocation, the offset will be four times the size of the condition variable.
        const auto                                      bufferSize      = static_cast<vk::VkDeviceSize>(sizeof(data.conditionValue)) * (data.padConditionValue ? 3ull : 1ull);
        const auto                                      dataOffset      = static_cast<vk::VkDeviceSize>(data.padConditionValue ? sizeof(data.conditionValue) : 0);
-       const auto                                      usage           = data.memoryType ? vk::VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT : vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
-
-       const vk::DeviceInterface&      vk                      = context.getDeviceInterface();
-       de::SharedPtr<Draw::Buffer>     buffer          = Draw::Buffer::createAndAlloc(vk, context.getDevice(),
-                                                                                               Draw::BufferCreateInfo(bufferSize, usage),
-                                                                                               context.getDefaultAllocator(),
-                                                                                               vk::MemoryRequirement::HostVisible);
-
-       deUint8* conditionBufferPtr = reinterpret_cast<deUint8*>(buffer->getBoundMemory().getHostPtr()) + buffer->getBoundMemory().getOffset();
+       const auto                                      allocOffset     = static_cast<vk::VkDeviceSize>(sizeof(data.conditionValue) * (data.allocationOffset ? 4u : 0u));
+
+       // Create host-visible buffer. This may be the final buffer or only a staging buffer.
+       const auto                                      hostUsage       = ((data.memoryType == HOST) ? vk::VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT : vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
+       de::SharedPtr<Draw::Buffer>     hostBuffer      = Draw::Buffer::createAndAlloc(vk, device,
+                                                                                               Draw::BufferCreateInfo(bufferSize, hostUsage),
+                                                                                               alloc,
+                                                                                               vk::MemoryRequirement::HostVisible,
+                                                                                               allocOffset);
+
+       // Copy data to host buffer.
+       deUint8* conditionBufferPtr = reinterpret_cast<deUint8*>(hostBuffer->getHostPtr());
        deMemset(conditionBufferPtr, 1, static_cast<size_t>(bufferSize));
        deMemcpy(conditionBufferPtr + dataOffset, &data.conditionValue, sizeof(data.conditionValue));
-
-       vk::flushMappedMemoryRange(     vk,
-                                                               context.getDevice(),
-                                                               buffer->getBoundMemory().getMemory(),
-                                                               buffer->getBoundMemory().getOffset(),
-                                                               VK_WHOLE_SIZE);
-
-       if (data.memoryType == ConditionalBufferMemory::LOCAL)
-       {
-               de::SharedPtr<Draw::Buffer>     conditionalBuffer = Draw::Buffer::createAndAlloc(vk, context.getDevice(),
-                                                                                               Draw::BufferCreateInfo(bufferSize,
-                                                                                                                                vk::VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT
-                                                                                                                               |vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
-                                                                                               context.getDefaultAllocator(),
-                                                                                               vk::MemoryRequirement::Local);
-
-               auto cmdBuffer = vk::allocateCommandBuffer
-               (
-                       vk, context.getDevice(),
-                       cmdPool,
-                       vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY
-               );
-
-               const vk::VkCommandBufferBeginInfo commandBufferBeginInfo =
-               {
-                       vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
-                       DE_NULL,
-                       vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
-                       nullptr
-               };
-
-               vk.beginCommandBuffer(*cmdBuffer, &commandBufferBeginInfo);
-
-               vk::VkBufferCopy copyInfo
-               {
-                       buffer->getBoundMemory().getOffset(),
-                       conditionalBuffer->getBoundMemory().getOffset(),
-                       static_cast<size_t>(bufferSize)
-               };
-               vk.cmdCopyBuffer(*cmdBuffer, buffer->object(), conditionalBuffer->object(), 1, &copyInfo);
-               vk.endCommandBuffer(*cmdBuffer);
-
-               vk::VkSubmitInfo submitInfo{};
-               submitInfo.sType = vk::VK_STRUCTURE_TYPE_SUBMIT_INFO;
-               submitInfo.commandBufferCount = 1;
-               submitInfo.pCommandBuffers = &(*cmdBuffer);
-
-               auto queue = context.getUniversalQueue();
-
-               vk.queueSubmit(queue, 1, &submitInfo, 0);
-
-               vk.queueWaitIdle(queue);
-
-               return conditionalBuffer;
-       }
-
-       return buffer;
+       vk::flushAlloc(vk, context.getDevice(), hostBuffer->getBoundMemory());
+
+       // Return host buffer if appropriate.
+       if (data.memoryType == HOST)
+               return hostBuffer;
+
+       // Create and return device-local buffer otherwise, after copying host-visible buffer contents to it.
+       const auto                                      deviceLocalUsage        = (vk::VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT | vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT);
+       de::SharedPtr<Draw::Buffer>     deviceLocalBuffer       = Draw::Buffer::createAndAlloc(vk, device,
+                                                                                                               Draw::BufferCreateInfo(bufferSize, deviceLocalUsage),
+                                                                                                               alloc,
+                                                                                                               vk::MemoryRequirement::Local,
+                                                                                                               allocOffset);
+
+       const auto cmdPool              = vk::makeCommandPool(vk, device, queueIndex);
+       const auto cmdBuffer    = vk::allocateCommandBuffer (vk, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+       const auto copyInfo             = vk::makeBufferCopy(0ull, 0ull, bufferSize);
+
+       vk::beginCommandBuffer(vk, *cmdBuffer);
+       vk.cmdCopyBuffer(*cmdBuffer, hostBuffer->object(), deviceLocalBuffer->object(), 1, &copyInfo);
+       vk::endCommandBuffer(vk, *cmdBuffer);
+       vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
+
+       return deviceLocalBuffer;
 }
 
 void beginConditionalRendering (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, Draw::Buffer& buffer, const ConditionalData& data)
index a048e5c..556e6df 100644 (file)
@@ -45,6 +45,7 @@ struct ConditionalData
        bool                                            conditionInherited;
        deUint32                                        conditionValue;
        bool                                            padConditionValue;
+       bool                                            allocationOffset; // Apply an offset to the condition variable buffer allocation.
 
        bool                                            expectCommandExecution;
 
@@ -53,54 +54,54 @@ struct ConditionalData
 
 static const ConditionalData s_testsData[] =
 {
-       //      CONDPRI CONDSEC INV             INH             V       PAD             RES             MEM
-       {       true,   false,  false,  false,  1,      false,  true,   HOST    },
-       {       true,   false,  false,  false,  0,      false,  false,  HOST    },
-       {       true,   false,  true,   false,  0,      false,  true,   HOST    },
-       {       true,   false,  true,   false,  1,      false,  false,  HOST    },
-       {       true,   false,  false,  true,   1,      false,  true,   HOST    },
-       {       true,   false,  false,  true,   0,      false,  false,  HOST    },
-       {       true,   false,  true,   true,   0,      false,  true,   HOST    },
-       {       true,   false,  true,   true,   1,      false,  false,  HOST    },
-
-       {       true,   false,  false,  false,  1,      false,  true,   LOCAL   },
-       {       true,   false,  false,  false,  0,      false,  false,  LOCAL   },
-       {       true,   false,  true,   false,  0,      false,  true,   LOCAL   },
-       {       true,   false,  true,   false,  1,      false,  false,  LOCAL   },
-       {       true,   false,  false,  true,   1,      false,  true,   LOCAL   },
-       {       true,   false,  false,  true,   0,      false,  false,  LOCAL   },
-       {       true,   false,  true,   true,   0,      false,  true,   LOCAL   },
-       {       true,   false,  true,   true,   1,      false,  false,  LOCAL   },
-
-       {       false,  true,   false,  false,  1,      false,  true,   HOST    },
-       {       false,  true,   false,  false,  0,      false,  false,  HOST    },
-       {       false,  true,   true,   false,  0,      false,  true,   HOST    },
-       {       false,  true,   true,   false,  1,      false,  false,  HOST    },
-
-       {       false,  true,   false,  false,  1,      false,  true,   LOCAL   },
-       {       false,  true,   false,  false,  0,      false,  false,  LOCAL   },
-       {       false,  true,   true,   false,  0,      false,  true,   LOCAL   },
-       {       false,  true,   true,   false,  1,      false,  false,  LOCAL   },
+       //      CONDPRI CONDSEC INV             INH             V       PAD             ALLOCOFFSET     RES             MEM
+       {       true,   false,  false,  false,  1,      false,  false,          true,   HOST    },
+       {       true,   false,  false,  false,  0,      false,  false,          false,  HOST    },
+       {       true,   false,  true,   false,  0,      false,  false,          true,   HOST    },
+       {       true,   false,  true,   false,  1,      false,  false,          false,  HOST    },
+       {       true,   false,  false,  true,   1,      false,  false,          true,   HOST    },
+       {       true,   false,  false,  true,   0,      false,  false,          false,  HOST    },
+       {       true,   false,  true,   true,   0,      false,  false,          true,   HOST    },
+       {       true,   false,  true,   true,   1,      false,  false,          false,  HOST    },
+
+       {       true,   false,  false,  false,  1,      false,  false,          true,   LOCAL   },
+       {       true,   false,  false,  false,  0,      false,  false,          false,  LOCAL   },
+       {       true,   false,  true,   false,  0,      false,  false,          true,   LOCAL   },
+       {       true,   false,  true,   false,  1,      false,  false,          false,  LOCAL   },
+       {       true,   false,  false,  true,   1,      false,  false,          true,   LOCAL   },
+       {       true,   false,  false,  true,   0,      false,  false,          false,  LOCAL   },
+       {       true,   false,  true,   true,   0,      false,  false,          true,   LOCAL   },
+       {       true,   false,  true,   true,   1,      false,  false,          false,  LOCAL   },
+
+       {       false,  true,   false,  false,  1,      false,  false,          true,   HOST    },
+       {       false,  true,   false,  false,  0,      false,  false,          false,  HOST    },
+       {       false,  true,   true,   false,  0,      false,  false,          true,   HOST    },
+       {       false,  true,   true,   false,  1,      false,  false,          false,  HOST    },
+
+       {       false,  true,   false,  false,  1,      false,  false,          true,   LOCAL   },
+       {       false,  true,   false,  false,  0,      false,  false,          false,  LOCAL   },
+       {       false,  true,   true,   false,  0,      false,  false,          true,   LOCAL   },
+       {       false,  true,   true,   false,  1,      false,  false,          false,  LOCAL   },
 
        // Test that inheritance does not affect outcome of secondary command buffer with conditional rendering or not.
-       {       false,  false,  false,  true,   0,      false,  true,   HOST    },
-       {       false,  false,  false,  true,   0,      false,  true,   LOCAL   },
-
-       {       false,  true,   false,  true,   1,      false,  true,   HOST    },
-       {       false,  true,   false,  true,   0,      false,  false,  HOST    },
-       {       false,  true,   true,   true,   1,      false,  false,  HOST    },
-       {       false,  true,   true,   true,   0,      false,  true,   HOST    },
-
-       {       false,  true,   false,  true,   1,      false,  true,   LOCAL   },
-       {       false,  true,   false,  true,   0,      false,  false,  LOCAL   },
-       {       false,  true,   true,   true,   1,      false,  false,  LOCAL   },
-       {       false,  true,   true,   true,   0,      false,  true,   LOCAL   },
+       {       false,  false,  false,  true,   0,      false,  false,          true,   HOST    },
+       {       false,  false,  false,  true,   0,      false,  false,          true,   LOCAL   },
+
+       {       false,  true,   false,  true,   1,      false,  false,          true,   HOST    },
+       {       false,  true,   false,  true,   0,      false,  false,          false,  HOST    },
+       {       false,  true,   true,   true,   1,      false,  false,          false,  HOST    },
+       {       false,  true,   true,   true,   0,      false,  false,          true,   HOST    },
+
+       {       false,  true,   false,  true,   1,      false,  false,          true,   LOCAL   },
+       {       false,  true,   false,  true,   0,      false,  false,          false,  LOCAL   },
+       {       false,  true,   true,   true,   1,      false,  false,          false,  LOCAL   },
+       {       false,  true,   true,   true,   0,      false,  false,          true,   LOCAL   },
 };
 
 std::ostream&                          operator<< (std::ostream& str, ConditionalData const& c);
 
 void                                           checkConditionalRenderingCapabilities   (vkt::Context& context, const ConditionalData& data);
-de::SharedPtr<Draw::Buffer>    createConditionalRenderingBuffer                (vkt::Context& context, const ConditionalData& data, vk::VkCommandPool cmdPool);
+de::SharedPtr<Draw::Buffer>    createConditionalRenderingBuffer                (vkt::Context& context, const ConditionalData& data);
 void                                           beginConditionalRendering                               (const vk::DeviceInterface& vk,
                                                                                                                                         vk::VkCommandBuffer cmdBuffer,
                                                                                                                                         Draw::Buffer& buffer,
index 06e0628..6779c69 100644 (file)
@@ -32,32 +32,40 @@ namespace Draw
 {
 
 Buffer::Buffer (const vk::DeviceInterface& vk, vk::VkDevice device, vk::Move<vk::VkBuffer> object_)
-       : m_allocation  (DE_NULL)
+       : m_allocation  (DE_NULL)
+       , m_allocOffset (0ull)
        , m_object              (object_)
        , m_vk                  (vk)
        , m_device              (device)
 {
 }
 
-void Buffer::bindMemory (de::MovePtr<vk::Allocation> allocation)
+void Buffer::bindMemory (de::MovePtr<vk::Allocation> allocation, vk::VkDeviceSize allocOffset)
 {
        DE_ASSERT(allocation);
-       VK_CHECK(m_vk.bindBufferMemory(m_device, *m_object, allocation->getMemory(), allocation->getOffset()));
+       VK_CHECK(m_vk.bindBufferMemory(m_device, *m_object, allocation->getMemory(), allocation->getOffset() + allocOffset));
 
        DE_ASSERT(!m_allocation);
        m_allocation = allocation;
+       m_allocOffset = allocOffset;
 }
 
 de::SharedPtr<Buffer> Buffer::createAndAlloc (const vk::DeviceInterface& vk,
                                                                                          vk::VkDevice device,
                                                                                          const vk::VkBufferCreateInfo &createInfo,
                                                                                          vk::Allocator &allocator,
-                                                                                         vk::MemoryRequirement memoryRequirement)
+                                                                                         vk::MemoryRequirement memoryRequirement,
+                                                                                         vk::VkDeviceSize allocationOffset)
 {
        de::SharedPtr<Buffer> ret = create(vk, device, createInfo);
 
        vk::VkMemoryRequirements bufferRequirements = vk::getBufferMemoryRequirements(vk, device, ret->object());
-       ret->bindMemory(allocator.allocate(bufferRequirements, memoryRequirement));
+
+       // If requested, allocate more memory for the extra offset inside the allocation.
+       const auto extraRoom = de::roundUp(allocationOffset, bufferRequirements.alignment);
+       bufferRequirements.size += extraRoom;
+
+       ret->bindMemory(allocator.allocate(bufferRequirements, memoryRequirement), extraRoom);
        return ret;
 }
 
@@ -68,6 +76,13 @@ de::SharedPtr<Buffer> Buffer::create (const vk::DeviceInterface& vk,
        return de::SharedPtr<Buffer>(new Buffer(vk, device, vk::createBuffer(vk, device, &createInfo)));
 }
 
+void* Buffer::getHostPtr (void) const
+{
+       if (!m_allocation)
+               return nullptr;
+       return reinterpret_cast<uint8_t*>(m_allocation->getHostPtr()) + m_allocOffset;
+}
+
 void bufferBarrier (const vk::DeviceInterface& vk,
                                        vk::VkCommandBuffer                     cmdBuffer,
                                        vk::VkBuffer                            buffer,
index b913695..107a144 100644 (file)
@@ -44,14 +44,16 @@ public:
                                                                                                 vk::VkDevice                                   device,
                                                                                                 const vk::VkBufferCreateInfo&  createInfo,
                                                                                                 vk::Allocator&                                 allocator,
-                                                                                                vk::MemoryRequirement                  allocationMemoryProperties = vk::MemoryRequirement::Any);
+                                                                                                vk::MemoryRequirement                  allocationMemoryProperties = vk::MemoryRequirement::Any,
+                                                                                                vk::VkDeviceSize                               allocationOffset = 0ull);
 
                                                                Buffer                  (const vk::DeviceInterface &vk, vk::VkDevice device, vk::Move<vk::VkBuffer> object);
 
-       void                                            bindMemory              (de::MovePtr<vk::Allocation> allocation);
+       void                                            bindMemory              (de::MovePtr<vk::Allocation> allocation, vk::VkDeviceSize allocOffset = 0ull);
 
        vk::VkBuffer                            object                  (void) const                                                            { return *m_object;             }
        vk::Allocation                          getBoundMemory  (void) const                                                            { return *m_allocation; }
+       void*                                           getHostPtr              (void) const;
 
 private:
 
@@ -59,6 +61,7 @@ private:
        Buffer&                                         operator=               (const Buffer& other);  // Not allowed!
 
        de::MovePtr<vk::Allocation>             m_allocation;
+       vk::VkDeviceSize                                m_allocOffset;
        vk::Unique<vk::VkBuffer>                m_object;
 
        const vk::DeviceInterface&              m_vk;
index 5ed374a..9ac2d5c 100644 (file)
@@ -324,6 +324,22 @@ dEQP-VK.conditional_rendering.dispatch.condition_size.secondary_inherited.second
 dEQP-VK.conditional_rendering.dispatch.condition_size.secondary_inherited.third_byte
 dEQP-VK.conditional_rendering.dispatch.condition_size.secondary_inherited.fourth_byte
 dEQP-VK.conditional_rendering.dispatch.condition_size.secondary_inherited.padded_zero
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.primary.zero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.primary.zero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.primary.nonzero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.primary.nonzero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.inherited.zero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.inherited.zero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.inherited.nonzero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.inherited.nonzero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary.zero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary.zero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary.nonzero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary.nonzero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary_inherited.zero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary_inherited.zero.host_visible
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary_inherited.nonzero.device_local
+dEQP-VK.conditional_rendering.dispatch.alloc_offset.secondary_inherited.nonzero.host_visible
 dEQP-VK.conditional_rendering.clear_attachments.condition_host_memory_expect_execution.clear_attachments
 dEQP-VK.conditional_rendering.clear_attachments.condition_host_memory_expect_noop.clear_attachments
 dEQP-VK.conditional_rendering.clear_attachments.condition_host_memory_expect_execution_inverted.clear_attachments