Vulkan: Use new readback methods for texture encoding
This commit is contained in:
parent
c2cc128f1b
commit
59517318d6
|
@ -67,9 +67,6 @@ TextureConverter::~TextureConverter()
|
|||
if (m_encoding_render_pass != VK_NULL_HANDLE)
|
||||
vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_encoding_render_pass, nullptr);
|
||||
|
||||
if (m_encoding_render_framebuffer != VK_NULL_HANDLE)
|
||||
vkDestroyFramebuffer(g_vulkan_context->GetDevice(), m_encoding_render_framebuffer, nullptr);
|
||||
|
||||
for (auto& it : m_encoding_shaders)
|
||||
vkDestroyShaderModule(g_vulkan_context->GetDevice(), it.second, nullptr);
|
||||
|
||||
|
@ -111,12 +108,6 @@ bool TextureConverter::Initialize()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!CreateEncodingDownloadTexture())
|
||||
{
|
||||
PanicAlert("Failed to create download texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CreateDecodingTexture())
|
||||
{
|
||||
PanicAlert("Failed to create decoding texture");
|
||||
|
@ -245,8 +236,10 @@ void TextureConverter::EncodeTextureToMemory(VkImageView src_texture, u8* dest_p
|
|||
// Can't do our own draw within a render pass.
|
||||
StateTracker::GetInstance()->EndRenderPass();
|
||||
|
||||
m_encoding_render_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
static_cast<VKTexture*>(m_encoding_render_texture.get())
|
||||
->GetRawTexIdentifier()
|
||||
->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_PUSH_CONSTANT),
|
||||
|
@ -276,23 +269,15 @@ void TextureConverter::EncodeTextureToMemory(VkImageView src_texture, u8* dest_p
|
|||
render_height);
|
||||
|
||||
VkRect2D render_region = {{0, 0}, {render_width, render_height}};
|
||||
draw.BeginRenderPass(m_encoding_render_framebuffer, render_region);
|
||||
draw.BeginRenderPass(static_cast<VKTexture*>(m_encoding_render_texture.get())->GetFramebuffer(),
|
||||
render_region);
|
||||
draw.DrawWithoutVertexBuffer(4);
|
||||
draw.EndRenderPass();
|
||||
|
||||
// Transition the image before copying
|
||||
m_encoding_render_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
m_encoding_download_texture->CopyFromImage(
|
||||
g_command_buffer_mgr->GetCurrentCommandBuffer(), m_encoding_render_texture->GetImage(),
|
||||
VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, render_width, render_height, 0, 0);
|
||||
|
||||
// Block until the GPU has finished copying to the staging texture.
|
||||
Util::ExecuteCurrentCommandsAndRestoreState(false, true);
|
||||
|
||||
// Copy from staging texture to the final destination, adjusting pitch if necessary.
|
||||
m_encoding_download_texture->ReadTexels(0, 0, render_width, render_height, dest_ptr,
|
||||
memory_stride);
|
||||
MathUtil::Rectangle<int> copy_rect(0, 0, render_width, render_height);
|
||||
m_encoding_readback_texture->CopyFromTexture(m_encoding_render_texture.get(), copy_rect, 0, 0,
|
||||
copy_rect);
|
||||
m_encoding_readback_texture->ReadTexels(copy_rect, dest_ptr, memory_stride);
|
||||
}
|
||||
|
||||
void TextureConverter::EncodeTextureToMemoryYUYV(void* dst_ptr, u32 dst_width, u32 dst_stride,
|
||||
|
@ -304,8 +289,9 @@ void TextureConverter::EncodeTextureToMemoryYUYV(void* dst_ptr, u32 dst_width, u
|
|||
// Borrow framebuffer from EFB2RAM encoder.
|
||||
VkCommandBuffer command_buffer = g_command_buffer_mgr->GetCurrentCommandBuffer();
|
||||
src_texture->TransitionToLayout(command_buffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
m_encoding_render_texture->TransitionToLayout(command_buffer,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
static_cast<VKTexture*>(m_encoding_render_texture.get())
|
||||
->GetRawTexIdentifier()
|
||||
->TransitionToLayout(command_buffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
// Use fragment shader to convert RGBA to YUYV.
|
||||
// Use linear sampler for downscaling. This texture is in BGRA order, so the data is already in
|
||||
|
@ -317,7 +303,8 @@ void TextureConverter::EncodeTextureToMemoryYUYV(void* dst_ptr, u32 dst_width, u
|
|||
m_encoding_render_pass, g_shader_cache->GetPassthroughVertexShader(),
|
||||
VK_NULL_HANDLE, m_rgb_to_yuyv_shader);
|
||||
VkRect2D region = {{0, 0}, {output_width, dst_height}};
|
||||
draw.BeginRenderPass(m_encoding_render_framebuffer, region);
|
||||
draw.BeginRenderPass(static_cast<VKTexture*>(m_encoding_render_texture.get())->GetFramebuffer(),
|
||||
region);
|
||||
draw.SetPSSampler(0, src_texture->GetView(), g_object_cache->GetLinearSampler());
|
||||
draw.DrawQuad(0, 0, static_cast<int>(output_width), static_cast<int>(dst_height), src_rect.left,
|
||||
src_rect.top, 0, src_rect.GetWidth(), src_rect.GetHeight(),
|
||||
|
@ -325,18 +312,11 @@ void TextureConverter::EncodeTextureToMemoryYUYV(void* dst_ptr, u32 dst_width, u
|
|||
static_cast<int>(src_texture->GetHeight()));
|
||||
draw.EndRenderPass();
|
||||
|
||||
// Render pass transitions to TRANSFER_SRC.
|
||||
m_encoding_render_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
|
||||
// Copy from encoding texture to download buffer.
|
||||
m_encoding_download_texture->CopyFromImage(command_buffer, m_encoding_render_texture->GetImage(),
|
||||
VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, output_width,
|
||||
dst_height, 0, 0);
|
||||
Util::ExecuteCurrentCommandsAndRestoreState(false, true);
|
||||
|
||||
// Finally, copy to guest memory. This may have a different stride.
|
||||
m_encoding_download_texture->ReadTexels(0, 0, output_width, dst_height, dst_ptr, dst_stride);
|
||||
MathUtil::Rectangle<int> copy_rect(0, 0, output_width, dst_height);
|
||||
m_encoding_readback_texture->CopyFromTexture(m_encoding_render_texture.get(), copy_rect, 0, 0,
|
||||
copy_rect);
|
||||
m_encoding_readback_texture->ReadTexels(copy_rect, dst_ptr, dst_stride);
|
||||
}
|
||||
|
||||
void TextureConverter::DecodeYUYVTextureFromMemory(VKTexture* dst_texture, const void* src_ptr,
|
||||
|
@ -734,10 +714,10 @@ VkShaderModule TextureConverter::GetEncodingShader(const EFBCopyParams& params)
|
|||
bool TextureConverter::CreateEncodingRenderPass()
|
||||
{
|
||||
VkAttachmentDescription attachments[] = {
|
||||
{0, ENCODING_TEXTURE_FORMAT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}};
|
||||
{0, Util::GetVkFormatForHostTextureFormat(ENCODING_TEXTURE_FORMAT), VK_SAMPLE_COUNT_1_BIT,
|
||||
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
|
||||
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}};
|
||||
|
||||
VkAttachmentReference color_attachment_references[] = {
|
||||
{0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}};
|
||||
|
@ -769,43 +749,14 @@ bool TextureConverter::CreateEncodingRenderPass()
|
|||
|
||||
bool TextureConverter::CreateEncodingTexture()
|
||||
{
|
||||
m_encoding_render_texture = Texture2D::Create(
|
||||
ENCODING_TEXTURE_WIDTH, ENCODING_TEXTURE_HEIGHT, 1, 1, ENCODING_TEXTURE_FORMAT,
|
||||
VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
||||
if (!m_encoding_render_texture)
|
||||
return false;
|
||||
TextureConfig config(ENCODING_TEXTURE_WIDTH, ENCODING_TEXTURE_HEIGHT, 1, 1,
|
||||
ENCODING_TEXTURE_FORMAT, true);
|
||||
|
||||
VkImageView framebuffer_attachments[] = {m_encoding_render_texture->GetView()};
|
||||
VkFramebufferCreateInfo framebuffer_info = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
nullptr,
|
||||
0,
|
||||
m_encoding_render_pass,
|
||||
static_cast<u32>(ArraySize(framebuffer_attachments)),
|
||||
framebuffer_attachments,
|
||||
m_encoding_render_texture->GetWidth(),
|
||||
m_encoding_render_texture->GetHeight(),
|
||||
m_encoding_render_texture->GetLayers()};
|
||||
m_encoding_render_texture = g_renderer->CreateTexture(config);
|
||||
m_encoding_readback_texture =
|
||||
g_renderer->CreateStagingTexture(StagingTextureType::Readback, config);
|
||||
|
||||
VkResult res = vkCreateFramebuffer(g_vulkan_context->GetDevice(), &framebuffer_info, nullptr,
|
||||
&m_encoding_render_framebuffer);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
LOG_VULKAN_ERROR(res, "vkCreateFramebuffer failed: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TextureConverter::CreateEncodingDownloadTexture()
|
||||
{
|
||||
m_encoding_download_texture =
|
||||
StagingTexture2D::Create(STAGING_BUFFER_TYPE_READBACK, ENCODING_TEXTURE_WIDTH,
|
||||
ENCODING_TEXTURE_HEIGHT, ENCODING_TEXTURE_FORMAT);
|
||||
|
||||
return m_encoding_download_texture && m_encoding_download_texture->Map();
|
||||
return m_encoding_render_texture && m_encoding_readback_texture;
|
||||
}
|
||||
|
||||
bool TextureConverter::CreateDecodingTexture()
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
#include "VideoCommon/TextureDecoder.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
|
||||
class AbstractTexture;
|
||||
class AbstractStagingTexture;
|
||||
|
||||
namespace Vulkan
|
||||
{
|
||||
class StagingTexture2D;
|
||||
|
@ -58,7 +61,7 @@ public:
|
|||
private:
|
||||
static const u32 ENCODING_TEXTURE_WIDTH = EFB_WIDTH * 4;
|
||||
static const u32 ENCODING_TEXTURE_HEIGHT = 1024;
|
||||
static const VkFormat ENCODING_TEXTURE_FORMAT = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
static const AbstractTextureFormat ENCODING_TEXTURE_FORMAT = AbstractTextureFormat::BGRA8;
|
||||
static const size_t NUM_PALETTE_CONVERSION_SHADERS = 3;
|
||||
|
||||
// Maximum size of a texture based on BP registers.
|
||||
|
@ -75,8 +78,6 @@ private:
|
|||
|
||||
bool CreateEncodingRenderPass();
|
||||
bool CreateEncodingTexture();
|
||||
bool CreateEncodingDownloadTexture();
|
||||
|
||||
bool CreateDecodingTexture();
|
||||
|
||||
bool CompileYUYVConversionShaders();
|
||||
|
@ -106,10 +107,9 @@ private:
|
|||
|
||||
// Texture encoding - RGBA8->GX format in memory
|
||||
std::map<EFBCopyParams, VkShaderModule> m_encoding_shaders;
|
||||
std::unique_ptr<AbstractTexture> m_encoding_render_texture;
|
||||
std::unique_ptr<AbstractStagingTexture> m_encoding_readback_texture;
|
||||
VkRenderPass m_encoding_render_pass = VK_NULL_HANDLE;
|
||||
std::unique_ptr<Texture2D> m_encoding_render_texture;
|
||||
VkFramebuffer m_encoding_render_framebuffer = VK_NULL_HANDLE;
|
||||
std::unique_ptr<StagingTexture2D> m_encoding_download_texture;
|
||||
|
||||
// Texture decoding - GX format in memory->RGBA8
|
||||
struct TextureDecodingPipeline
|
||||
|
|
Loading…
Reference in New Issue