mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-04-27 10:25:41 -04:00
GPU/D3D12: Implement VRAM write replacements
This commit is contained in:
parent
18df8d48e7
commit
9723e617f9
@ -1,4 +1,5 @@
|
|||||||
#include "gpu_hw_d3d12.h"
|
#include "gpu_hw_d3d12.h"
|
||||||
|
#include "common/align.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/d3d11/shader_compiler.h"
|
#include "common/d3d11/shader_compiler.h"
|
||||||
#include "common/d3d12/context.h"
|
#include "common/d3d12/context.h"
|
||||||
@ -420,7 +421,7 @@ bool GPU_HW_D3D12::CompilePipelines()
|
|||||||
m_pgxp_depth_buffer, m_supports_dual_source_blend);
|
m_pgxp_depth_buffer, m_supports_dual_source_blend);
|
||||||
|
|
||||||
ShaderCompileProgressTracker progress("Compiling Pipelines", 2 + (4 * 9 * 2 * 2) + (2 * 4 * 5 * 9 * 2 * 2) + 1 + 2 +
|
ShaderCompileProgressTracker progress("Compiling Pipelines", 2 + (4 * 9 * 2 * 2) + (2 * 4 * 5 * 9 * 2 * 2) + 1 + 2 +
|
||||||
2 + 2 + 1 + 1 + (2 * 3));
|
2 + 2 + 1 + 1 + (2 * 3) + 1);
|
||||||
|
|
||||||
// vertex shaders - [textured]
|
// vertex shaders - [textured]
|
||||||
// fragment shaders - [render_mode][texture_mode][dithering][interlacing]
|
// fragment shaders - [render_mode][texture_mode][dithering][interlacing]
|
||||||
@ -711,6 +712,30 @@ bool GPU_HW_D3D12::CompilePipelines()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy/blit
|
||||||
|
{
|
||||||
|
gpbuilder.Clear();
|
||||||
|
gpbuilder.SetRootSignature(m_single_sampler_root_signature.Get());
|
||||||
|
gpbuilder.SetPrimitiveTopologyType(D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE);
|
||||||
|
gpbuilder.SetVertexShader(fullscreen_quad_vertex_shader.Get());
|
||||||
|
gpbuilder.SetNoCullRasterizationState();
|
||||||
|
gpbuilder.SetNoDepthTestState();
|
||||||
|
gpbuilder.SetNoBlendingState();
|
||||||
|
gpbuilder.SetRenderTarget(0, DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||||
|
|
||||||
|
ComPtr<ID3DBlob> fs = shader_cache.GetPixelShader(shadergen.GenerateCopyFragmentShader());
|
||||||
|
if (!fs)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
gpbuilder.SetPixelShader(fs.Get());
|
||||||
|
|
||||||
|
m_copy_pipeline = gpbuilder.Create(g_d3d12_context->GetDevice(), shader_cache);
|
||||||
|
if (!m_copy_pipeline)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
progress.Increment();
|
||||||
|
}
|
||||||
|
|
||||||
#undef UPDATE_PROGRESS
|
#undef UPDATE_PROGRESS
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -728,6 +753,77 @@ void GPU_HW_D3D12::DestroyPipelines()
|
|||||||
m_display_pipelines = {};
|
m_display_pipelines = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GPU_HW_D3D12::CreateTextureReplacementStreamBuffer()
|
||||||
|
{
|
||||||
|
if (m_texture_replacment_stream_buffer.IsValid())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!m_texture_replacment_stream_buffer.Create(TEXTURE_REPLACEMENT_BUFFER_SIZE))
|
||||||
|
{
|
||||||
|
Log_ErrorPrint("Failed to allocate texture replacement streaming buffer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GPU_HW_D3D12::BlitVRAMReplacementTexture(const TextureReplacementTexture* tex, u32 dst_x, u32 dst_y, u32 width,
|
||||||
|
u32 height)
|
||||||
|
{
|
||||||
|
if (!CreateTextureReplacementStreamBuffer())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (m_vram_write_replacement_texture.GetWidth() < tex->GetWidth() ||
|
||||||
|
m_vram_write_replacement_texture.GetHeight() < tex->GetHeight())
|
||||||
|
{
|
||||||
|
if (!m_vram_write_replacement_texture.Create(tex->GetWidth(), tex->GetHeight(), 1, DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||||
|
DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN,
|
||||||
|
D3D12_RESOURCE_FLAG_NONE))
|
||||||
|
{
|
||||||
|
Log_ErrorPrint("Failed to create VRAM write replacement texture");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const u32 copy_pitch = Common::AlignUpPow2<u32>(tex->GetWidth() * sizeof(u32), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||||
|
const u32 required_size = copy_pitch * tex->GetHeight();
|
||||||
|
if (!m_texture_replacment_stream_buffer.ReserveMemory(required_size, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT))
|
||||||
|
{
|
||||||
|
Log_PerfPrint("Executing command buffer while waiting for texture replacement buffer space");
|
||||||
|
g_d3d12_context->ExecuteCommandList(false);
|
||||||
|
RestoreGraphicsAPIState();
|
||||||
|
if (!m_texture_replacment_stream_buffer.ReserveMemory(required_size, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT))
|
||||||
|
{
|
||||||
|
Log_ErrorPrintf("Failed to allocate %u bytes from texture replacement streaming buffer", required_size);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// buffer -> texture
|
||||||
|
const u32 sb_offset = m_texture_replacment_stream_buffer.GetCurrentOffset();
|
||||||
|
D3D12::Texture::CopyToUploadBuffer(tex->GetPixels(), tex->GetByteStride(), tex->GetHeight(),
|
||||||
|
m_texture_replacment_stream_buffer.GetCurrentHostPointer(), copy_pitch);
|
||||||
|
m_texture_replacment_stream_buffer.CommitMemory(sb_offset);
|
||||||
|
m_vram_write_replacement_texture.CopyFromBuffer(0, 0, tex->GetWidth(), tex->GetHeight(), copy_pitch,
|
||||||
|
m_texture_replacment_stream_buffer.GetBuffer(), sb_offset);
|
||||||
|
m_vram_write_replacement_texture.TransitionToState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||||
|
|
||||||
|
// texture -> vram
|
||||||
|
const float uniforms[] = {
|
||||||
|
0.0f, 0.0f, static_cast<float>(tex->GetWidth()) / static_cast<float>(m_vram_write_replacement_texture.GetWidth()),
|
||||||
|
static_cast<float>(tex->GetHeight()) / static_cast<float>(m_vram_write_replacement_texture.GetHeight())};
|
||||||
|
ID3D12GraphicsCommandList* cmdlist = g_d3d12_context->GetCommandList();
|
||||||
|
cmdlist->SetGraphicsRootSignature(m_single_sampler_root_signature.Get());
|
||||||
|
cmdlist->SetGraphicsRoot32BitConstants(0, sizeof(uniforms) / sizeof(u32), uniforms, 0);
|
||||||
|
cmdlist->SetGraphicsRootDescriptorTable(1, m_vram_write_replacement_texture.GetSRVDescriptor());
|
||||||
|
cmdlist->SetGraphicsRootDescriptorTable(2, m_linear_sampler.gpu_handle);
|
||||||
|
cmdlist->SetPipelineState(m_copy_pipeline.Get());
|
||||||
|
D3D12::SetViewportAndScissor(cmdlist, dst_x, dst_y, width, height);
|
||||||
|
cmdlist->DrawInstanced(3, 1, 0, 0);
|
||||||
|
RestoreGraphicsAPIState();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void GPU_HW_D3D12::DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices)
|
void GPU_HW_D3D12::DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices)
|
||||||
{
|
{
|
||||||
ID3D12GraphicsCommandList* cmdlist = g_d3d12_context->GetCommandList();
|
ID3D12GraphicsCommandList* cmdlist = g_d3d12_context->GetCommandList();
|
||||||
@ -936,6 +1032,16 @@ void GPU_HW_D3D12::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* d
|
|||||||
const Common::Rectangle<u32> bounds = GetVRAMTransferBounds(x, y, width, height);
|
const Common::Rectangle<u32> bounds = GetVRAMTransferBounds(x, y, width, height);
|
||||||
GPU_HW::UpdateVRAM(bounds.left, bounds.top, bounds.GetWidth(), bounds.GetHeight(), data, set_mask, check_mask);
|
GPU_HW::UpdateVRAM(bounds.left, bounds.top, bounds.GetWidth(), bounds.GetHeight(), data, set_mask, check_mask);
|
||||||
|
|
||||||
|
if (!check_mask)
|
||||||
|
{
|
||||||
|
const TextureReplacementTexture* rtex = g_texture_replacements.GetVRAMWriteReplacement(width, height, data);
|
||||||
|
if (rtex && BlitVRAMReplacementTexture(rtex, x * m_resolution_scale, y * m_resolution_scale,
|
||||||
|
width * m_resolution_scale, height * m_resolution_scale))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const u32 data_size = width * height * sizeof(u16);
|
const u32 data_size = width * height * sizeof(u16);
|
||||||
const u32 alignment = D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT; // ???
|
const u32 alignment = D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT; // ???
|
||||||
if (!m_texture_stream_buffer.ReserveMemory(data_size, alignment))
|
if (!m_texture_stream_buffer.ReserveMemory(data_size, alignment))
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "common/dimensional_array.h"
|
|
||||||
#include "common/d3d12/staging_texture.h"
|
#include "common/d3d12/staging_texture.h"
|
||||||
#include "common/d3d12/stream_buffer.h"
|
#include "common/d3d12/stream_buffer.h"
|
||||||
#include "common/d3d12/texture.h"
|
#include "common/d3d12/texture.h"
|
||||||
|
#include "common/dimensional_array.h"
|
||||||
#include "gpu_hw.h"
|
#include "gpu_hw.h"
|
||||||
|
#include "texture_replacements.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
@ -46,6 +47,7 @@ private:
|
|||||||
enum : u32
|
enum : u32
|
||||||
{
|
{
|
||||||
MAX_PUSH_CONSTANTS_SIZE = 64,
|
MAX_PUSH_CONSTANTS_SIZE = 64,
|
||||||
|
TEXTURE_REPLACEMENT_BUFFER_SIZE = 64 * 1024 * 1024,
|
||||||
};
|
};
|
||||||
void SetCapabilities();
|
void SetCapabilities();
|
||||||
void DestroyResources();
|
void DestroyResources();
|
||||||
@ -64,6 +66,9 @@ private:
|
|||||||
bool CompilePipelines();
|
bool CompilePipelines();
|
||||||
void DestroyPipelines();
|
void DestroyPipelines();
|
||||||
|
|
||||||
|
bool CreateTextureReplacementStreamBuffer();
|
||||||
|
bool BlitVRAMReplacementTexture(const TextureReplacementTexture* tex, u32 dst_x, u32 dst_y, u32 width, u32 height);
|
||||||
|
|
||||||
ComPtr<ID3D12RootSignature> m_batch_root_signature;
|
ComPtr<ID3D12RootSignature> m_batch_root_signature;
|
||||||
ComPtr<ID3D12RootSignature> m_single_sampler_root_signature;
|
ComPtr<ID3D12RootSignature> m_single_sampler_root_signature;
|
||||||
|
|
||||||
@ -99,4 +104,8 @@ private:
|
|||||||
|
|
||||||
// [depth_24][interlace_mode]
|
// [depth_24][interlace_mode]
|
||||||
DimensionalArray<ComPtr<ID3D12PipelineState>, 3, 2> m_display_pipelines;
|
DimensionalArray<ComPtr<ID3D12PipelineState>, 3, 2> m_display_pipelines;
|
||||||
|
|
||||||
|
ComPtr<ID3D12PipelineState> m_copy_pipeline;
|
||||||
|
D3D12::Texture m_vram_write_replacement_texture;
|
||||||
|
D3D12::StreamBuffer m_texture_replacment_stream_buffer;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user