Commit 57dd97aa by Jamie Madill Committed by Commit Bot

Vulkan: Add helper for allocating image memory.

Also refactors some memory index searching code that was duplicated. This will lead the way to having more code reuse for our Renderbuffers implementation in Vulkan, and for other types of Texture. Bug: angleproject:2347 Change-Id: I49cbd77328c01f945d66f92e6ec4ba7c552abeff Reviewed-on: https://chromium-review.googlesource.com/904684 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent fbb1c792
...@@ -68,7 +68,11 @@ gl::Error BufferVk::setData(const gl::Context *context, ...@@ -68,7 +68,11 @@ gl::Error BufferVk::setData(const gl::Context *context,
createInfo.pQueueFamilyIndices = nullptr; createInfo.pQueueFamilyIndices = nullptr;
ANGLE_TRY(mBuffer.init(device, createInfo)); ANGLE_TRY(mBuffer.init(device, createInfo));
ANGLE_TRY(vk::AllocateBufferMemory(contextVk, size, &mBuffer, &mBufferMemory,
// Assume host vislble/coherent memory available.
VkMemoryPropertyFlags flags =
(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
ANGLE_TRY(vk::AllocateBufferMemory(contextVk, flags, &mBuffer, &mBufferMemory,
&mCurrentRequiredSize)); &mCurrentRequiredSize));
} }
......
...@@ -263,9 +263,8 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context, ...@@ -263,9 +263,8 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context,
vk::Image *readImage = renderTarget->image; vk::Image *readImage = renderTarget->image;
vk::StagingImage stagingImage; vk::StagingImage stagingImage;
ANGLE_TRY(renderer->createStagingImage(TextureDimension::TEX_2D, *renderTarget->format, ANGLE_TRY(stagingImage.init(contextVk, TextureDimension::TEX_2D, *renderTarget->format,
renderTarget->extents, vk::StagingUsage::Read, renderTarget->extents, vk::StagingUsage::Read));
&stagingImage));
vk::CommandBuffer *commandBuffer = nullptr; vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(recordWriteCommands(renderer, &commandBuffer)); ANGLE_TRY(recordWriteCommands(renderer, &commandBuffer));
......
...@@ -62,7 +62,10 @@ gl::Error InitDefaultUniformBlock(const gl::Context *context, ...@@ -62,7 +62,10 @@ gl::Error InitDefaultUniformBlock(const gl::Context *context,
ANGLE_TRY(storageOut->buffer.init(device, uniformBufferInfo)); ANGLE_TRY(storageOut->buffer.init(device, uniformBufferInfo));
ANGLE_TRY(AllocateBufferMemory(vk::GetImpl(context), blockSize, &storageOut->buffer, // Assume host vislble/coherent memory available.
VkMemoryPropertyFlags flags =
(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
ANGLE_TRY(AllocateBufferMemory(vk::GetImpl(context), flags, &storageOut->buffer,
&storageOut->memory, requiredSizeOut)); &storageOut->memory, requiredSizeOut));
return gl::NoError(); return gl::NoError();
...@@ -357,8 +360,11 @@ gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext) ...@@ -357,8 +360,11 @@ gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
ANGLE_TRY(mEmptyUniformBlockStorage.buffer.init(device, uniformBufferInfo)); ANGLE_TRY(mEmptyUniformBlockStorage.buffer.init(device, uniformBufferInfo));
// Assume host vislble/coherent memory available.
VkMemoryPropertyFlags flags =
(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
size_t requiredSize = 0; size_t requiredSize = 0;
ANGLE_TRY(AllocateBufferMemory(contextVk, 1, &mEmptyUniformBlockStorage.buffer, ANGLE_TRY(AllocateBufferMemory(contextVk, flags, &mEmptyUniformBlockStorage.buffer,
&mEmptyUniformBlockStorage.memory, &requiredSize)); &mEmptyUniformBlockStorage.memory, &requiredSize));
} }
......
...@@ -720,17 +720,6 @@ vk::Error RendererVk::submitFrame(const VkSubmitInfo &submitInfo, vk::CommandBuf ...@@ -720,17 +720,6 @@ vk::Error RendererVk::submitFrame(const VkSubmitInfo &submitInfo, vk::CommandBuf
return vk::NoError(); return vk::NoError();
} }
vk::Error RendererVk::createStagingImage(TextureDimension dimension,
const vk::Format &format,
const gl::Extents &extent,
vk::StagingUsage usage,
vk::StagingImage *imageOut)
{
ANGLE_TRY(imageOut->init(mDevice, mCurrentQueueFamilyIndex, mMemoryProperties, dimension,
format.vkTextureFormat, extent, usage));
return vk::NoError();
}
GlslangWrapper *RendererVk::getGlslangWrapper() GlslangWrapper *RendererVk::getGlslangWrapper()
{ {
return mGlslangWrapper; return mGlslangWrapper;
......
...@@ -63,12 +63,6 @@ class RendererVk : angle::NonCopyable ...@@ -63,12 +63,6 @@ class RendererVk : angle::NonCopyable
const gl::Extensions &getNativeExtensions() const; const gl::Extensions &getNativeExtensions() const;
const gl::Limitations &getNativeLimitations() const; const gl::Limitations &getNativeLimitations() const;
vk::Error createStagingImage(TextureDimension dimension,
const vk::Format &format,
const gl::Extents &extent,
vk::StagingUsage usage,
vk::StagingImage *imageOut);
GlslangWrapper *getGlslangWrapper(); GlslangWrapper *getGlslangWrapper();
Serial getCurrentQueueSerial() const; Serial getCurrentQueueSerial() const;
......
...@@ -113,22 +113,10 @@ gl::Error TextureVk::setImage(const gl::Context *context, ...@@ -113,22 +113,10 @@ gl::Error TextureVk::setImage(const gl::Context *context,
ANGLE_TRY(mImage.init(device, imageInfo)); ANGLE_TRY(mImage.init(device, imageInfo));
// Allocate the device memory for the image. VkMemoryPropertyFlags flags = (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
// TODO(jmadill): Use more intelligent device memory allocation. size_t requiredSize = 0;
VkMemoryRequirements memoryRequirements; ANGLE_TRY(
mImage.getMemoryRequirements(device, &memoryRequirements); vk::AllocateImageMemory(contextVk, flags, &mImage, &mDeviceMemory, &requiredSize));
uint32_t memoryIndex = renderer->getMemoryProperties().findCompatibleMemoryIndex(
memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
VkMemoryAllocateInfo allocateInfo;
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocateInfo.pNext = nullptr;
allocateInfo.allocationSize = memoryRequirements.size;
allocateInfo.memoryTypeIndex = memoryIndex;
ANGLE_TRY(mDeviceMemory.allocate(device, allocateInfo));
ANGLE_TRY(mImage.bindMemory(device, mDeviceMemory));
VkImageViewCreateInfo viewInfo; VkImageViewCreateInfo viewInfo;
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
...@@ -220,8 +208,8 @@ gl::Error TextureVk::setSubImageImpl(ContextVk *contextVk, ...@@ -220,8 +208,8 @@ gl::Error TextureVk::setSubImageImpl(ContextVk *contextVk,
const vk::Format &vkFormat = *mRenderTarget.format; const vk::Format &vkFormat = *mRenderTarget.format;
vk::StagingImage stagingImage; vk::StagingImage stagingImage;
ANGLE_TRY(renderer->createStagingImage(TextureDimension::TEX_2D, vkFormat, size, ANGLE_TRY(stagingImage.init(contextVk, TextureDimension::TEX_2D, vkFormat, size,
vk::StagingUsage::Write, &stagingImage)); vk::StagingUsage::Write));
GLuint inputRowPitch = 0; GLuint inputRowPitch = 0;
ANGLE_TRY_RESULT( ANGLE_TRY_RESULT(
......
...@@ -147,6 +147,49 @@ bool HasValidationLayers(const std::vector<VkLayerProperties> &layerProps) ...@@ -147,6 +147,49 @@ bool HasValidationLayers(const std::vector<VkLayerProperties> &layerProps)
return true; return true;
} }
vk::Error FindAndAllocateCompatibleMemory(VkDevice device,
const vk::MemoryProperties &memoryProperties,
VkMemoryPropertyFlags memoryPropertyFlags,
const VkMemoryRequirements &memoryRequirements,
vk::DeviceMemory *deviceMemoryOut)
{
uint32_t memoryTypeIndex = 0;
ANGLE_TRY(memoryProperties.findCompatibleMemoryIndex(memoryRequirements, memoryPropertyFlags,
&memoryTypeIndex));
VkMemoryAllocateInfo allocInfo;
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.pNext = nullptr;
allocInfo.memoryTypeIndex = memoryTypeIndex;
allocInfo.allocationSize = memoryRequirements.size;
ANGLE_TRY(deviceMemoryOut->allocate(device, allocInfo));
return vk::NoError();
}
template <typename T>
vk::Error AllocateBufferOrImageMemory(ContextVk *contextVk,
VkMemoryPropertyFlags memoryPropertyFlags,
T *bufferOrImage,
vk::DeviceMemory *deviceMemoryOut,
size_t *requiredSizeOut)
{
VkDevice device = contextVk->getDevice();
const vk::MemoryProperties &memoryProperties = contextVk->getRenderer()->getMemoryProperties();
// Call driver to determine memory requirements.
VkMemoryRequirements memoryRequirements;
bufferOrImage->getMemoryRequirements(device, &memoryRequirements);
// The requirements size is not always equal to the specified API size.
*requiredSizeOut = static_cast<size_t>(memoryRequirements.size);
ANGLE_TRY(FindAndAllocateCompatibleMemory(device, memoryProperties, memoryPropertyFlags,
memoryRequirements, deviceMemoryOut));
ANGLE_TRY(bufferOrImage->bindMemory(device, *deviceMemoryOut));
return vk::NoError();
}
} // anonymous namespace } // anonymous namespace
const char *g_VkLoaderLayersPathEnv = "VK_LAYER_PATH"; const char *g_VkLoaderLayersPathEnv = "VK_LAYER_PATH";
...@@ -809,21 +852,22 @@ void StagingImage::destroy(VkDevice device) ...@@ -809,21 +852,22 @@ void StagingImage::destroy(VkDevice device)
mDeviceMemory.destroy(device); mDeviceMemory.destroy(device);
} }
Error StagingImage::init(VkDevice device, Error StagingImage::init(ContextVk *contextVk,
uint32_t queueFamilyIndex,
const vk::MemoryProperties &memoryProperties,
TextureDimension dimension, TextureDimension dimension,
VkFormat format, const Format &format,
const gl::Extents &extent, const gl::Extents &extent,
StagingUsage usage) StagingUsage usage)
{ {
VkDevice device = contextVk->getDevice();
uint32_t queueFamilyIndex = contextVk->getRenderer()->getQueueFamilyIndex();
VkImageCreateInfo createInfo; VkImageCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
createInfo.pNext = nullptr; createInfo.pNext = nullptr;
createInfo.flags = 0; createInfo.flags = 0;
createInfo.imageType = VK_IMAGE_TYPE_2D; createInfo.imageType = VK_IMAGE_TYPE_2D;
createInfo.format = format; createInfo.format = format.vkTextureFormat;
createInfo.extent.width = static_cast<uint32_t>(extent.width); createInfo.extent.width = static_cast<uint32_t>(extent.width);
createInfo.extent.height = static_cast<uint32_t>(extent.height); createInfo.extent.height = static_cast<uint32_t>(extent.height);
createInfo.extent.depth = static_cast<uint32_t>(extent.depth); createInfo.extent.depth = static_cast<uint32_t>(extent.depth);
...@@ -843,28 +887,14 @@ Error StagingImage::init(VkDevice device, ...@@ -843,28 +887,14 @@ Error StagingImage::init(VkDevice device,
ANGLE_TRY(mImage.init(device, createInfo)); ANGLE_TRY(mImage.init(device, createInfo));
VkMemoryRequirements memoryRequirements; // Allocate and bind host visible and coherent Image memory.
mImage.getMemoryRequirements(device, &memoryRequirements);
// Find the right kind of memory index.
// TODO(ynovikov): better approach would be to request just visible memory, // TODO(ynovikov): better approach would be to request just visible memory,
// and call vkInvalidateMappedMemoryRanges if the allocated memory is not coherent. // and call vkInvalidateMappedMemoryRanges if the allocated memory is not coherent.
// This would solve potential issues of: // This would solve potential issues of:
// 1) not having (enough) coherent memory and 2) coherent memory being slower // 1) not having (enough) coherent memory and 2) coherent memory being slower
uint32_t memoryIndex = memoryProperties.findCompatibleMemoryIndex( VkMemoryPropertyFlags memoryPropertyFlags =
memoryRequirements.memoryTypeBits, (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); ANGLE_TRY(AllocateImageMemory(contextVk, memoryPropertyFlags, &mImage, &mDeviceMemory, &mSize));
VkMemoryAllocateInfo allocateInfo;
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocateInfo.pNext = nullptr;
allocateInfo.allocationSize = memoryRequirements.size;
allocateInfo.memoryTypeIndex = memoryIndex;
ANGLE_TRY(mDeviceMemory.allocate(device, allocateInfo));
ANGLE_TRY(mImage.bindMemory(device, mDeviceMemory));
mSize = memoryRequirements.size;
return NoError(); return NoError();
} }
...@@ -903,6 +933,12 @@ Error Buffer::bindMemory(VkDevice device, const DeviceMemory &deviceMemory) ...@@ -903,6 +933,12 @@ Error Buffer::bindMemory(VkDevice device, const DeviceMemory &deviceMemory)
return NoError(); return NoError();
} }
void Buffer::getMemoryRequirements(VkDevice device, VkMemoryRequirements *memoryRequirementsOut)
{
ASSERT(valid());
vkGetBufferMemoryRequirements(device, mHandle, memoryRequirementsOut);
}
// ShaderModule implementation. // ShaderModule implementation.
ShaderModule::ShaderModule() ShaderModule::ShaderModule()
{ {
...@@ -1077,24 +1113,30 @@ void MemoryProperties::init(VkPhysicalDevice physicalDevice) ...@@ -1077,24 +1113,30 @@ void MemoryProperties::init(VkPhysicalDevice physicalDevice)
ASSERT(mMemoryProperties.memoryTypeCount > 0); ASSERT(mMemoryProperties.memoryTypeCount > 0);
} }
uint32_t MemoryProperties::findCompatibleMemoryIndex(uint32_t bitMask, uint32_t propertyFlags) const Error MemoryProperties::findCompatibleMemoryIndex(const VkMemoryRequirements &memoryRequirements,
VkMemoryPropertyFlags memoryPropertyFlags,
uint32_t *typeIndexOut) const
{ {
ASSERT(mMemoryProperties.memoryTypeCount > 0); ASSERT(mMemoryProperties.memoryTypeCount > 0 && mMemoryProperties.memoryTypeCount <= 32);
// TODO(jmadill): Cache compatible memory indexes after finding them once. // Find a compatible memory pool index. If the index doesn't change, we could cache it.
for (size_t memoryIndex : angle::BitSet32<32>(bitMask)) // Not finding a valid memory pool means an out-of-spec driver, or internal error.
// TODO(jmadill): Determine if it is possible to cache indexes.
// TODO(jmadill): More efficient memory allocation.
for (size_t memoryIndex : angle::BitSet32<32>(memoryRequirements.memoryTypeBits))
{ {
ASSERT(memoryIndex < mMemoryProperties.memoryTypeCount); ASSERT(memoryIndex < mMemoryProperties.memoryTypeCount);
if ((mMemoryProperties.memoryTypes[memoryIndex].propertyFlags & propertyFlags) == if ((mMemoryProperties.memoryTypes[memoryIndex].propertyFlags & memoryPropertyFlags) ==
propertyFlags) memoryPropertyFlags)
{ {
return static_cast<uint32_t>(memoryIndex); *typeIndexOut = static_cast<uint32_t>(memoryIndex);
return NoError();
} }
} }
UNREACHABLE(); // TODO(jmadill): Add error message to error.
return std::numeric_limits<uint32_t>::max(); return vk::Error(VK_ERROR_INCOMPATIBLE_DRIVER);
} }
// StagingBuffer implementation. // StagingBuffer implementation.
...@@ -1121,9 +1163,11 @@ vk::Error StagingBuffer::init(ContextVk *contextVk, VkDeviceSize size, StagingUs ...@@ -1121,9 +1163,11 @@ vk::Error StagingBuffer::init(ContextVk *contextVk, VkDeviceSize size, StagingUs
createInfo.queueFamilyIndexCount = 0; createInfo.queueFamilyIndexCount = 0;
createInfo.pQueueFamilyIndices = nullptr; createInfo.pQueueFamilyIndices = nullptr;
VkMemoryPropertyFlags flags =
(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
ANGLE_TRY(mBuffer.init(contextVk->getDevice(), createInfo)); ANGLE_TRY(mBuffer.init(contextVk->getDevice(), createInfo));
ANGLE_TRY(AllocateBufferMemory(contextVk, static_cast<size_t>(size), &mBuffer, &mDeviceMemory, ANGLE_TRY(AllocateBufferMemory(contextVk, flags, &mBuffer, &mDeviceMemory, &mSize));
&mSize));
return vk::NoError(); return vk::NoError();
} }
...@@ -1134,60 +1178,24 @@ void StagingBuffer::dumpResources(Serial serial, std::vector<vk::GarbageObject> ...@@ -1134,60 +1178,24 @@ void StagingBuffer::dumpResources(Serial serial, std::vector<vk::GarbageObject>
mDeviceMemory.dumpResources(serial, garbageQueue); mDeviceMemory.dumpResources(serial, garbageQueue);
} }
Optional<uint32_t> FindMemoryType(const VkPhysicalDeviceMemoryProperties &memoryProps,
const VkMemoryRequirements &requirements,
uint32_t propertyFlagMask)
{
for (uint32_t typeIndex = 0; typeIndex < memoryProps.memoryTypeCount; ++typeIndex)
{
if ((requirements.memoryTypeBits & (1u << typeIndex)) != 0 &&
((memoryProps.memoryTypes[typeIndex].propertyFlags & propertyFlagMask) ==
propertyFlagMask))
{
return typeIndex;
}
}
return Optional<uint32_t>::Invalid();
}
Error AllocateBufferMemory(ContextVk *contextVk, Error AllocateBufferMemory(ContextVk *contextVk,
size_t size, VkMemoryPropertyFlags memoryPropertyFlags,
Buffer *buffer, Buffer *buffer,
DeviceMemory *deviceMemoryOut, DeviceMemory *deviceMemoryOut,
size_t *requiredSizeOut) size_t *requiredSizeOut)
{ {
VkDevice device = contextVk->getDevice(); return AllocateBufferOrImageMemory(contextVk, memoryPropertyFlags, buffer, deviceMemoryOut,
requiredSizeOut);
// Find a compatible memory pool index. If the index doesn't change, we could cache it. }
// Not finding a valid memory pool means an out-of-spec driver, or internal error.
// TODO(jmadill): More efficient memory allocation.
VkMemoryRequirements memoryRequirements;
vkGetBufferMemoryRequirements(device, buffer->getHandle(), &memoryRequirements);
// The requirements size is not always equal to the specified API size.
ASSERT(memoryRequirements.size >= size);
*requiredSizeOut = static_cast<size_t>(memoryRequirements.size);
VkPhysicalDeviceMemoryProperties memoryProperties;
vkGetPhysicalDeviceMemoryProperties(contextVk->getRenderer()->getPhysicalDevice(),
&memoryProperties);
auto memoryTypeIndex =
FindMemoryType(memoryProperties, memoryRequirements,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
ANGLE_VK_CHECK(memoryTypeIndex.valid(), VK_ERROR_INCOMPATIBLE_DRIVER);
VkMemoryAllocateInfo allocInfo;
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.pNext = nullptr;
allocInfo.memoryTypeIndex = memoryTypeIndex.value();
allocInfo.allocationSize = memoryRequirements.size;
ANGLE_TRY(deviceMemoryOut->allocate(device, allocInfo));
ANGLE_TRY(buffer->bindMemory(device, *deviceMemoryOut));
return NoError(); Error AllocateImageMemory(ContextVk *contextVk,
VkMemoryPropertyFlags memoryPropertyFlags,
Image *image,
DeviceMemory *deviceMemoryOut,
size_t *requiredSizeOut)
{
return AllocateBufferOrImageMemory(contextVk, memoryPropertyFlags, image, deviceMemoryOut,
requiredSizeOut);
} }
// GarbageObject implementation. // GarbageObject implementation.
......
...@@ -115,18 +115,6 @@ GetImplType<T> *GetImpl(const T *glObject) ...@@ -115,18 +115,6 @@ GetImplType<T> *GetImpl(const T *glObject)
return GetImplAs<GetImplType<T>>(glObject); return GetImplAs<GetImplType<T>>(glObject);
} }
class MemoryProperties final : angle::NonCopyable
{
public:
MemoryProperties();
void init(VkPhysicalDevice physicalDevice);
uint32_t findCompatibleMemoryIndex(uint32_t bitMask, uint32_t propertyFlags) const;
private:
VkPhysicalDeviceMemoryProperties mMemoryProperties;
};
class Error final class Error final
{ {
public: public:
...@@ -292,6 +280,20 @@ class WrappedObject : angle::NonCopyable ...@@ -292,6 +280,20 @@ class WrappedObject : angle::NonCopyable
HandleT mHandle; HandleT mHandle;
}; };
class MemoryProperties final : angle::NonCopyable
{
public:
MemoryProperties();
void init(VkPhysicalDevice physicalDevice);
Error findCompatibleMemoryIndex(const VkMemoryRequirements &memoryRequirements,
VkMemoryPropertyFlags memoryPropertyFlags,
uint32_t *indexOut) const;
private:
VkPhysicalDeviceMemoryProperties mMemoryProperties;
};
class CommandPool final : public WrappedObject<CommandPool, VkCommandPool> class CommandPool final : public WrappedObject<CommandPool, VkCommandPool>
{ {
public: public:
...@@ -481,6 +483,7 @@ class Buffer final : public WrappedObject<Buffer, VkBuffer> ...@@ -481,6 +483,7 @@ class Buffer final : public WrappedObject<Buffer, VkBuffer>
Error init(VkDevice device, const VkBufferCreateInfo &createInfo); Error init(VkDevice device, const VkBufferCreateInfo &createInfo);
Error bindMemory(VkDevice device, const DeviceMemory &deviceMemory); Error bindMemory(VkDevice device, const DeviceMemory &deviceMemory);
void getMemoryRequirements(VkDevice device, VkMemoryRequirements *memoryRequirementsOut);
}; };
class ShaderModule final : public WrappedObject<ShaderModule, VkShaderModule> class ShaderModule final : public WrappedObject<ShaderModule, VkShaderModule>
...@@ -559,11 +562,9 @@ class StagingImage final : angle::NonCopyable ...@@ -559,11 +562,9 @@ class StagingImage final : angle::NonCopyable
StagingImage(StagingImage &&other); StagingImage(StagingImage &&other);
void destroy(VkDevice device); void destroy(VkDevice device);
vk::Error init(VkDevice device, vk::Error init(ContextVk *contextVk,
uint32_t queueFamilyIndex,
const MemoryProperties &memoryProperties,
TextureDimension dimension, TextureDimension dimension,
VkFormat format, const Format &format,
const gl::Extents &extent, const gl::Extents &extent,
StagingUsage usage); StagingUsage usage);
...@@ -578,7 +579,7 @@ class StagingImage final : angle::NonCopyable ...@@ -578,7 +579,7 @@ class StagingImage final : angle::NonCopyable
private: private:
Image mImage; Image mImage;
DeviceMemory mDeviceMemory; DeviceMemory mDeviceMemory;
VkDeviceSize mSize; size_t mSize;
}; };
// Similar to StagingImage, for Buffers. // Similar to StagingImage, for Buffers.
...@@ -641,12 +642,8 @@ class ObjectAndSerial final : angle::NonCopyable ...@@ -641,12 +642,8 @@ class ObjectAndSerial final : angle::NonCopyable
Serial mQueueSerial; Serial mQueueSerial;
}; };
Optional<uint32_t> FindMemoryType(const VkPhysicalDeviceMemoryProperties &memoryProps,
const VkMemoryRequirements &requirements,
uint32_t propertyFlagMask);
Error AllocateBufferMemory(ContextVk *contextVk, Error AllocateBufferMemory(ContextVk *contextVk,
size_t size, VkMemoryPropertyFlags memoryPropertyFlags,
Buffer *buffer, Buffer *buffer,
DeviceMemory *deviceMemoryOut, DeviceMemory *deviceMemoryOut,
size_t *requiredSizeOut); size_t *requiredSizeOut);
...@@ -657,6 +654,12 @@ struct BufferAndMemory final : private angle::NonCopyable ...@@ -657,6 +654,12 @@ struct BufferAndMemory final : private angle::NonCopyable
vk::DeviceMemory memory; vk::DeviceMemory memory;
}; };
Error AllocateImageMemory(ContextVk *contextVk,
VkMemoryPropertyFlags memoryPropertyFlags,
Image *image,
DeviceMemory *deviceMemoryOut,
size_t *requiredSizeOut);
} // namespace vk } // namespace vk
namespace gl_vk namespace gl_vk
......
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