}
void VkImageObj::InitNoLayout(uint32_t const width, uint32_t const height, uint32_t const mipLevels, VkFormat const format,
- VkFlags const usage, VkImageTiling const requested_tiling, VkMemoryPropertyFlags const reqs) {
+ VkFlags const usage, VkImageTiling const requested_tiling, VkMemoryPropertyFlags const reqs,
+ const std::vector<uint32_t> *queue_families) {
VkFormatProperties image_fmt;
VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
imageCreateInfo.tiling = tiling;
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ // Automatically set sharing mode etc. based on queue family information
+ if (queue_families && (queue_families->size() > 1)) {
+ imageCreateInfo.sharingMode = VK_SHARING_MODE_CONCURRENT;
+ imageCreateInfo.queueFamilyIndexCount = static_cast<uint32_t>(queue_families->size());
+ imageCreateInfo.pQueueFamilyIndices = queue_families->data();
+ }
+
Layout(imageCreateInfo.initialLayout);
imageCreateInfo.usage = usage;
}
void VkImageObj::Init(uint32_t const width, uint32_t const height, uint32_t const mipLevels, VkFormat const format,
- VkFlags const usage, VkImageTiling const requested_tiling, VkMemoryPropertyFlags const reqs) {
- InitNoLayout(width, height, mipLevels, format, usage, requested_tiling, reqs);
+ VkFlags const usage, VkImageTiling const requested_tiling, VkMemoryPropertyFlags const reqs,
+ const std::vector<uint32_t> *queue_families) {
+ InitNoLayout(width, height, mipLevels, format, usage, requested_tiling, reqs, queue_families);
VkImageLayout newLayout;
if (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
public:
void Init(uint32_t const width, uint32_t const height, uint32_t const mipLevels, VkFormat const format, VkFlags const usage,
- VkImageTiling const tiling = VK_IMAGE_TILING_LINEAR, VkMemoryPropertyFlags const reqs = 0);
+ VkImageTiling const tiling = VK_IMAGE_TILING_LINEAR, VkMemoryPropertyFlags const reqs = 0,
+ const std::vector<uint32_t> *queue_families = nullptr);
void init(const VkImageCreateInfo *create_info);
void InitNoLayout(uint32_t const width, uint32_t const height, uint32_t const mipLevels, VkFormat const format,
- VkFlags const usage, VkImageTiling tiling = VK_IMAGE_TILING_LINEAR, VkMemoryPropertyFlags reqs = 0);
+ VkFlags const usage, VkImageTiling tiling = VK_IMAGE_TILING_LINEAR, VkMemoryPropertyFlags reqs = 0,
+ const std::vector<uint32_t> *queue_families = nullptr);
// void clear( CommandBuffer*, uint32_t[4] );
void init(const Device &dev, const VkBufferCreateInfo &info) { init(dev, info, 0); }
void init(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags mem_props) { init(dev, create_info(size, 0), mem_props); }
void init(const Device &dev, VkDeviceSize size) { init(dev, size, 0); }
- void init_as_src(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags &reqs) {
- init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT), reqs);
+ void init_as_src(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags &reqs,
+ const std::vector<uint32_t> *queue_families = nullptr) {
+ init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, queue_families), reqs);
}
- void init_as_dst(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags &reqs) {
- init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT), reqs);
+ void init_as_dst(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags &reqs,
+ const std::vector<uint32_t> *queue_families = nullptr) {
+ init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, queue_families), reqs);
}
- void init_as_src_and_dst(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags &reqs) {
- init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT), reqs);
+ void init_as_src_and_dst(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags &reqs,
+ const std::vector<uint32_t> *queue_families = nullptr) {
+ init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, queue_families), reqs);
}
void init_no_mem(const Device &dev, const VkBufferCreateInfo &info);
// vkBindObjectMemory()
void bind_memory(const DeviceMemory &mem, VkDeviceSize mem_offset);
- static VkBufferCreateInfo create_info(VkDeviceSize size, VkFlags usage);
+ static VkBufferCreateInfo create_info(VkDeviceSize size, VkFlags usage, const std::vector<uint32_t> *queue_families = nullptr);
VkBufferMemoryBarrier buffer_memory_barrier(VkFlags output_mask, VkFlags input_mask, VkDeviceSize offset,
VkDeviceSize size) const {
barrier.dstAccessMask = input_mask;
barrier.offset = offset;
barrier.size = size;
+ if (create_info_.sharingMode == VK_SHARING_MODE_CONCURRENT) {
+ barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ }
return barrier;
}
VkExtent3D extent(uint32_t mip_level) const { return extent(create_info_.extent, mip_level); }
VkFormat format() const { return create_info_.format; }
VkImageUsageFlags usage() const { return create_info_.usage; }
+ VkSharingMode sharing_mode() const { return create_info_.sharingMode; }
VkImageMemoryBarrier image_memory_barrier(VkFlags output_mask, VkFlags input_mask, VkImageLayout old_layout,
VkImageLayout new_layout, const VkImageSubresourceRange &range) const {
VkImageMemoryBarrier barrier = {};
barrier.newLayout = new_layout;
barrier.image = handle();
barrier.subresourceRange = range;
+
+ if (sharing_mode() == VK_SHARING_MODE_CONCURRENT) {
+ barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ }
return barrier;
}
return info;
}
-inline VkBufferCreateInfo Buffer::create_info(VkDeviceSize size, VkFlags usage) {
+inline VkBufferCreateInfo Buffer::create_info(VkDeviceSize size, VkFlags usage, const std::vector<uint32_t> *queue_families) {
VkBufferCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
info.size = size;
info.usage = usage;
+
+ if (queue_families && queue_families->size() > 1) {
+ info.sharingMode = VK_SHARING_MODE_CONCURRENT;
+ info.queueFamilyIndexCount = static_cast<uint32_t>(queue_families->size());
+ info.pQueueFamilyIndices = queue_families->data();
+ }
+
return info;
}