mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-30 01:29:42 -06:00
VideoBackends: Support updated texture encoding shader generators
This commit is contained in:
@ -88,9 +88,9 @@ void TextureCache::ConvertTexture(TCacheEntryBase* base_entry, TCacheEntryBase*
|
||||
m_texture_converter->ConvertTexture(entry, unconverted, m_render_pass, palette, format);
|
||||
}
|
||||
|
||||
void TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row,
|
||||
u32 num_blocks_y, u32 memory_stride, bool is_depth_copy,
|
||||
const EFBRectangle& src_rect, bool is_intensity, bool scale_by_half)
|
||||
void TextureCache::CopyEFB(u8* dst, const EFBCopyFormat& format, u32 native_width,
|
||||
u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride,
|
||||
bool is_depth_copy, const EFBRectangle& src_rect, bool scale_by_half)
|
||||
{
|
||||
// Flush EFB pokes first, as they're expected to be included.
|
||||
FramebufferManager::GetInstance()->FlushEFBPokes();
|
||||
@ -120,7 +120,7 @@ void TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_
|
||||
|
||||
m_texture_converter->EncodeTextureToMemory(src_texture->GetView(), dst, format, native_width,
|
||||
bytes_per_row, num_blocks_y, memory_stride,
|
||||
is_depth_copy, is_intensity, scale_by_half, src_rect);
|
||||
is_depth_copy, src_rect, scale_by_half);
|
||||
|
||||
// Transition back to original state
|
||||
src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), original_layout);
|
||||
|
@ -59,9 +59,9 @@ public:
|
||||
void ConvertTexture(TCacheEntryBase* base_entry, TCacheEntryBase* base_unconverted, void* palette,
|
||||
TlutFormat format) override;
|
||||
|
||||
void CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
||||
u32 memory_stride, bool is_depth_copy, const EFBRectangle& src_rect,
|
||||
bool is_intensity, bool scale_by_half) override;
|
||||
void CopyEFB(u8* dst, const EFBCopyFormat& format, u32 native_width, u32 bytes_per_row,
|
||||
u32 num_blocks_y, u32 memory_stride, bool is_depth_copy,
|
||||
const EFBRectangle& src_rect, bool scale_by_half) override;
|
||||
|
||||
void CopyRectangleFromTexture(TCacheEntry* dst_texture, const MathUtil::Rectangle<int>& dst_rect,
|
||||
Texture2D* src_texture, const MathUtil::Rectangle<int>& src_rect);
|
||||
|
@ -57,11 +57,8 @@ TextureConverter::~TextureConverter()
|
||||
if (m_encoding_render_framebuffer != VK_NULL_HANDLE)
|
||||
vkDestroyFramebuffer(g_vulkan_context->GetDevice(), m_encoding_render_framebuffer, nullptr);
|
||||
|
||||
for (VkShaderModule shader : m_encoding_shaders)
|
||||
{
|
||||
if (shader != VK_NULL_HANDLE)
|
||||
vkDestroyShaderModule(g_vulkan_context->GetDevice(), shader, nullptr);
|
||||
}
|
||||
for (auto& it : m_encoding_shaders)
|
||||
vkDestroyShaderModule(g_vulkan_context->GetDevice(), it.second, nullptr);
|
||||
|
||||
for (const auto& it : m_decoding_pipelines)
|
||||
{
|
||||
@ -89,12 +86,6 @@ bool TextureConverter::Initialize()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CompileEncodingShaders())
|
||||
{
|
||||
PanicAlert("Failed to compile texture encoding shaders");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CreateEncodingRenderPass())
|
||||
{
|
||||
PanicAlert("Failed to create encode render pass");
|
||||
@ -221,15 +212,17 @@ void TextureConverter::ConvertTexture(TextureCache::TCacheEntry* dst_entry,
|
||||
draw.EndRenderPass();
|
||||
}
|
||||
|
||||
void TextureConverter::EncodeTextureToMemory(VkImageView src_texture, u8* dest_ptr, u32 format,
|
||||
u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
||||
u32 memory_stride, bool is_depth_copy,
|
||||
bool is_intensity, int scale_by_half,
|
||||
const EFBRectangle& src_rect)
|
||||
void TextureConverter::EncodeTextureToMemory(VkImageView src_texture, u8* dest_ptr,
|
||||
const EFBCopyFormat& format, u32 native_width,
|
||||
u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride,
|
||||
bool is_depth_copy, const EFBRectangle& src_rect,
|
||||
bool scale_by_half)
|
||||
{
|
||||
if (m_encoding_shaders[format] == VK_NULL_HANDLE)
|
||||
VkShaderModule shader = GetEncodingShader(format);
|
||||
if (shader == VK_NULL_HANDLE)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Missing encoding fragment shader for format %u", format);
|
||||
ERROR_LOG(VIDEO, "Missing encoding fragment shader for format %u->%u", format.efb_format,
|
||||
static_cast<u32>(format.copy_format));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -242,7 +235,7 @@ void TextureConverter::EncodeTextureToMemory(VkImageView src_texture, u8* dest_p
|
||||
UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_PUSH_CONSTANT),
|
||||
m_encoding_render_pass, g_object_cache->GetScreenQuadVertexShader(),
|
||||
VK_NULL_HANDLE, m_encoding_shaders[format]);
|
||||
VK_NULL_HANDLE, shader);
|
||||
|
||||
// Uniform - int4 of left,top,native_width,scale
|
||||
s32 position_uniform[4] = {src_rect.left, src_rect.top, static_cast<s32>(native_width),
|
||||
@ -681,24 +674,25 @@ bool TextureConverter::CompilePaletteConversionShaders()
|
||||
m_palette_conversion_shaders[GX_TL_RGB5A3] != VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
bool TextureConverter::CompileEncodingShaders()
|
||||
VkShaderModule TextureConverter::CompileEncodingShader(const EFBCopyFormat& format)
|
||||
{
|
||||
// Texture encoding shaders
|
||||
static const u32 texture_encoding_shader_formats[] = {
|
||||
GX_TF_I4, GX_TF_I8, GX_TF_IA4, GX_TF_IA8, GX_TF_RGB565, GX_TF_RGB5A3, GX_TF_RGBA8,
|
||||
GX_CTF_R4, GX_CTF_RA4, GX_CTF_RA8, GX_CTF_A8, GX_CTF_R8, GX_CTF_G8, GX_CTF_B8,
|
||||
GX_CTF_RG8, GX_CTF_GB8, GX_CTF_Z8H, GX_TF_Z8, GX_CTF_Z16R, GX_TF_Z16, GX_TF_Z24X8,
|
||||
GX_CTF_Z4, GX_CTF_Z8M, GX_CTF_Z8L, GX_CTF_Z16L};
|
||||
for (u32 format : texture_encoding_shader_formats)
|
||||
{
|
||||
const char* shader_source =
|
||||
TextureConversionShader::GenerateEncodingShader(format, APIType::Vulkan);
|
||||
m_encoding_shaders[format] = Util::CompileAndCreateFragmentShader(shader_source);
|
||||
if (m_encoding_shaders[format] == VK_NULL_HANDLE)
|
||||
return false;
|
||||
}
|
||||
const char* shader = TextureConversionShader::GenerateEncodingShader(format, APIType::Vulkan);
|
||||
VkShaderModule module = Util::CompileAndCreateFragmentShader(shader);
|
||||
if (module == VK_NULL_HANDLE)
|
||||
PanicAlert("Failed to compile texture encoding shader.");
|
||||
|
||||
return true;
|
||||
return module;
|
||||
}
|
||||
|
||||
VkShaderModule TextureConverter::GetEncodingShader(const EFBCopyFormat& format)
|
||||
{
|
||||
auto iter = m_encoding_shaders.find(format);
|
||||
if (iter != m_encoding_shaders.end())
|
||||
return iter->second;
|
||||
|
||||
VkShaderModule shader = CompileEncodingShader(format);
|
||||
m_encoding_shaders.emplace(format, shader);
|
||||
return shader;
|
||||
}
|
||||
|
||||
bool TextureConverter::CreateEncodingRenderPass()
|
||||
|
@ -35,10 +35,10 @@ public:
|
||||
|
||||
// Uses an encoding shader to copy src_texture to dest_ptr.
|
||||
// NOTE: Executes the current command buffer.
|
||||
void EncodeTextureToMemory(VkImageView src_texture, u8* dest_ptr, u32 format, u32 native_width,
|
||||
u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride,
|
||||
bool is_depth_copy, bool is_intensity, int scale_by_half,
|
||||
const EFBRectangle& source);
|
||||
void EncodeTextureToMemory(VkImageView src_texture, u8* dest_ptr, const EFBCopyFormat& format,
|
||||
u32 native_width, u32 bytes_per_row, u32 num_blocks_y,
|
||||
u32 memory_stride, bool is_depth_copy, const EFBRectangle& src_rect,
|
||||
bool scale_by_half);
|
||||
|
||||
// Encodes texture to guest memory in XFB (YUYV) format.
|
||||
void EncodeTextureToMemoryYUYV(void* dst_ptr, u32 dst_width, u32 dst_stride, u32 dst_height,
|
||||
@ -55,7 +55,6 @@ public:
|
||||
TlutFormat palette_format);
|
||||
|
||||
private:
|
||||
static const u32 NUM_TEXTURE_ENCODING_SHADERS = 64;
|
||||
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;
|
||||
@ -70,7 +69,9 @@ private:
|
||||
|
||||
bool CompilePaletteConversionShaders();
|
||||
|
||||
bool CompileEncodingShaders();
|
||||
VkShaderModule CompileEncodingShader(const EFBCopyFormat& format);
|
||||
VkShaderModule GetEncodingShader(const EFBCopyFormat& format);
|
||||
|
||||
bool CreateEncodingRenderPass();
|
||||
bool CreateEncodingTexture();
|
||||
bool CreateEncodingDownloadTexture();
|
||||
@ -102,7 +103,7 @@ private:
|
||||
std::array<VkShaderModule, NUM_PALETTE_CONVERSION_SHADERS> m_palette_conversion_shaders = {};
|
||||
|
||||
// Texture encoding - RGBA8->GX format in memory
|
||||
std::array<VkShaderModule, NUM_TEXTURE_ENCODING_SHADERS> m_encoding_shaders = {};
|
||||
std::map<EFBCopyFormat, VkShaderModule> m_encoding_shaders;
|
||||
VkRenderPass m_encoding_render_pass = VK_NULL_HANDLE;
|
||||
std::unique_ptr<Texture2D> m_encoding_render_texture;
|
||||
VkFramebuffer m_encoding_render_framebuffer = VK_NULL_HANDLE;
|
||||
|
Reference in New Issue
Block a user