Skip to content

Commit

Permalink
Vulkan: Remove the old method of uploading images.
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Feb 25, 2018
1 parent eb014e8 commit e185232
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 272 deletions.
205 changes: 1 addition & 204 deletions Common/Vulkan/VulkanImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,204 +2,6 @@
#include "Common/Vulkan/VulkanMemory.h"
#include "Common/Log.h"

VkResult VulkanTexture::Create(int w, int h, VkFormat format) {
tex_width = w;
tex_height = h;
format_ = format;

VkFormatProperties formatProps;
vkGetPhysicalDeviceFormatProperties(vulkan_->GetPhysicalDevice(), format, &formatProps);
return VK_SUCCESS;
}

void VulkanTexture::CreateMappableImage() {
// If we already have a mappableImage, forget it.
if (mappableImage) {
vulkan_->Delete().QueueDeleteImage(mappableImage);
}
if (mappableMemory) {
vulkan_->Delete().QueueDeleteDeviceMemory(mappableMemory);
}

VkImageCreateInfo image_create_info{ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
image_create_info.imageType = VK_IMAGE_TYPE_2D;
image_create_info.format = format_;
image_create_info.extent.width = tex_width;
image_create_info.extent.height = tex_height;
image_create_info.extent.depth = 1;
image_create_info.mipLevels = 1;
image_create_info.arrayLayers = 1;
image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
image_create_info.queueFamilyIndexCount = 0;
image_create_info.pQueueFamilyIndices = NULL;
image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
image_create_info.flags = 0;
image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;

VkMemoryAllocateInfo mem_alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
mem_alloc.allocationSize = 0;
mem_alloc.memoryTypeIndex = 0;

// Create a mappable image. It will be the texture if linear images are ok to be textures
// or it will be the staging image if they are not.
VkResult res = vkCreateImage(vulkan_->GetDevice(), &image_create_info, NULL, &mappableImage);
assert(res == VK_SUCCESS);

vkGetImageMemoryRequirements(vulkan_->GetDevice(), mappableImage, &mem_reqs);
assert(res == VK_SUCCESS);

mem_alloc.allocationSize = mem_reqs.size;

// Find the memory type that is host mappable.
bool pass = vulkan_->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &mem_alloc.memoryTypeIndex);
assert(pass);

res = vkAllocateMemory(vulkan_->GetDevice(), &mem_alloc, NULL, &mappableMemory);
assert(res == VK_SUCCESS);

res = vkBindImageMemory(vulkan_->GetDevice(), mappableImage, mappableMemory, 0);
assert(res == VK_SUCCESS);
}

uint8_t *VulkanTexture::Lock(int level, int *rowPitch) {
CreateMappableImage();

VkImageSubresource subres = {};
subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subres.mipLevel = 0;
subres.arrayLayer = 0;

VkSubresourceLayout layout;
void *data;

// Get the subresource layout so we know what the row pitch is
vkGetImageSubresourceLayout(vulkan_->GetDevice(), mappableImage, &subres, &layout);
VkResult res = vkMapMemory(vulkan_->GetDevice(), mappableMemory, layout.offset, layout.size, 0, &data);
assert(res == VK_SUCCESS);

*rowPitch = (int)layout.rowPitch;
return (uint8_t *)data;
}

void VulkanTexture::Unlock(VkCommandBuffer cmd) {
vkUnmapMemory(vulkan_->GetDevice(), mappableMemory);

// if we already have an image, queue it for destruction and forget it.
Wipe();

{ // Shrink the diff by not unindenting. If you make major changes, remove this.
VkImageCreateInfo image_create_info{ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
image_create_info.imageType = VK_IMAGE_TYPE_2D;
image_create_info.format = format_;
image_create_info.extent.width = tex_width;
image_create_info.extent.height = tex_height;
image_create_info.extent.depth = 1;
image_create_info.mipLevels = 1;
image_create_info.arrayLayers = 1;
image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
image_create_info.queueFamilyIndexCount = 0;
image_create_info.pQueueFamilyIndices = NULL;
image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
image_create_info.flags = 0;
// The mappable image cannot be our texture, so create an optimally tiled image and blit to it
image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

VkResult res = vkCreateImage(vulkan_->GetDevice(), &image_create_info, NULL, &image);
assert(res == VK_SUCCESS);

vkGetImageMemoryRequirements(vulkan_->GetDevice(), image, &mem_reqs);

VkMemoryAllocateInfo mem_alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
mem_alloc.memoryTypeIndex = 0;
mem_alloc.allocationSize = mem_reqs.size;

if (allocator_) {
offset_ = allocator_->Allocate(mem_reqs, &mem);
} else {
offset_ = 0;
// Find memory type - don't specify any mapping requirements
bool pass = vulkan_->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &mem_alloc.memoryTypeIndex);
assert(pass);
res = vkAllocateMemory(vulkan_->GetDevice(), &mem_alloc, NULL, &mem);
assert(res == VK_SUCCESS);
}

res = vkBindImageMemory(vulkan_->GetDevice(), image, mem, offset_);
assert(res == VK_SUCCESS);

// Since we're going to blit from the mappable image, set its layout to SOURCE_OPTIMAL
TransitionImageLayout2(cmd, mappableImage, 0, 1,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);

TransitionImageLayout2(cmd, image, 0, 1,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, VK_ACCESS_TRANSFER_WRITE_BIT);

VkImageCopy copy_region;
copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_region.srcSubresource.mipLevel = 0;
copy_region.srcSubresource.baseArrayLayer = 0;
copy_region.srcSubresource.layerCount = 1;
copy_region.srcOffset.x = 0;
copy_region.srcOffset.y = 0;
copy_region.srcOffset.z = 0;
copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_region.dstSubresource.mipLevel = 0;
copy_region.dstSubresource.baseArrayLayer = 0;
copy_region.dstSubresource.layerCount = 1;
copy_region.dstOffset.x = 0;
copy_region.dstOffset.y = 0;
copy_region.dstOffset.z = 0;
copy_region.extent.width = tex_width;
copy_region.extent.height = tex_height;
copy_region.extent.depth = 1;

// Put the copy command into the command buffer
vkCmdCopyImage(cmd,
mappableImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &copy_region);

assert(res == VK_SUCCESS);

// Set the layout for the texture image from DESTINATION_OPTIMAL to SHADER_READ_ONLY
TransitionImageLayout2(cmd, image, 0, 1,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);

// Then drop the temporary mappable image - although should not be necessary...
vulkan_->Delete().QueueDeleteImage(mappableImage);
vulkan_->Delete().QueueDeleteDeviceMemory(mappableMemory);
}

VkImageViewCreateInfo view_info{ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
view_info.image = image;
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_info.format = format_;
view_info.components.r = VK_COMPONENT_SWIZZLE_R;
view_info.components.g = VK_COMPONENT_SWIZZLE_G;
view_info.components.b = VK_COMPONENT_SWIZZLE_B;
view_info.components.a = VK_COMPONENT_SWIZZLE_A;
view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
view_info.subresourceRange.baseMipLevel = 0;
view_info.subresourceRange.levelCount = 1;
view_info.subresourceRange.baseArrayLayer = 0;
view_info.subresourceRange.layerCount = 1;
VkResult res = vkCreateImageView(vulkan_->GetDevice(), &view_info, NULL, &view);
assert(res == VK_SUCCESS);
}

void VulkanTexture::Wipe() {
if (image) {
vulkan_->Delete().QueueDeleteImage(image);
Expand Down Expand Up @@ -262,6 +64,7 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips,
return false;
}

VkMemoryRequirements mem_reqs{};
vkGetImageMemoryRequirements(vulkan_->GetDevice(), image, &mem_reqs);

if (allocator_) {
Expand Down Expand Up @@ -399,15 +202,9 @@ void VulkanTexture::Destroy() {
vulkan_->Delete().QueueDeleteImageView(view);
}
if (image != VK_NULL_HANDLE) {
if (mappableImage == image) {
mappableImage = VK_NULL_HANDLE;
}
vulkan_->Delete().QueueDeleteImage(image);
}
if (mem != VK_NULL_HANDLE && !allocator_) {
if (mappableMemory == mem) {
mappableMemory = VK_NULL_HANDLE;
}
vulkan_->Delete().QueueDeleteDeviceMemory(mem);
} else if (mem != VK_NULL_HANDLE) {
allocator_->Free(mem, offset_);
Expand Down
17 changes: 1 addition & 16 deletions Common/Vulkan/VulkanImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,12 @@ class VulkanTexture {
VulkanTexture(VulkanContext *vulkan, VulkanDeviceAllocator *allocator)
: vulkan_(vulkan), image(VK_NULL_HANDLE), mem(VK_NULL_HANDLE), view(VK_NULL_HANDLE),
tex_width(0), tex_height(0), numMips_(1), format_(VK_FORMAT_UNDEFINED),
mappableImage(VK_NULL_HANDLE), mappableMemory(VK_NULL_HANDLE),
allocator_(allocator), offset_(0) {
memset(&mem_reqs, 0, sizeof(mem_reqs));
}
~VulkanTexture() {
Destroy();
}

// Simple usage - no cleverness, no mipmaps.
// Always call Create, Lock, Unlock. Unlock performs the upload if necessary.
// Can later Lock and Unlock again. This cannot change the format. Create cannot
// be called a second time without recreating the texture object until Destroy has
// been called.
VkResult Create(int w, int h, VkFormat format);
uint8_t *Lock(int level, int *rowPitch);
void Unlock(VkCommandBuffer cmd);

// Fast uploads from buffer. Mipmaps supported.
// Usage must at least include VK_IMAGE_USAGE_TRANSFER_DST_BIT in order to use UploadMip.
// When using UploadMip, initialLayout should be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
Expand All @@ -50,18 +39,14 @@ class VulkanTexture {
VkFormat GetFormat() const { return format_; }

private:
void CreateMappableImage();
void Wipe();

VulkanContext *vulkan_;
VkImage image;
VkDeviceMemory mem;
VkImageView view;
VkDeviceMemory mem;
int32_t tex_width, tex_height, numMips_;
VkFormat format_;
VkImage mappableImage;
VkDeviceMemory mappableMemory;
VkMemoryRequirements mem_reqs;
VulkanDeviceAllocator *allocator_;
size_t offset_;
};
18 changes: 0 additions & 18 deletions UI/NativeApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,6 @@ static UI::Theme ui_theme;
#include "android/android-ndk-profiler/prof.h"
#endif

std::unique_ptr<ManagedTexture> uiTexture;

ScreenManager *screenManager;
std::string config_filename;

Expand Down Expand Up @@ -622,16 +620,6 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) {

UIThemeInit();

uiTexture = CreateTextureFromFile(g_draw, "ui_atlas.zim", ImageFileType::ZIM);
if (!uiTexture) {
PanicAlert("Failed to load ui_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory.");
ELOG("Failed to load ui_atlas.zim");
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
UINT ExitCode = 0;
ExitProcess(ExitCode);
#endif
}

uiContext = new UIContext();
uiContext->theme = &ui_theme;

Expand Down Expand Up @@ -714,8 +702,6 @@ void NativeShutdownGraphics() {

UIBackgroundShutdown();

uiTexture.reset(nullptr);

delete uiContext;
uiContext = nullptr;

Expand Down Expand Up @@ -804,10 +790,6 @@ void RenderOverlays(UIContext *dc, void *userdata) {
void NativeRender(GraphicsContext *graphicsContext) {
g_GameManager.Update();

// If uitexture gets reloaded, make sure we use the latest one.
// Not sure this happens anymore now that we tear down all graphics on app switches...
uiContext->FrameSetup(uiTexture->GetTexture());

float xres = dp_xres;
float yres = dp_yres;

Expand Down
1 change: 0 additions & 1 deletion UI/TextureUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include <memory>

#include "thin3d/thin3d.h"
#include "Core/Config.h"

enum ImageFileType {
PNG,
Expand Down
Loading

0 comments on commit e185232

Please sign in to comment.