D3D11/StagingTexture: Add auto-resizing staging texture
This commit is contained in:
parent
cfcdc1c336
commit
212fddd195
|
@ -1,6 +1,6 @@
|
||||||
#include "staging_texture.h"
|
#include "staging_texture.h"
|
||||||
#include "../log.h"
|
|
||||||
#include "../assert.h"
|
#include "../assert.h"
|
||||||
|
#include "../log.h"
|
||||||
Log_SetChannel(D3D11);
|
Log_SetChannel(D3D11);
|
||||||
|
|
||||||
namespace D3D11 {
|
namespace D3D11 {
|
||||||
|
@ -58,36 +58,60 @@ void StagingTexture::Unmap(ID3D11DeviceContext* context)
|
||||||
m_map = {};
|
m_map = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void StagingTexture::CopyToTexture(ID3D11DeviceContext* context, u32 src_x, u32 src_y, ID3D11Texture2D* dst_texture,
|
void StagingTexture::CopyToTexture(ID3D11DeviceContext* context, u32 src_x, u32 src_y, ID3D11Resource* dst_texture,
|
||||||
u32 dst_subresource, u32 dst_x, u32 dst_y, u32 width, u32 height)
|
u32 dst_subresource, u32 dst_x, u32 dst_y, u32 width, u32 height)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
DebugAssert((src_x + width) <= m_width && (src_y + height) <= m_height);
|
||||||
Assert((src_x + width) <= m_width && (src_y + height) <= m_height);
|
|
||||||
|
|
||||||
D3D11_TEXTURE2D_DESC dst_desc;
|
|
||||||
dst_texture->GetDesc(&dst_desc);
|
|
||||||
Assert((dst_x + width) <= dst_desc.Width && (dst_y + height) <= dst_desc.Height);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const CD3D11_BOX box(static_cast<LONG>(src_x), static_cast<LONG>(src_y), 0, static_cast<LONG>(src_x + width),
|
const CD3D11_BOX box(static_cast<LONG>(src_x), static_cast<LONG>(src_y), 0, static_cast<LONG>(src_x + width),
|
||||||
static_cast<LONG>(src_y + height), 1);
|
static_cast<LONG>(src_y + height), 1);
|
||||||
context->CopySubresourceRegion(dst_texture, dst_subresource, dst_x, dst_y, 0, m_texture.Get(), 0, &box);
|
context->CopySubresourceRegion(dst_texture, dst_subresource, dst_x, dst_y, 0, m_texture.Get(), 0, &box);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StagingTexture::CopyFromTexture(ID3D11DeviceContext* context, ID3D11Texture2D* src_texture, u32 src_subresource,
|
void StagingTexture::CopyFromTexture(ID3D11DeviceContext* context, ID3D11Resource* src_texture, u32 src_subresource,
|
||||||
u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height)
|
u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
DebugAssert((dst_x + width) <= m_width && (dst_y + height) <= m_height);
|
||||||
Assert((dst_x + width) <= m_width && (dst_y + height) <= m_height);
|
|
||||||
|
|
||||||
D3D11_TEXTURE2D_DESC src_desc;
|
|
||||||
src_texture->GetDesc(&src_desc);
|
|
||||||
Assert((src_x + width) <= src_desc.Width && (src_y + height) <= src_desc.Height);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const CD3D11_BOX box(static_cast<LONG>(src_x), static_cast<LONG>(src_y), 0, static_cast<LONG>(src_x + width),
|
const CD3D11_BOX box(static_cast<LONG>(src_x), static_cast<LONG>(src_y), 0, static_cast<LONG>(src_x + width),
|
||||||
static_cast<LONG>(src_y + height), 1);
|
static_cast<LONG>(src_y + height), 1);
|
||||||
context->CopySubresourceRegion(m_texture.Get(), 0, dst_x, dst_y, 0, src_texture, src_subresource, &box);
|
context->CopySubresourceRegion(m_texture.Get(), 0, dst_x, dst_y, 0, src_texture, src_subresource, &box);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AutoStagingTexture::EnsureSize(ID3D11DeviceContext* context, u32 width, u32 height, DXGI_FORMAT format,
|
||||||
|
bool for_uploading)
|
||||||
|
{
|
||||||
|
if (m_texture && m_width >= width && m_height >= height && m_format == format)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
ID3D11Device* device;
|
||||||
|
context->GetDevice(&device);
|
||||||
|
|
||||||
|
CD3D11_TEXTURE2D_DESC new_desc(format, width, height, 1, 1, 0,
|
||||||
|
for_uploading ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_STAGING,
|
||||||
|
for_uploading ? D3D11_CPU_ACCESS_WRITE : D3D11_CPU_ACCESS_READ, 1, 0, 0);
|
||||||
|
ComPtr<ID3D11Texture2D> new_texture;
|
||||||
|
HRESULT hr = device->CreateTexture2D(&new_desc, nullptr, new_texture.GetAddressOf());
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
Log_ErrorPrintf("Create texture failed: 0x%08X", hr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_texture = std::move(new_texture);
|
||||||
|
m_width = width;
|
||||||
|
m_height = height;
|
||||||
|
m_format = format;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoStagingTexture::CopyFromTexture(ID3D11DeviceContext* context, ID3D11Resource* src_texture, u32 src_subresource,
|
||||||
|
u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height)
|
||||||
|
{
|
||||||
|
if (!EnsureSize(context, width, height, m_format, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
StagingTexture::CopyFromTexture(context, src_texture, src_subresource, src_x, src_y, dst_x, dst_y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace D3D11
|
} // namespace D3D11
|
|
@ -30,9 +30,9 @@ public:
|
||||||
bool Map(ID3D11DeviceContext* context, bool writing);
|
bool Map(ID3D11DeviceContext* context, bool writing);
|
||||||
void Unmap(ID3D11DeviceContext* context);
|
void Unmap(ID3D11DeviceContext* context);
|
||||||
|
|
||||||
void CopyToTexture(ID3D11DeviceContext* context, u32 src_x, u32 src_y, ID3D11Texture2D* dst_texture,
|
void CopyToTexture(ID3D11DeviceContext* context, u32 src_x, u32 src_y, ID3D11Resource* dst_texture,
|
||||||
u32 dst_subresource, u32 dst_x, u32 dst_y, u32 width, u32 height);
|
u32 dst_subresource, u32 dst_x, u32 dst_y, u32 width, u32 height);
|
||||||
void CopyFromTexture(ID3D11DeviceContext* context, ID3D11Texture2D* src_texture, u32 src_subresource, u32 src_x,
|
void CopyFromTexture(ID3D11DeviceContext* context, ID3D11Resource* src_texture, u32 src_subresource, u32 src_x,
|
||||||
u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height);
|
u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -69,6 +69,20 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool ReadPixels(ID3D11DeviceContext* context, u32 x, u32 y, u32 width, u32 height, u32 stride, T* data)
|
||||||
|
{
|
||||||
|
const bool was_mapped = IsMapped();
|
||||||
|
if (!was_mapped && !Map(context, false))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ReadPixels<T>(x, y, width, height, stride, data);
|
||||||
|
if (!was_mapped)
|
||||||
|
Unmap(context);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void WritePixels(u32 x, u32 y, u32 width, u32 height, u32 stride, const T* data)
|
void WritePixels(u32 x, u32 y, u32 width, u32 height, u32 stride, const T* data)
|
||||||
{
|
{
|
||||||
|
@ -89,7 +103,21 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
template<typename T>
|
||||||
|
bool WritePixels(ID3D11DeviceContext* context, u32 x, u32 y, u32 width, u32 height, u32 stride, const T* data)
|
||||||
|
{
|
||||||
|
const bool was_mapped = IsMapped();
|
||||||
|
if (!was_mapped && !Map(context, true))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
WritePixels<T>(context, x, y, width, height, stride, data);
|
||||||
|
if (!was_mapped)
|
||||||
|
Unmap(context);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
ComPtr<ID3D11Texture2D> m_texture;
|
ComPtr<ID3D11Texture2D> m_texture;
|
||||||
u32 m_width;
|
u32 m_width;
|
||||||
u32 m_height;
|
u32 m_height;
|
||||||
|
@ -97,4 +125,31 @@ private:
|
||||||
|
|
||||||
D3D11_MAPPED_SUBRESOURCE m_map = {};
|
D3D11_MAPPED_SUBRESOURCE m_map = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class AutoStagingTexture : public StagingTexture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool EnsureSize(ID3D11DeviceContext* context, u32 width, u32 height, DXGI_FORMAT format, bool for_uploading);
|
||||||
|
|
||||||
|
void CopyFromTexture(ID3D11DeviceContext* context, ID3D11Resource* src_texture, u32 src_subresource, u32 src_x,
|
||||||
|
u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool WritePixels(ID3D11DeviceContext* context, u32 x, u32 y, u32 width, u32 height, u32 stride, const T* data)
|
||||||
|
{
|
||||||
|
if (!EnsureSize(context, width, height, m_format, true))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const bool was_mapped = IsMapped();
|
||||||
|
if (!was_mapped && !Map(context, true))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
WritePixels<T>(context, x, y, width, height, stride, data);
|
||||||
|
|
||||||
|
if (!was_mapped)
|
||||||
|
Unmap(context);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
} // namespace D3D11
|
} // namespace D3D11
|
Loading…
Reference in New Issue