mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2025-12-23 16:32:22 +00:00
Refactor resource destruction to fix data races.
This commit is contained in:
parent
f96b2ad16c
commit
cd99cf2c04
1 changed files with 64 additions and 91 deletions
|
|
@ -313,15 +313,72 @@ struct UploadAllocator
|
||||||
|
|
||||||
static UploadAllocator g_uploadAllocators[NUM_FRAMES];
|
static UploadAllocator g_uploadAllocators[NUM_FRAMES];
|
||||||
|
|
||||||
static Mutex g_tempMutex;
|
static std::vector<GuestResource*> g_tempResources[NUM_FRAMES];
|
||||||
static std::vector<std::unique_ptr<RenderTexture>> g_tempTextures[NUM_FRAMES];
|
|
||||||
static std::vector<std::unique_ptr<RenderBuffer>> g_tempBuffers[NUM_FRAMES];
|
static std::vector<std::unique_ptr<RenderBuffer>> g_tempBuffers[NUM_FRAMES];
|
||||||
static std::vector<uint32_t> g_tempDescriptorIndices[NUM_FRAMES];
|
|
||||||
static std::vector<std::unique_ptr<RenderFramebuffer>> g_tempFramebuffers[NUM_FRAMES];
|
|
||||||
|
|
||||||
static RenderBufferReference g_quadIndexBuffer;
|
static RenderBufferReference g_quadIndexBuffer;
|
||||||
static uint32_t g_quadCount;
|
static uint32_t g_quadCount;
|
||||||
|
|
||||||
|
static void DestructTempResources()
|
||||||
|
{
|
||||||
|
for (auto resource : g_tempResources[g_frame])
|
||||||
|
{
|
||||||
|
switch (resource->type)
|
||||||
|
{
|
||||||
|
case ResourceType::Texture:
|
||||||
|
case ResourceType::VolumeTexture:
|
||||||
|
{
|
||||||
|
const auto texture = reinterpret_cast<GuestTexture*>(resource);
|
||||||
|
|
||||||
|
if (texture->mappedMemory != nullptr)
|
||||||
|
g_userHeap.Free(texture->mappedMemory);
|
||||||
|
|
||||||
|
g_textureDescriptorAllocator.free(texture->descriptorIndex);
|
||||||
|
|
||||||
|
texture->~GuestTexture();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ResourceType::VertexBuffer:
|
||||||
|
case ResourceType::IndexBuffer:
|
||||||
|
{
|
||||||
|
const auto buffer = reinterpret_cast<GuestBuffer*>(resource);
|
||||||
|
|
||||||
|
if (buffer->mappedMemory != nullptr)
|
||||||
|
g_userHeap.Free(buffer->mappedMemory);
|
||||||
|
|
||||||
|
buffer->~GuestBuffer();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ResourceType::RenderTarget:
|
||||||
|
case ResourceType::DepthStencil:
|
||||||
|
{
|
||||||
|
const auto surface = reinterpret_cast<GuestSurface*>(resource);
|
||||||
|
|
||||||
|
if (surface->descriptorIndex != NULL)
|
||||||
|
g_textureDescriptorAllocator.free(surface->descriptorIndex);
|
||||||
|
|
||||||
|
surface->~GuestSurface();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ResourceType::VertexDeclaration:
|
||||||
|
reinterpret_cast<GuestVertexDeclaration*>(resource)->~GuestVertexDeclaration();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ResourceType::VertexShader:
|
||||||
|
case ResourceType::PixelShader:
|
||||||
|
reinterpret_cast<GuestShader*>(resource)->~GuestShader();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_userHeap.Free(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_tempResources[g_frame].clear();
|
||||||
|
g_tempBuffers[g_frame].clear();
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t g_mainThreadId;
|
static uint32_t g_mainThreadId;
|
||||||
|
|
||||||
static ankerl::unordered_dense::map<RenderTexture*, RenderTextureLayout> g_barrierMap;
|
static ankerl::unordered_dense::map<RenderTexture*, RenderTextureLayout> g_barrierMap;
|
||||||
|
|
@ -1105,78 +1162,7 @@ static void DestructResource(GuestResource* resource)
|
||||||
static void ProcDestructResource(const RenderCommand& cmd)
|
static void ProcDestructResource(const RenderCommand& cmd)
|
||||||
{
|
{
|
||||||
const auto& args = cmd.destructResource;
|
const auto& args = cmd.destructResource;
|
||||||
|
g_tempResources[g_frame].push_back(args.resource);
|
||||||
switch (args.resource->type)
|
|
||||||
{
|
|
||||||
case ResourceType::Texture:
|
|
||||||
case ResourceType::VolumeTexture:
|
|
||||||
{
|
|
||||||
const auto texture = reinterpret_cast<GuestTexture*>(args.resource);
|
|
||||||
|
|
||||||
if (texture->mappedMemory != nullptr)
|
|
||||||
g_userHeap.Free(texture->mappedMemory);
|
|
||||||
|
|
||||||
{
|
|
||||||
std::lock_guard lock(g_tempMutex);
|
|
||||||
g_tempTextures[g_frame].emplace_back(std::move(texture->textureHolder));
|
|
||||||
g_tempDescriptorIndices[g_frame].push_back(texture->descriptorIndex);
|
|
||||||
|
|
||||||
if (texture->framebuffer != nullptr)
|
|
||||||
g_tempFramebuffers[g_frame].emplace_back(std::move(texture->framebuffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
texture->~GuestTexture();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ResourceType::VertexBuffer:
|
|
||||||
case ResourceType::IndexBuffer:
|
|
||||||
{
|
|
||||||
const auto buffer = reinterpret_cast<GuestBuffer*>(args.resource);
|
|
||||||
|
|
||||||
if (buffer->mappedMemory != nullptr)
|
|
||||||
g_userHeap.Free(buffer->mappedMemory);
|
|
||||||
|
|
||||||
{
|
|
||||||
std::lock_guard lock(g_tempMutex);
|
|
||||||
g_tempBuffers[g_frame].emplace_back(std::move(buffer->buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer->~GuestBuffer();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ResourceType::RenderTarget:
|
|
||||||
case ResourceType::DepthStencil:
|
|
||||||
{
|
|
||||||
const auto surface = reinterpret_cast<GuestSurface*>(args.resource);
|
|
||||||
|
|
||||||
{
|
|
||||||
std::lock_guard lock(g_tempMutex);
|
|
||||||
g_tempTextures[g_frame].emplace_back(std::move(surface->textureHolder));
|
|
||||||
|
|
||||||
if (surface->descriptorIndex != NULL)
|
|
||||||
g_tempDescriptorIndices[g_frame].push_back(surface->descriptorIndex);
|
|
||||||
|
|
||||||
for (auto& [texture, framebuffer] : surface->framebuffers)
|
|
||||||
g_tempFramebuffers[g_frame].emplace_back(std::move(framebuffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
surface->~GuestSurface();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ResourceType::VertexDeclaration:
|
|
||||||
reinterpret_cast<GuestVertexDeclaration*>(args.resource)->~GuestVertexDeclaration();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ResourceType::VertexShader:
|
|
||||||
case ResourceType::PixelShader:
|
|
||||||
reinterpret_cast<GuestShader*>(args.resource)->~GuestShader();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_userHeap.Free(args.resource);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr uint32_t PITCH_ALIGNMENT = 0x100;
|
static constexpr uint32_t PITCH_ALIGNMENT = 0x100;
|
||||||
|
|
@ -1364,7 +1350,6 @@ static uint32_t HashVertexDeclaration(uint32_t vertexDeclaration)
|
||||||
static void Present()
|
static void Present()
|
||||||
{
|
{
|
||||||
WaitForRenderThread();
|
WaitForRenderThread();
|
||||||
bool needsResize = g_needsResize;
|
|
||||||
g_pendingRenderThread = true;
|
g_pendingRenderThread = true;
|
||||||
|
|
||||||
RenderCommand cmd;
|
RenderCommand cmd;
|
||||||
|
|
@ -1412,21 +1397,9 @@ static void ProcPresent(const RenderCommand& cmd)
|
||||||
g_commandListStates[g_frame] = false;
|
g_commandListStates[g_frame] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
std::lock_guard lock(g_tempMutex);
|
|
||||||
|
|
||||||
g_tempBuffers[g_frame].clear();
|
|
||||||
g_tempTextures[g_frame].clear();
|
|
||||||
|
|
||||||
for (auto index : g_tempDescriptorIndices[g_frame])
|
|
||||||
g_textureDescriptorAllocator.free(index);
|
|
||||||
|
|
||||||
g_tempDescriptorIndices[g_frame].clear();
|
|
||||||
g_tempFramebuffers[g_frame].clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
g_dirtyStates = DirtyStates(true);
|
g_dirtyStates = DirtyStates(true);
|
||||||
g_uploadAllocators[g_frame].reset();
|
g_uploadAllocators[g_frame].reset();
|
||||||
|
DestructTempResources();
|
||||||
g_quadIndexBuffer = {};
|
g_quadIndexBuffer = {};
|
||||||
g_quadCount = 0;
|
g_quadCount = 0;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue