summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp')
-rw-r--r--Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp95
1 files changed, 29 insertions, 66 deletions
diff --git a/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp b/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp
index 4fcce4ef03..d97cd2bc35 100644
--- a/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp
+++ b/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp
@@ -4,17 +4,21 @@
#include "VideoBackends/D3D/PSTextureEncoder.h"
+#include "Common/Assert.h"
#include "Common/Logging/Log.h"
#include "Core/HW/Memmap.h"
#include "VideoBackends/D3D/D3DBase.h"
#include "VideoBackends/D3D/D3DShader.h"
#include "VideoBackends/D3D/D3DState.h"
#include "VideoBackends/D3D/D3DUtil.h"
+#include "VideoBackends/D3D/DXTexture.h"
#include "VideoBackends/D3D/FramebufferManager.h"
#include "VideoBackends/D3D/Render.h"
#include "VideoBackends/D3D/TextureCache.h"
#include "VideoBackends/D3D/VertexShaderCache.h"
+#include "VideoCommon/AbstractStagingTexture.h"
+#include "VideoCommon/AbstractTexture.h"
#include "VideoCommon/TextureConversionShader.h"
#include "VideoCommon/VideoCommon.h"
@@ -31,76 +35,41 @@ struct EFBEncodeParams
};
PSTextureEncoder::PSTextureEncoder()
- : m_ready(false), m_out(nullptr), m_outRTV(nullptr), m_outStage(nullptr),
- m_encodeParams(nullptr)
{
}
+PSTextureEncoder::~PSTextureEncoder() = default;
+
void PSTextureEncoder::Init()
{
- m_ready = false;
-
- HRESULT hr;
-
- // Create output texture RGBA format
- // TODO: This Texture is overly large and parts of it are unused
- // EFB2RAM copies use max (EFB_WIDTH * 4) by (EFB_HEIGHT / 4)
- // XFB2RAM copies use max (EFB_WIDTH / 2) by (EFB_HEIGHT)
- D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_B8G8R8A8_UNORM, EFB_WIDTH * 4, 1024,
- 1, 1, D3D11_BIND_RENDER_TARGET);
- hr = D3D::device->CreateTexture2D(&t2dd, nullptr, &m_out);
- CHECK(SUCCEEDED(hr), "create efb encode output texture");
- D3D::SetDebugObjectName(m_out, "efb encoder output texture");
-
- // Create output render target view
- D3D11_RENDER_TARGET_VIEW_DESC rtvd = CD3D11_RENDER_TARGET_VIEW_DESC(
- m_out, D3D11_RTV_DIMENSION_TEXTURE2D, DXGI_FORMAT_B8G8R8A8_UNORM);
- hr = D3D::device->CreateRenderTargetView(m_out, &rtvd, &m_outRTV);
- CHECK(SUCCEEDED(hr), "create efb encode output render target view");
- D3D::SetDebugObjectName(m_outRTV, "efb encoder output rtv");
-
- // Create output staging buffer
- t2dd.Usage = D3D11_USAGE_STAGING;
- t2dd.BindFlags = 0;
- t2dd.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
- hr = D3D::device->CreateTexture2D(&t2dd, nullptr, &m_outStage);
- CHECK(SUCCEEDED(hr), "create efb encode output staging buffer");
- D3D::SetDebugObjectName(m_outStage, "efb encoder output staging buffer");
+ // TODO: Move this to a constant somewhere in common.
+ TextureConfig encoding_texture_config(EFB_WIDTH * 4, 1024, 1, 1, AbstractTextureFormat::BGRA8,
+ true);
+ m_encoding_render_texture = g_renderer->CreateTexture(encoding_texture_config);
+ m_encoding_readback_texture =
+ g_renderer->CreateStagingTexture(StagingTextureType::Readback, encoding_texture_config);
+ _assert_(m_encoding_render_texture && m_encoding_readback_texture);
// Create constant buffer for uploading data to shaders
D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(EFBEncodeParams), D3D11_BIND_CONSTANT_BUFFER);
- hr = D3D::device->CreateBuffer(&bd, nullptr, &m_encodeParams);
+ HRESULT hr = D3D::device->CreateBuffer(&bd, nullptr, &m_encode_params);
CHECK(SUCCEEDED(hr), "create efb encode params buffer");
- D3D::SetDebugObjectName(m_encodeParams, "efb encoder params buffer");
-
- m_ready = true;
+ D3D::SetDebugObjectName(m_encode_params, "efb encoder params buffer");
}
void PSTextureEncoder::Shutdown()
{
- m_ready = false;
-
for (auto& it : m_encoding_shaders)
- {
SAFE_RELEASE(it.second);
- }
m_encoding_shaders.clear();
- SAFE_RELEASE(m_encodeParams);
- SAFE_RELEASE(m_outStage);
- SAFE_RELEASE(m_outRTV);
- SAFE_RELEASE(m_out);
+ SAFE_RELEASE(m_encode_params);
}
void PSTextureEncoder::Encode(u8* dst, const EFBCopyParams& params, u32 native_width,
u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride,
const EFBRectangle& src_rect, bool scale_by_half)
{
- if (!m_ready) // Make sure we initialized OK
- return;
-
- HRESULT hr;
-
// Resolve MSAA targets before copying.
// FIXME: Instead of resolving EFB, it would be better to pick out a
// single sample from each pixel. The game may break if it isn't
@@ -122,7 +91,10 @@ void PSTextureEncoder::Encode(u8* dst, const EFBCopyParams& params, u32 native_w
constexpr EFBRectangle fullSrcRect(0, 0, EFB_WIDTH, EFB_HEIGHT);
TargetRectangle targetRect = g_renderer->ConvertEFBRectangle(fullSrcRect);
- D3D::context->OMSetRenderTargets(1, &m_outRTV, nullptr);
+ D3D::context->OMSetRenderTargets(
+ 1,
+ &static_cast<DXTexture*>(m_encoding_render_texture.get())->GetRawTexIdentifier()->GetRTV(),
+ nullptr);
EFBEncodeParams encode_params;
encode_params.SrcLeft = src_rect.left;
@@ -130,8 +102,8 @@ void PSTextureEncoder::Encode(u8* dst, const EFBCopyParams& params, u32 native_w
encode_params.DestWidth = native_width;
encode_params.ScaleFactor = scale_by_half ? 2 : 1;
encode_params.y_scale = params.y_scale;
- D3D::context->UpdateSubresource(m_encodeParams, 0, nullptr, &encode_params, 0, 0);
- D3D::stateman->SetPixelConstants(m_encodeParams);
+ D3D::context->UpdateSubresource(m_encode_params, 0, nullptr, &encode_params, 0, 0);
+ D3D::stateman->SetPixelConstants(m_encode_params);
// We also linear filtering for both box filtering and downsampling higher resolutions to 1x
// TODO: This only produces perfect downsampling for 2x IR, other resolutions will need more
@@ -148,24 +120,15 @@ void PSTextureEncoder::Encode(u8* dst, const EFBCopyParams& params, u32 native_w
VertexShaderCache::GetSimpleInputLayout());
// Copy to staging buffer
- D3D11_BOX srcBox = CD3D11_BOX(0, 0, 0, words_per_row, num_blocks_y, 1);
- D3D::context->CopySubresourceRegion(m_outStage, 0, 0, 0, 0, m_out, 0, &srcBox);
-
- // Transfer staging buffer to GameCube/Wii RAM
- D3D11_MAPPED_SUBRESOURCE map = {0};
- hr = D3D::context->Map(m_outStage, 0, D3D11_MAP_READ, 0, &map);
- CHECK(SUCCEEDED(hr), "map staging buffer (0x%x)", hr);
-
- u8* src = (u8*)map.pData;
- u32 readStride = std::min(bytes_per_row, map.RowPitch);
- for (unsigned int y = 0; y < num_blocks_y; ++y)
+ MathUtil::Rectangle<int> copy_rect(0, 0, words_per_row, num_blocks_y);
+ m_encoding_readback_texture->CopyFromTexture(m_encoding_render_texture.get(), copy_rect, 0, 0,
+ copy_rect);
+ m_encoding_readback_texture->Flush();
+ if (m_encoding_readback_texture->Map())
{
- memcpy(dst, src, readStride);
- dst += memory_stride;
- src += map.RowPitch;
+ m_encoding_readback_texture->ReadTexels(copy_rect, dst, memory_stride);
+ m_encoding_readback_texture->Unmap();
}
-
- D3D::context->Unmap(m_outStage, 0);
}
// Restore API