Skip to content

Commit

Permalink
Merge pull request #12873 from hrydgard/draw-texture-allocator
Browse files Browse the repository at this point in the history
Vulkan: Framebuffer manager: Use an allocator for "MakePixelTexture" images.
  • Loading branch information
unknownbrackets authored May 6, 2020
2 parents 31b1993 + f9f568d commit b942607
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Common/Vulkan/VulkanImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class VulkanDeviceAllocator;

// Wrapper around what you need to use a texture.
// Not very optimal - if you have many small textures you should use other strategies.
// ALWAYS use an allocator when calling CreateDirect.
class VulkanTexture {
public:
VulkanTexture(VulkanContext *vulkan)
Expand Down
24 changes: 21 additions & 3 deletions GPU/Vulkan/FramebufferVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ FramebufferManagerVulkan::FramebufferManagerVulkan(Draw::DrawContext *draw, Vulk
FramebufferManagerCommon(draw),
vulkan_(vulkan) {

InitDeviceObjects();
DeviceRestore(vulkan, draw);

// After a blit we do need to rebind for the VulkanRenderManager to know what to do.
needGLESRebinds_ = true;
Expand All @@ -94,7 +94,7 @@ FramebufferManagerVulkan::FramebufferManagerVulkan(Draw::DrawContext *draw, Vulk
FramebufferManagerVulkan::~FramebufferManagerVulkan() {
delete[] convBuf_;

DestroyDeviceObjects();
DeviceLost();
}

void FramebufferManagerVulkan::SetTextureCache(TextureCacheVulkan *tc) {
Expand Down Expand Up @@ -207,9 +207,12 @@ void FramebufferManagerVulkan::MakePixelTexture(const u8 *srcPixels, GEBufferFor
VkCommandBuffer initCmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER);

// There's only ever a few of these alive, don't need to stress the allocator with these big ones.
// OR NOT! Hot Shot Golf (#12355) does tons of these in a frame in some situations! So actually,
// we do use an allocator. In fact, I've now banned allocator-less textures.

drawPixelsTex_ = new VulkanTexture(vulkan_);
drawPixelsTex_->SetTag("DrawPixels");
if (!drawPixelsTex_->CreateDirect(initCmd, nullptr, width, height, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)) {
if (!drawPixelsTex_->CreateDirect(initCmd, allocator_, width, height, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)) {
// out of memory?
delete drawPixelsTex_;
drawPixelsTex_ = nullptr;
Expand Down Expand Up @@ -551,12 +554,27 @@ void FramebufferManagerVulkan::EndFrame() {
void FramebufferManagerVulkan::DeviceLost() {
DestroyAllFBOs();
DestroyDeviceObjects();

if (allocator_) {
allocator_->Destroy();

// We have to delete on queue, so this can free its queued deletions.
vulkan_->Delete().QueueCallback([](void *ptr) {
auto allocator = static_cast<VulkanDeviceAllocator *>(ptr);
delete allocator;
}, allocator_);
allocator_ = nullptr;
}
}

void FramebufferManagerVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw) {
vulkan_ = vulkan;
draw_ = draw;

_assert_(!allocator_);

allocator_ = new VulkanDeviceAllocator(vulkan_, 1 * 1024 * 1024, 8 * 1024 * 1024);

InitDeviceObjects();
}

Expand Down
1 change: 1 addition & 0 deletions GPU/Vulkan/FramebufferVulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class FramebufferManagerVulkan : public FramebufferManagerCommon {
TextureCacheVulkan *textureCacheVulkan_ = nullptr;
ShaderManagerVulkan *shaderManagerVulkan_ = nullptr;
DrawEngineVulkan *drawEngineVulkan_ = nullptr;
VulkanDeviceAllocator *allocator_ = nullptr;
VulkanPushBuffer *push_;

enum {
Expand Down

0 comments on commit b942607

Please sign in to comment.