Commit 1a9714a9 by Alexis Hetu Committed by Alexis Hétu

Allocation failure fix

Intentional allocation failure tests were crashing on Linux, because the object's constructor was called even when the allocator returned nullptr. Separated the allocation from the construction to fix the issue. Bug b/116336664 Change-Id: I7a5d4e957ec27f37a96b795a7f17aacebb240fe9 Tests: dEQP-VK.api.device_init.create_instance_device_intentional_alloc_fail Tests: dEQP-VK.api.object_management.alloc_callback_fail.* Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28948Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Presubmit-Ready: Alexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 22186793
......@@ -1104,6 +1104,7 @@ VkResult CommandBuffer::reset(VkCommandPoolResetFlags flags)
template<typename T, typename... Args>
void CommandBuffer::addCommand(Args&&... args)
{
// FIXME (b/119409619): use an allocator here so we can control all memory allocations
commands->push_back(std::unique_ptr<T>(new T(std::forward<Args>(args)...)));
}
......
......@@ -16,6 +16,7 @@
#include "VkCommandBuffer.hpp"
#include "VkDestroy.h"
#include <algorithm>
#include <new>
namespace vk
{
......@@ -23,7 +24,10 @@ namespace vk
CommandPool::CommandPool(const VkCommandPoolCreateInfo* pCreateInfo, void* mem)
{
// FIXME (b/119409619): use an allocator here so we can control all memory allocations
commandBuffers = new std::set<VkCommandBuffer>();
void* deviceMemory = vk::allocate(sizeof(std::set<VkCommandBuffer>), REQUIRED_MEMORY_ALIGNMENT,
DEVICE_MEMORY, GetAllocationScope());
ASSERT(deviceMemory);
commandBuffers = new (deviceMemory) std::set<VkCommandBuffer>();
}
void CommandPool::destroy(const VkAllocationCallbacks* pAllocator)
......@@ -35,7 +39,7 @@ void CommandPool::destroy(const VkAllocationCallbacks* pAllocator)
}
// FIXME (b/119409619): use an allocator here so we can control all memory allocations
delete commandBuffers;
vk::deallocate(commandBuffers, DEVICE_MEMORY);
}
size_t CommandPool::ComputeRequiredAllocationSize(const VkCommandPoolCreateInfo* pCreateInfo)
......@@ -47,7 +51,11 @@ VkResult CommandPool::allocateCommandBuffers(VkCommandBufferLevel level, uint32_
{
for(uint32_t i = 0; i < commandBufferCount; i++)
{
DispatchableCommandBuffer* commandBuffer = new (DEVICE_MEMORY) DispatchableCommandBuffer(level);
// FIXME (b/119409619): use an allocator here so we can control all memory allocations
void* deviceMemory = vk::allocate(sizeof(DispatchableCommandBuffer), REQUIRED_MEMORY_ALIGNMENT,
DEVICE_MEMORY, DispatchableCommandBuffer::GetAllocationScope());
ASSERT(deviceMemory);
DispatchableCommandBuffer* commandBuffer = new (deviceMemory) DispatchableCommandBuffer(level);
if(commandBuffer)
{
pCommandBuffers[i] = *commandBuffer;
......
......@@ -47,6 +47,7 @@ size_t DescriptorPool::ComputeRequiredAllocationSize(const VkDescriptorPoolCreat
VkResult DescriptorPool::allocateSets(uint32_t descriptorSetCount, const VkDescriptorSetLayout* pSetLayouts, VkDescriptorSet* pDescriptorSets)
{
// FIXME (b/119409619): use an allocator here so we can control all memory allocations
std::unique_ptr<size_t[]> layoutSizes(new size_t[descriptorSetCount]);
for(uint32_t i = 0; i < descriptorSetCount; i++)
{
......
......@@ -52,6 +52,7 @@ Device::Device(const Device::CreateInfo* info, void* mem)
UNIMPLEMENTED("enabledLayerCount"); // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
}
// FIXME (b/119409619): use an allocator here so we can control all memory allocations
blitter = new sw::Blitter();
}
......
......@@ -19,6 +19,7 @@
#include "VkDebug.hpp"
#include "VkMemory.h"
#include <new>
#include <vulkan/vulkan_core.h>
#include <vulkan/vk_icd.h>
......@@ -43,7 +44,14 @@ static VkResult Create(const VkAllocationCallbacks* pAllocator, const CreateInfo
}
}
auto object = new (pAllocator) T(pCreateInfo, memory);
void* objectMemory = vk::allocate(sizeof(T), alignof(T), pAllocator, T::GetAllocationScope());
if(!objectMemory)
{
vk::deallocate(memory, pAllocator);
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
auto object = new (objectMemory) T(pCreateInfo, memory);
if(!object)
{
......@@ -64,11 +72,6 @@ public:
void destroy(const VkAllocationCallbacks* pAllocator) {} // Method defined by objects to delete their content, if necessary
void* operator new(size_t count, const VkAllocationCallbacks* pAllocator)
{
return vk::allocate(count, alignof(T), pAllocator, T::GetAllocationScope());
}
void operator delete(void* ptr, const VkAllocationCallbacks* pAllocator)
{
// Should never happen
......@@ -119,11 +122,6 @@ public:
object.destroy(pAllocator);
}
void* operator new(size_t count, const VkAllocationCallbacks* pAllocator)
{
return vk::allocate(count, alignof(T), pAllocator, T::GetAllocationScope());
}
void operator delete(void* ptr, const VkAllocationCallbacks* pAllocator)
{
// Should never happen
......
......@@ -453,6 +453,7 @@ void GraphicsPipeline::compileShaders(const VkAllocationCallbacks* pAllocator, c
auto module = Cast(pStage->module);
auto code = preprocessSpirv(module->getCode(), pStage->pSpecializationInfo);
// FIXME (b/119409619): use an allocator here so we can control all memory allocations
// TODO: also pass in any pipeline state which will affect shader compilation
auto spirvShader = new sw::SpirvShader{code};
......
......@@ -24,6 +24,7 @@ namespace vk
Queue::Queue(uint32_t pFamilyIndex, float pPriority) : familyIndex(pFamilyIndex), priority(pPriority)
{
// FIXME (b/119409619): use an allocator here so we can control all memory allocations
context = new sw::Context();
renderer = new sw::Renderer(context, sw::OpenGL, true);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment