mirror of https://github.com/PCSX2/pcsx2.git
GS/DX12: Fix creating display textures mid-frame crashing
This commit is contained in:
parent
d54715a9c3
commit
ddbc143178
|
@ -284,7 +284,7 @@ void Texture::TransitionSubresourceToState(ID3D12GraphicsCommandList* cmdlist, u
|
||||||
cmdlist->ResourceBarrier(1, &barrier);
|
cmdlist->ResourceBarrier(1, &barrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Texture::BeginStreamUpdate(u32 level, u32 x, u32 y, u32 width, u32 height, void** out_data, u32* out_data_pitch)
|
ID3D12GraphicsCommandList* Texture::BeginStreamUpdate(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height, void** out_data, u32* out_data_pitch)
|
||||||
{
|
{
|
||||||
const u32 copy_pitch = Common::AlignUpPow2(width * GetTexelSize(m_format), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
const u32 copy_pitch = Common::AlignUpPow2(width * GetTexelSize(m_format), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||||
const u32 upload_size = copy_pitch * height;
|
const u32 upload_size = copy_pitch * height;
|
||||||
|
@ -297,16 +297,19 @@ bool Texture::BeginStreamUpdate(u32 level, u32 x, u32 y, u32 width, u32 height,
|
||||||
if (!g_d3d12_context->GetTextureStreamBuffer().ReserveMemory(upload_size, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT))
|
if (!g_d3d12_context->GetTextureStreamBuffer().ReserveMemory(upload_size, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT))
|
||||||
{
|
{
|
||||||
Console.Error("Failed to reserve %u bytes for %ux%u upload", upload_size, width, height);
|
Console.Error("Failed to reserve %u bytes for %ux%u upload", upload_size, width, height);
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cmdlist change
|
||||||
|
return g_d3d12_context->GetInitCommandList();
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_data = g_d3d12_context->GetTextureStreamBuffer().GetCurrentHostPointer();
|
*out_data = g_d3d12_context->GetTextureStreamBuffer().GetCurrentHostPointer();
|
||||||
*out_data_pitch = copy_pitch;
|
*out_data_pitch = copy_pitch;
|
||||||
return true;
|
return cmdlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::EndStreamUpdate(u32 level, u32 x, u32 y, u32 width, u32 height)
|
void Texture::EndStreamUpdate(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height)
|
||||||
{
|
{
|
||||||
const u32 copy_pitch = Common::AlignUpPow2(width * GetTexelSize(m_format), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
const u32 copy_pitch = Common::AlignUpPow2(width * GetTexelSize(m_format), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||||
const u32 upload_size = copy_pitch * height;
|
const u32 upload_size = copy_pitch * height;
|
||||||
|
@ -315,10 +318,10 @@ void Texture::EndStreamUpdate(u32 level, u32 x, u32 y, u32 width, u32 height)
|
||||||
const u32 sb_offset = sb.GetCurrentOffset();
|
const u32 sb_offset = sb.GetCurrentOffset();
|
||||||
sb.CommitMemory(upload_size);
|
sb.CommitMemory(upload_size);
|
||||||
|
|
||||||
CopyFromBuffer(level, x, y, width, height, copy_pitch, sb.GetBuffer(), sb_offset);
|
CopyFromBuffer(cmdlist, level, x, y, width, height, copy_pitch, sb.GetBuffer(), sb_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::CopyFromBuffer(u32 level, u32 x, u32 y, u32 width, u32 height, u32 pitch, ID3D12Resource* buffer, u32 buffer_offset)
|
void Texture::CopyFromBuffer(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height, u32 pitch, ID3D12Resource* buffer, u32 buffer_offset)
|
||||||
{
|
{
|
||||||
D3D12_TEXTURE_COPY_LOCATION src;
|
D3D12_TEXTURE_COPY_LOCATION src;
|
||||||
src.pResource = buffer;
|
src.pResource = buffer;
|
||||||
|
@ -337,7 +340,6 @@ void Texture::CopyFromBuffer(u32 level, u32 x, u32 y, u32 width, u32 height, u32
|
||||||
|
|
||||||
const D3D12_BOX src_box{0u, 0u, 0u, width, height, 1u};
|
const D3D12_BOX src_box{0u, 0u, 0u, width, height, 1u};
|
||||||
const D3D12_RESOURCE_STATES old_state = m_state;
|
const D3D12_RESOURCE_STATES old_state = m_state;
|
||||||
ID3D12GraphicsCommandList* cmdlist = g_d3d12_context->GetCommandList();
|
|
||||||
TransitionToState(cmdlist, D3D12_RESOURCE_STATE_COPY_DEST);
|
TransitionToState(cmdlist, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||||
cmdlist->CopyTextureRegion(&dst, x, y, 0, &src, &src_box);
|
cmdlist->CopyTextureRegion(&dst, x, y, 0, &src, &src_box);
|
||||||
TransitionToState(cmdlist, old_state);
|
TransitionToState(cmdlist, old_state);
|
||||||
|
@ -381,7 +383,7 @@ static ID3D12Resource* CreateStagingBuffer(u32 height, const void* data, u32 pit
|
||||||
return resource.get();
|
return resource.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Texture::LoadData(u32 level, u32 x, u32 y, u32 width, u32 height, const void* data, u32 pitch)
|
bool Texture::LoadData(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height, const void* data, u32 pitch)
|
||||||
{
|
{
|
||||||
const u32 texel_size = GetTexelSize(m_format);
|
const u32 texel_size = GetTexelSize(m_format);
|
||||||
const u32 upload_pitch = Common::AlignUpPow2(width * texel_size, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
const u32 upload_pitch = Common::AlignUpPow2(width * texel_size, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||||
|
@ -392,17 +394,17 @@ bool Texture::LoadData(u32 level, u32 x, u32 y, u32 width, u32 height, const voi
|
||||||
if (!staging_buffer)
|
if (!staging_buffer)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CopyFromBuffer(level, x, y, width, height, upload_pitch, staging_buffer, 0);
|
CopyFromBuffer(cmdlist, level, x, y, width, height, upload_pitch, staging_buffer, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* write_ptr;
|
void* write_ptr;
|
||||||
u32 write_pitch;
|
u32 write_pitch;
|
||||||
if (!BeginStreamUpdate(level, x, y, width, height, &write_ptr, &write_pitch))
|
if (!(cmdlist = BeginStreamUpdate(cmdlist, level, x, y, width, height, &write_ptr, &write_pitch)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
StringUtil::StrideMemCpy(write_ptr, write_pitch, data, pitch, std::min(pitch, upload_pitch), height);
|
StringUtil::StrideMemCpy(write_ptr, write_pitch, data, pitch, std::min(pitch, upload_pitch), height);
|
||||||
EndStreamUpdate(level, x, y, width, height);
|
EndStreamUpdate(cmdlist, level, x, y, width, height);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,10 +74,10 @@ namespace D3D12
|
||||||
Texture& operator=(Texture&& texture);
|
Texture& operator=(Texture&& texture);
|
||||||
|
|
||||||
// NOTE: Does not handle compressed formats.
|
// NOTE: Does not handle compressed formats.
|
||||||
bool BeginStreamUpdate(u32 level, u32 x, u32 y, u32 width, u32 height, void** out_data, u32* out_data_pitch);
|
ID3D12GraphicsCommandList* BeginStreamUpdate(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height, void** out_data, u32* out_data_pitch);
|
||||||
void EndStreamUpdate(u32 level, u32 x, u32 y, u32 width, u32 height);
|
void EndStreamUpdate(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height);
|
||||||
bool LoadData(u32 level, u32 x, u32 y, u32 width, u32 height, const void* data, u32 pitch);
|
bool LoadData(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height, const void* data, u32 pitch);
|
||||||
void CopyFromBuffer(u32 level, u32 x, u32 y, u32 width, u32 height, u32 pitch, ID3D12Resource* buffer, u32 buffer_offset);
|
void CopyFromBuffer(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height, u32 pitch, ID3D12Resource* buffer, u32 buffer_offset);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool CreateSRVDescriptor(ID3D12Resource* resource, u32 levels, DXGI_FORMAT format, DescriptorHandle* dh);
|
static bool CreateSRVDescriptor(ID3D12Resource* resource, u32 levels, DXGI_FORMAT format, DescriptorHandle* dh);
|
||||||
|
|
|
@ -85,7 +85,8 @@ bool D3D12HostDisplay::HasRenderSurface() const
|
||||||
return static_cast<bool>(m_swap_chain);
|
return static_cast<bool>(m_swap_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<HostDisplayTexture> D3D12HostDisplay::CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic /* = false */)
|
std::unique_ptr<HostDisplayTexture> D3D12HostDisplay::CreateTexture(
|
||||||
|
u32 width, u32 height, const void* data, u32 data_stride, bool dynamic /* = false */)
|
||||||
{
|
{
|
||||||
D3D12::Texture tex;
|
D3D12::Texture tex;
|
||||||
if (!tex.Create(width, height, 1, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN,
|
if (!tex.Create(width, height, 1, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN,
|
||||||
|
@ -94,17 +95,17 @@ std::unique_ptr<HostDisplayTexture> D3D12HostDisplay::CreateTexture(u32 width, u
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data && !tex.LoadData(0, 0, 0, width, height, data, data_stride))
|
if (data && !tex.LoadData(g_d3d12_context->GetInitCommandList(), 0, 0, 0, width, height, data, data_stride))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return std::make_unique<D3D12HostDisplayTexture>(std::move(tex));
|
return std::make_unique<D3D12HostDisplayTexture>(std::move(tex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12HostDisplay::UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height,
|
void D3D12HostDisplay::UpdateTexture(
|
||||||
const void* texture_data, u32 texture_data_stride)
|
HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, const void* texture_data, u32 texture_data_stride)
|
||||||
{
|
{
|
||||||
static_cast<D3D12HostDisplayTexture*>(texture)->GetTexture().LoadData(0, x, y, width, height, texture_data,
|
static_cast<D3D12HostDisplayTexture*>(texture)->GetTexture().LoadData(
|
||||||
texture_data_stride);
|
g_d3d12_context->GetCommandList(), 0, x, y, width, height, texture_data, texture_data_stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D12HostDisplay::GetHostRefreshRate(float* refresh_rate)
|
bool D3D12HostDisplay::GetHostRefreshRate(float* refresh_rate)
|
||||||
|
|
|
@ -271,7 +271,7 @@ bool ImGui_ImplDX12_CreateFontsTexture()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bd->FontTexture.LoadData(0, 0, 0, width, height, pixels, width * sizeof(u32)))
|
if (!bd->FontTexture.LoadData(g_d3d12_context->GetInitCommandList(), 0, 0, 0, width, height, pixels, width * sizeof(u32)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
io.Fonts->SetTexID((ImTextureID)&bd->FontTexture);
|
io.Fonts->SetTexID((ImTextureID)&bd->FontTexture);
|
||||||
|
|
Loading…
Reference in New Issue