mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 23:11:25 +12:00
d3d12: enable texture caching
Bring a little more perf in arkedo 2
This commit is contained in:
parent
8cc9642b96
commit
c6a5e905bc
3 changed files with 47 additions and 25 deletions
|
@ -399,18 +399,29 @@ D3D12GSRender::D3D12GSRender()
|
||||||
{
|
{
|
||||||
|
|
||||||
gfxHandler = [this](u32 addr) {
|
gfxHandler = [this](u32 addr) {
|
||||||
LOG_ERROR(RSX, "CATCH SEGFAULT %x", addr);
|
bool handled = false;
|
||||||
for (auto tmp : texaddrs)
|
auto It = m_protectedTextures.begin(), E = m_protectedTextures.end();
|
||||||
|
for (; It != E;)
|
||||||
{
|
{
|
||||||
if (addr - tmp.first < tmp.second)
|
auto currentIt = It;
|
||||||
|
++It;
|
||||||
|
auto protectedTexture = *currentIt;
|
||||||
|
u32 protectedRangeStart = std::get<1>(protectedTexture), protectedRangeSize = std::get<2>(protectedTexture);
|
||||||
|
if (addr - protectedRangeStart < protectedRangeSize)
|
||||||
{
|
{
|
||||||
LOG_ERROR(RSX, "Modified %x range, starting again", tmp.first);
|
std::lock_guard<std::mutex> lock(mut);
|
||||||
vm::page_protect(tmp.first, tmp.second, 0, vm::page_writable, 0);
|
u32 texadrr = std::get<0>(protectedTexture);
|
||||||
return true;
|
LOG_WARNING(RSX, "Modified %x, starting again", texadrr);
|
||||||
|
ID3D12Resource *texToErase = m_texturesCache[texadrr];
|
||||||
|
m_texturesCache.erase(texadrr);
|
||||||
|
m_Textoclean.push_back(texToErase);
|
||||||
|
|
||||||
|
vm::page_protect(protectedRangeStart, protectedRangeSize, 0, vm::page_writable, 0);
|
||||||
|
m_protectedTextures.erase(currentIt);
|
||||||
|
handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return handled;
|
||||||
return false;
|
|
||||||
};
|
};
|
||||||
loadD3D12FunctionPointers();
|
loadD3D12FunctionPointers();
|
||||||
if (Ini.GSDebugOutputEnable.GetValue())
|
if (Ini.GSDebugOutputEnable.GetValue())
|
||||||
|
@ -1041,7 +1052,6 @@ void D3D12GSRender::Flip()
|
||||||
m_commandQueueGraphic->Signal(storage.m_frameFinishedFence, 1);
|
m_commandQueueGraphic->Signal(storage.m_frameFinishedFence, 1);
|
||||||
|
|
||||||
// Flush
|
// Flush
|
||||||
m_texturesCache.clear();
|
|
||||||
m_texturesRTTs.clear();
|
m_texturesRTTs.clear();
|
||||||
|
|
||||||
std::vector<std::function<void()> > cleaningFunction =
|
std::vector<std::function<void()> > cleaningFunction =
|
||||||
|
@ -1052,7 +1062,11 @@ void D3D12GSRender::Flip()
|
||||||
m_textureData.getCleaningFunction()
|
m_textureData.getCleaningFunction()
|
||||||
};
|
};
|
||||||
|
|
||||||
m_GC.pushWork([&, cleaningFunction]()
|
std::lock_guard<std::mutex> lock(mut);
|
||||||
|
std::vector<ID3D12Resource *> textoclean = m_Textoclean;
|
||||||
|
m_Textoclean.clear();
|
||||||
|
|
||||||
|
m_GC.pushWork([&, cleaningFunction, textoclean]()
|
||||||
{
|
{
|
||||||
WaitForSingleObject(storage.m_frameFinishedHandle, INFINITE);
|
WaitForSingleObject(storage.m_frameFinishedHandle, INFINITE);
|
||||||
CloseHandle(storage.m_frameFinishedHandle);
|
CloseHandle(storage.m_frameFinishedHandle);
|
||||||
|
@ -1061,6 +1075,9 @@ void D3D12GSRender::Flip()
|
||||||
for (unsigned i = 0; i < 4; i++)
|
for (unsigned i = 0; i < 4; i++)
|
||||||
cleaningFunction[i]();
|
cleaningFunction[i]();
|
||||||
storage.Reset();
|
storage.Reset();
|
||||||
|
|
||||||
|
for (auto tmp : textoclean)
|
||||||
|
tmp->Release();
|
||||||
});
|
});
|
||||||
|
|
||||||
while (getCurrentResourceStorage().m_frameFinishedHandle)
|
while (getCurrentResourceStorage().m_frameFinishedHandle)
|
||||||
|
|
|
@ -202,7 +202,14 @@ struct GarbageCollectionThread
|
||||||
class D3D12GSRender : public GSRender
|
class D3D12GSRender : public GSRender
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::vector <std::pair<u32, u32> > texaddrs; // Address, size
|
/**
|
||||||
|
* Mutex protecting m_texturesCache and m_Textoclean access
|
||||||
|
* Memory protection fault catch can be generated by any thread and
|
||||||
|
* modifies these two members.
|
||||||
|
*/
|
||||||
|
std::mutex mut;
|
||||||
|
std::list <std::tuple<u32, u32, u32> > m_protectedTextures; // Texaddress, start of protected range, size of protected range
|
||||||
|
std::vector<ID3D12Resource *> m_Textoclean;
|
||||||
GarbageCollectionThread m_GC;
|
GarbageCollectionThread m_GC;
|
||||||
// Copy of RTT to be used as texture
|
// Copy of RTT to be used as texture
|
||||||
std::unordered_map<u32, ID3D12Resource* > m_texturesRTTs;
|
std::unordered_map<u32, ID3D12Resource* > m_texturesRTTs;
|
||||||
|
|
|
@ -337,8 +337,7 @@ ID3D12Resource *uploadSingleTexture(
|
||||||
const RSXTexture &texture,
|
const RSXTexture &texture,
|
||||||
ID3D12Device *device,
|
ID3D12Device *device,
|
||||||
ID3D12GraphicsCommandList *commandList,
|
ID3D12GraphicsCommandList *commandList,
|
||||||
DataHeap<ID3D12Heap, 65536> &textureBuffersHeap,
|
DataHeap<ID3D12Heap, 65536> &textureBuffersHeap)
|
||||||
DataHeap<ID3D12Heap, 65536> &textureHeap)
|
|
||||||
{
|
{
|
||||||
ID3D12Resource *vramTexture;
|
ID3D12Resource *vramTexture;
|
||||||
size_t w = texture.GetWidth(), h = texture.GetHeight();
|
size_t w = texture.GetWidth(), h = texture.GetHeight();
|
||||||
|
@ -552,19 +551,17 @@ ID3D12Resource *uploadSingleTexture(
|
||||||
D3D12_RESOURCE_DESC texturedesc = getTexture2DResourceDesc(w, h, dxgiFormat, texture.GetMipmap());
|
D3D12_RESOURCE_DESC texturedesc = getTexture2DResourceDesc(w, h, dxgiFormat, texture.GetMipmap());
|
||||||
textureSize = device->GetResourceAllocationInfo(0, 1, &texturedesc).SizeInBytes;
|
textureSize = device->GetResourceAllocationInfo(0, 1, &texturedesc).SizeInBytes;
|
||||||
|
|
||||||
assert(textureHeap.canAlloc(textureSize));
|
D3D12_HEAP_PROPERTIES heapProp = {};
|
||||||
size_t heapOffset2 = textureHeap.alloc(textureSize);
|
heapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||||
|
|
||||||
check(device->CreatePlacedResource(
|
check(device->CreateCommittedResource(
|
||||||
textureHeap.m_heap,
|
&heapProp,
|
||||||
heapOffset2,
|
D3D12_HEAP_FLAG_NONE,
|
||||||
&texturedesc,
|
&texturedesc,
|
||||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||||
nullptr,
|
nullptr,
|
||||||
IID_PPV_ARGS(&vramTexture)
|
IID_PPV_ARGS(&vramTexture)
|
||||||
));
|
));
|
||||||
textureHeap.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset2, textureSize, vramTexture));
|
|
||||||
|
|
||||||
|
|
||||||
size_t miplevel = 0;
|
size_t miplevel = 0;
|
||||||
for (const MipmapLevelInfo mli : mipInfos)
|
for (const MipmapLevelInfo mli : mipInfos)
|
||||||
|
@ -597,6 +594,7 @@ ID3D12Resource *uploadSingleTexture(
|
||||||
|
|
||||||
size_t D3D12GSRender::UploadTextures()
|
size_t D3D12GSRender::UploadTextures()
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mut);
|
||||||
size_t usedTexture = 0;
|
size_t usedTexture = 0;
|
||||||
|
|
||||||
for (u32 i = 0; i < m_textures_count; ++i)
|
for (u32 i = 0; i < m_textures_count; ++i)
|
||||||
|
@ -630,17 +628,17 @@ size_t D3D12GSRender::UploadTextures()
|
||||||
ID3D12GraphicsCommandList *commandList;
|
ID3D12GraphicsCommandList *commandList;
|
||||||
check(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, getCurrentResourceStorage().m_textureUploadCommandAllocator, nullptr, IID_PPV_ARGS(&commandList)));
|
check(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, getCurrentResourceStorage().m_textureUploadCommandAllocator, nullptr, IID_PPV_ARGS(&commandList)));
|
||||||
|
|
||||||
vramTexture = uploadSingleTexture(m_textures[i], m_device, commandList, m_textureUploadData, m_textureData);
|
vramTexture = uploadSingleTexture(m_textures[i], m_device, commandList, m_textureUploadData);
|
||||||
|
|
||||||
commandList->Close();
|
commandList->Close();
|
||||||
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)&commandList);
|
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)&commandList);
|
||||||
getCurrentResourceStorage().m_inflightCommandList.push_back(commandList);
|
getCurrentResourceStorage().m_inflightCommandList.push_back(commandList);
|
||||||
m_texturesCache[texaddr] = vramTexture;
|
m_texturesCache[texaddr] = vramTexture;
|
||||||
|
|
||||||
size_t s = powerOf2Align(w * h * 4, 4096);
|
u32 s = align(w * h * 4, 4096);
|
||||||
LOG_ERROR(RSX, "PROTECTING %x of size %d", powerOf2Align(texaddr, 4096), s);
|
LOG_WARNING(RSX, "PROTECTING %x of size %d", align(texaddr, 4096), s);
|
||||||
texaddrs.push_back(std::make_pair(texaddr & ~0xfff, s));
|
m_protectedTextures.push_back(std::make_tuple(texaddr, align(texaddr, 4096), s));
|
||||||
vm::page_protect(texaddr & ~0xfff, s, 0, 0, vm::page_writable);
|
vm::page_protect(align(texaddr, 4096), s, 0, 0, vm::page_writable);
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
|
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue