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) ...@@ -1104,6 +1104,7 @@ VkResult CommandBuffer::reset(VkCommandPoolResetFlags flags)
template<typename T, typename... Args> template<typename T, typename... Args>
void CommandBuffer::addCommand(Args&&... 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)...))); commands->push_back(std::unique_ptr<T>(new T(std::forward<Args>(args)...)));
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "VkCommandBuffer.hpp" #include "VkCommandBuffer.hpp"
#include "VkDestroy.h" #include "VkDestroy.h"
#include <algorithm> #include <algorithm>
#include <new>
namespace vk namespace vk
{ {
...@@ -23,7 +24,10 @@ namespace vk ...@@ -23,7 +24,10 @@ namespace vk
CommandPool::CommandPool(const VkCommandPoolCreateInfo* pCreateInfo, void* mem) CommandPool::CommandPool(const VkCommandPoolCreateInfo* pCreateInfo, void* mem)
{ {
// FIXME (b/119409619): use an allocator here so we can control all memory allocations // 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) void CommandPool::destroy(const VkAllocationCallbacks* pAllocator)
...@@ -35,7 +39,7 @@ 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 // 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) size_t CommandPool::ComputeRequiredAllocationSize(const VkCommandPoolCreateInfo* pCreateInfo)
...@@ -47,7 +51,11 @@ VkResult CommandPool::allocateCommandBuffers(VkCommandBufferLevel level, uint32_ ...@@ -47,7 +51,11 @@ VkResult CommandPool::allocateCommandBuffers(VkCommandBufferLevel level, uint32_
{ {
for(uint32_t i = 0; i < commandBufferCount; i++) 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) if(commandBuffer)
{ {
pCommandBuffers[i] = *commandBuffer; pCommandBuffers[i] = *commandBuffer;
......
...@@ -47,6 +47,7 @@ size_t DescriptorPool::ComputeRequiredAllocationSize(const VkDescriptorPoolCreat ...@@ -47,6 +47,7 @@ size_t DescriptorPool::ComputeRequiredAllocationSize(const VkDescriptorPoolCreat
VkResult DescriptorPool::allocateSets(uint32_t descriptorSetCount, const VkDescriptorSetLayout* pSetLayouts, VkDescriptorSet* pDescriptorSets) 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]); std::unique_ptr<size_t[]> layoutSizes(new size_t[descriptorSetCount]);
for(uint32_t i = 0; i < descriptorSetCount; i++) for(uint32_t i = 0; i < descriptorSetCount; i++)
{ {
......
...@@ -52,6 +52,7 @@ Device::Device(const Device::CreateInfo* info, void* mem) ...@@ -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. 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(); blitter = new sw::Blitter();
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "VkDebug.hpp" #include "VkDebug.hpp"
#include "VkMemory.h" #include "VkMemory.h"
#include <new>
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
#include <vulkan/vk_icd.h> #include <vulkan/vk_icd.h>
...@@ -43,7 +44,14 @@ static VkResult Create(const VkAllocationCallbacks* pAllocator, const CreateInfo ...@@ -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) if(!object)
{ {
...@@ -64,11 +72,6 @@ public: ...@@ -64,11 +72,6 @@ public:
void destroy(const VkAllocationCallbacks* pAllocator) {} // Method defined by objects to delete their content, if necessary 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) void operator delete(void* ptr, const VkAllocationCallbacks* pAllocator)
{ {
// Should never happen // Should never happen
...@@ -119,11 +122,6 @@ public: ...@@ -119,11 +122,6 @@ public:
object.destroy(pAllocator); 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) void operator delete(void* ptr, const VkAllocationCallbacks* pAllocator)
{ {
// Should never happen // Should never happen
......
...@@ -453,6 +453,7 @@ void GraphicsPipeline::compileShaders(const VkAllocationCallbacks* pAllocator, c ...@@ -453,6 +453,7 @@ void GraphicsPipeline::compileShaders(const VkAllocationCallbacks* pAllocator, c
auto module = Cast(pStage->module); auto module = Cast(pStage->module);
auto code = preprocessSpirv(module->getCode(), pStage->pSpecializationInfo); 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 // TODO: also pass in any pipeline state which will affect shader compilation
auto spirvShader = new sw::SpirvShader{code}; auto spirvShader = new sw::SpirvShader{code};
......
...@@ -24,6 +24,7 @@ namespace vk ...@@ -24,6 +24,7 @@ namespace vk
Queue::Queue(uint32_t pFamilyIndex, float pPriority) : familyIndex(pFamilyIndex), priority(pPriority) 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(); context = new sw::Context();
renderer = new sw::Renderer(context, sw::OpenGL, true); 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