blob: a3c756c925bad3b32dbace7d413312d5e1f2f064 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIB_ESCHER_VK_IMAGE_H_
#define LIB_ESCHER_VK_IMAGE_H_
#include "lib/escher/forward_declarations.h"
#include "lib/escher/renderer/semaphore.h"
#include "lib/escher/resources/waitable_resource.h"
#include "lib/escher/util/debug_print.h"
namespace escher {
// Full description of the size and layout of an Image.
#pragma pack(push, 1) // As required by escher::HashMapHasher<ImageInfo>
struct ImageInfo {
vk::Format format = vk::Format::eUndefined;
uint32_t width = 0;
uint32_t height = 0;
uint32_t sample_count = 1;
vk::ImageUsageFlags usage;
vk::MemoryPropertyFlags memory_flags =
vk::MemoryPropertyFlagBits::eDeviceLocal;
vk::ImageTiling tiling = vk::ImageTiling::eOptimal;
bool operator==(const ImageInfo& other) const {
return format == other.format && width == other.width &&
height == other.height && sample_count == other.sample_count &&
usage == other.usage && memory_flags == other.memory_flags;
}
// Transient images are neither loaded nor stored by render passes. Instead
// they may be rendered into by one subpass and used as an input attachment by
// a subsequent pass. Consequently, it may be possible (not implemented yet,
// and depending on the hardware/driver) to avoid allocating any memory for
// such images, so that it exists only transiently in tile-local storage.
bool is_transient() const {
return static_cast<bool>(usage &
vk::ImageUsageFlagBits::eTransientAttachment);
}
};
#pragma pack(pop)
// An Image is a WaitableResource that encapsulates a vk::Image.
class Image : public WaitableResource {
public:
static const ResourceTypeInfo kTypeInfo;
const ResourceTypeInfo& type_info() const override { return kTypeInfo; }
// Constructor. Wraps an existing image without claiming ownership. Useful
// when the image is owned/maintained by another system (e.g.,
// vk::SwapchainKHR).
static ImagePtr WrapVkImage(ResourceManager* image_owner, ImageInfo info,
vk::Image image);
const ImageInfo& info() const { return info_; }
vk::Image vk() const { return image_; }
vk::Format format() const { return info_.format; }
// TODO(ES-82): decide whether to deprecate format().
vk::Format vk_format() const { return info_.format; }
uint32_t width() const { return info_.width; }
uint32_t height() const { return info_.height; }
bool has_depth() const { return has_depth_; }
bool has_stencil() const { return has_stencil_; }
bool is_transient() const { return info_.is_transient(); }
vk::DeviceSize size() const { return size_; }
uint8_t* host_ptr() const { return host_ptr_; }
// TODO(ES-83): how does this interact with swapchain_layout_?
// Should this be automatically set when various transitions are made, e.g.
// finishing a render-pass? Should it be locked so that the layout can't be
// changed during a render-pass where it is used as an attachment?
void set_layout(vk::ImageLayout new_layout) { layout_ = new_layout; }
vk::ImageLayout layout() const { return layout_; }
// Specify the layout that should be transitioned to when this image is used
// as a framebuffer attachment.
void set_swapchain_layout(vk::ImageLayout layout) {
swapchain_layout_ = layout;
}
vk::ImageLayout swapchain_layout() const { return swapchain_layout_; }
bool is_swapchain_image() const {
return swapchain_layout_ != vk::ImageLayout::eUndefined;
}
protected:
// Constructor. In some cases it is necessary to wrap an un-owned vk::Image,
// which should not be destroyed when this Image is destroyed (e.g. when
// working with images associated with a vk::SwapchainKHR); this is done by
// passing nullptr as the |mem| argument.
Image(ResourceManager* image_owner, ImageInfo info, vk::Image image,
vk::DeviceSize size_, uint8_t* host_ptr_);
private:
const ImageInfo info_;
const vk::Image image_;
bool has_depth_;
bool has_stencil_;
const vk::DeviceSize size_;
uint8_t* const host_ptr_;
// TODO(ES-83): consider allowing image to have an initial layout.
vk::ImageLayout layout_ = vk::ImageLayout::eUndefined;
vk::ImageLayout swapchain_layout_ = vk::ImageLayout::eUndefined;
FXL_DISALLOW_COPY_AND_ASSIGN(Image);
};
typedef fxl::RefPtr<Image> ImagePtr;
// Debugging.
ESCHER_DEBUG_PRINTABLE(ImageInfo);
} // namespace escher
#endif // LIB_ESCHER_VK_IMAGE_H_