GPU: Support replacing VRAM writes with new textures

This commit is contained in:
Connor McLaughlin
2020-12-25 18:02:38 +10:00
parent a66f14b5c3
commit 8db961042a
15 changed files with 680 additions and 26 deletions

View File

@ -616,6 +616,52 @@ void GPU_HW_D3D11::DrawUtilityShader(ID3D11PixelShader* shader, const void* unif
m_context->Draw(3, 0);
}
bool GPU_HW_D3D11::BlitVRAMReplacementTexture(const TextureReplacementTexture* tex, u32 dst_x, u32 dst_y, u32 width,
u32 height)
{
if (m_vram_replacement_texture.GetWidth() < tex->GetWidth() ||
m_vram_replacement_texture.GetHeight() < tex->GetHeight())
{
if (!m_vram_replacement_texture.Create(m_device.Get(), tex->GetWidth(), tex->GetHeight(), 1,
DXGI_FORMAT_R8G8B8A8_UNORM, D3D11_BIND_SHADER_RESOURCE, tex->GetPixels(),
tex->GetByteStride(), true))
{
return false;
}
}
else
{
D3D11_MAPPED_SUBRESOURCE sr;
HRESULT hr = m_context->Map(m_vram_replacement_texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &sr);
if (FAILED(hr))
{
Log_ErrorPrintf("Texture map failed: %08X", hr);
return false;
}
const u32 copy_size = std::min(tex->GetByteStride(), sr.RowPitch);
const u8* src_ptr = reinterpret_cast<const u8*>(tex->GetPixels());
u8* dst_ptr = static_cast<u8*>(sr.pData);
for (u32 i = 0; i < tex->GetHeight(); i++)
{
std::memcpy(dst_ptr, src_ptr, copy_size);
src_ptr += tex->GetByteStride();
dst_ptr += sr.RowPitch;
}
m_context->Unmap(m_vram_replacement_texture, 0);
}
m_context->OMSetDepthStencilState(m_depth_disabled_state.Get(), 0);
m_context->PSSetShaderResources(0, 1, m_vram_replacement_texture.GetD3DSRVArray());
SetViewportAndScissor(dst_x, dst_y, width, height);
const float uniforms[] = {0.0f, 0.0f, 1.0f, 1.0f};
DrawUtilityShader(m_copy_pixel_shader.Get(), uniforms, sizeof(uniforms));
RestoreGraphicsAPIState();
return true;
}
void GPU_HW_D3D11::DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices)
{
const bool textured = (m_batch.texture_mode != GPUTextureMode::Disabled);
@ -803,6 +849,16 @@ void GPU_HW_D3D11::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* d
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);
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 num_pixels = width * height;
const auto map_result = m_texture_stream_buffer.Map(m_context.Get(), sizeof(u16), num_pixels * sizeof(u16));
std::memcpy(map_result.pointer, data, num_pixels * sizeof(u16));