Skip to content

Commit 2c0d9f2

Browse files
committed
New RT detection algorithm with better compatibility
1 parent 92d4bdf commit 2c0d9f2

File tree

1 file changed

+79
-31
lines changed

1 file changed

+79
-31
lines changed

impl.cpp

Lines changed: 79 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@ static const GUID IID_MSAATexture = {0xe2728d94,0x9fdd,0x40d0,{0x87,0xa8,0x09,0x
1818
static const GUID IID_AlphaToCoverage = {0xe2728d95,0x9fdd,0x40d0,{0x87,0xa8,0x09,0xb6,0x2d,0xf3,0x14,0x9a}};
1919
static const GUID IID_OriginalShader = {0xe2728d96,0x9fdd,0x40d0,{0x87,0xa8,0x09,0xb6,0x2d,0xf3,0x14,0x9a}};
2020

21+
enum class MSAACandidateState : UINT {
22+
None = 0,
23+
Possible, // Created SRV, not shadow buffer
24+
Probable, // Likely to be the main RV
25+
Dirty, // MSAA texture created, not yet resolved
26+
Clean, // MSAA texture created, has been resolved
27+
};
28+
// Static const versions that we can take pointers to
29+
static const MSAACandidateState MSAACandidateStatePossible = MSAACandidateState::Possible;
30+
static const MSAACandidateState MSAACandidateStateProbable = MSAACandidateState::Probable;
31+
static const MSAACandidateState MSAACandidateStateDirty = MSAACandidateState::Dirty;
32+
static const MSAACandidateState MSAACandidateStateClean = MSAACandidateState::Clean;
33+
2134
struct ATFIX_RESOURCE_INFO {
2235
D3D11_RESOURCE_DIMENSION Dim;
2336
DXGI_FORMAT Format;
@@ -290,6 +303,7 @@ ID3D11DepthStencilView* getOrCreateMSAADSV(ID3D11Device* dev, ID3D11DepthStencil
290303
desc.Format = vdesc.Format;
291304
desc.SampleDesc.Count = config.msaaSamples;
292305
desc.SampleDesc.Quality = 0;
306+
desc.BindFlags &= ~D3D11_BIND_SHADER_RESOURCE;
293307
while (desc.SampleDesc.Count > 1) {
294308
UINT quality = 0;
295309
if (SUCCEEDED(dev->CheckMultisampleQualityLevels(desc.Format, desc.SampleDesc.Count, &quality)) && quality > 0)
@@ -310,12 +324,17 @@ ID3D11DepthStencilView* getOrCreateMSAADSV(ID3D11Device* dev, ID3D11DepthStencil
310324

311325
void resolveIfMSAA(ID3D11DeviceContext* ctx, ID3D11Resource* res) {
312326
if (ID3D11Resource* msaa = getMSAATexture(res)) {
313-
ID3D11Texture2D* tex;
314-
D3D11_TEXTURE2D_DESC desc;
315-
msaa->QueryInterface(IID_PPV_ARGS(&tex));
316-
tex->GetDesc(&desc);
317-
tex->Release();
318-
ctx->ResolveSubresource(res, 0, msaa, 0, desc.Format);
327+
MSAACandidateState state = MSAACandidateState::None;
328+
UINT size = sizeof(state);
329+
if (SUCCEEDED(res->GetPrivateData(IID_MSAACandidate, &size, &state)) && state == MSAACandidateState::Dirty) {
330+
ID3D11Texture2D* tex;
331+
D3D11_TEXTURE2D_DESC desc;
332+
msaa->QueryInterface(IID_PPV_ARGS(&tex));
333+
tex->GetDesc(&desc);
334+
tex->Release();
335+
ctx->ResolveSubresource(res, 0, msaa, 0, desc.Format);
336+
msaa->SetPrivateData(IID_MSAACandidate, sizeof(state), &MSAACandidateStateClean);
337+
}
319338
msaa->Release();
320339
}
321340
}
@@ -837,6 +856,13 @@ class DeviceWrapper final : public ID3D11Device, IDXGIDevice1 {
837856
desc.Format = DXGI_FORMAT_R16_UNORM;
838857
pDesc = &desc;
839858
}
859+
if (config.msaaSamples && tdesc.Format == DXGI_FORMAT_B8G8R8A8_TYPELESS && !(isPowerOfTwo(tdesc.Width) && !isPowerOfTwo(tdesc.Height))) {
860+
// Not shadow texture
861+
MSAACandidateState state = MSAACandidateState::None;
862+
UINT size = sizeof(state);
863+
if (FAILED(tex->GetPrivateData(IID_MSAACandidate, &size, &state)) || state == MSAACandidateState::None)
864+
tex->SetPrivateData(IID_MSAACandidate, sizeof(state), &MSAACandidateStatePossible);
865+
}
840866
tex->Release();
841867
}
842868
return dev->CreateRenderTargetView(pResource, pDesc, ppRTView);
@@ -967,6 +993,7 @@ class DeviceWrapper final : public ID3D11Device, IDXGIDevice1 {
967993

968994
class ContextWrapper final : public ID3D11DeviceContext {
969995
LONG refcnt;
996+
UINT numIndexedDraws = 0;
970997
ID3D11DeviceContext* ctx;
971998
ID3D11BlendState* alphaToCoverageBlend = nullptr;
972999
ID3D11BlendState* requestedBlend = nullptr;
@@ -1027,10 +1054,8 @@ class ContextWrapper final : public ID3D11DeviceContext {
10271054

10281055
// ID3D11DeviceContext
10291056
void VSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) override { ctx->VSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); }
1030-
void PSSetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) override { ctx->PSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); }
10311057
void PSSetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) override { ctx->PSSetSamplers(StartSlot, NumSamplers, ppSamplers); }
10321058
void VSSetShader(ID3D11VertexShader* pVertexShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances) override { ctx->VSSetShader(pVertexShader, ppClassInstances, NumClassInstances); }
1033-
void DrawIndexed(UINT IndexCount, UINT StartIndexLocation, INT BaseVertexLocation) override { ctx->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation); }
10341059
void Draw(UINT VertexCount, UINT StartVertexLocation) override { ctx->Draw(VertexCount, StartVertexLocation); }
10351060
HRESULT Map(ID3D11Resource* pResource, UINT Subresource, D3D11_MAP MapType, UINT MapFlags, D3D11_MAPPED_SUBRESOURCE* pMappedResource) override { return ctx->Map(pResource, Subresource, MapType, MapFlags, pMappedResource); }
10361061
void Unmap(ID3D11Resource* pResource, UINT Subresource) override { ctx->Unmap(pResource, Subresource); }
@@ -1122,6 +1147,23 @@ class ContextWrapper final : public ID3D11DeviceContext {
11221147
UINT GetContextFlags() override { return ctx->GetContextFlags(); }
11231148
HRESULT FinishCommandList(BOOL RestoreDeferredContextState, ID3D11CommandList** ppCommandList) override { return ctx->FinishCommandList(RestoreDeferredContextState, ppCommandList); }
11241149

1150+
void DrawIndexed(UINT IndexCount, UINT StartIndexLocation, INT BaseVertexLocation) override {
1151+
numIndexedDraws++;
1152+
ctx->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation);
1153+
}
1154+
1155+
void PSSetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) override {
1156+
for (UINT i = 0; i < NumViews; i++) {
1157+
if (ppShaderResourceViews[i]) {
1158+
ID3D11Resource* res = nullptr;
1159+
ppShaderResourceViews[i]->GetResource(&res);
1160+
resolveIfMSAA(ctx, res);
1161+
res->Release();
1162+
}
1163+
}
1164+
ctx->PSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews);
1165+
}
1166+
11251167
void PSSetShader(ID3D11PixelShader* pPixelShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances) override {
11261168
requestedPS = pPixelShader;
11271169
ID3D11PixelShader* a2c = nullptr;
@@ -1258,14 +1300,6 @@ class ContextWrapper final : public ID3D11DeviceContext {
12581300
ID3D11Resource* dstShadow = getShadowResource(pDstResource);
12591301

12601302
resolveIfMSAA(ctx, pSrcResource);
1261-
UINT info;
1262-
UINT size = sizeof(info);
1263-
if (SUCCEEDED(pSrcResource->GetPrivateData(IID_MSAACandidate, &size, &info)) && info == 1) {
1264-
// Sophie always copies from its main render target to another one for postprocessing effects
1265-
// Detect that to enable MSAA on it
1266-
info = 2;
1267-
pSrcResource->SetPrivateData(IID_MSAACandidate, sizeof(info), &info);
1268-
}
12691303

12701304
bool needsBaseCopy = true;
12711305
bool needsShadowCopy = true;
@@ -1325,38 +1359,52 @@ class ContextWrapper final : public ID3D11DeviceContext {
13251359
ID3D11DepthStencilView* pDSV) override {
13261360
updateRtvShadowResources(ctx);
13271361

1328-
ID3D11Resource* base = nullptr;
1362+
// Sophie seems to only use indexed draws on the main RT, shadow texture, and a texture where they pre-blend ground tiles
1363+
// There's usually only 10-20 ground tile draws, so target 64 as a safe number to avoid the ground tile draws
1364+
if (config.msaaSamples > 1 && numIndexedDraws > 64) {
1365+
ID3D11DepthStencilView* dsv = nullptr;
1366+
ID3D11RenderTargetView* rtv = nullptr;
1367+
MSAACandidateState state = MSAACandidateState::None;
1368+
UINT size = sizeof(state);
1369+
ctx->OMGetRenderTargets(1, &rtv, &dsv);
1370+
if (rtv && dsv) {
1371+
ID3D11Resource* rtvtex = nullptr;
1372+
rtv->GetResource(&rtvtex);
1373+
if (SUCCEEDED(rtvtex->GetPrivateData(IID_MSAACandidate, &size, &state)) && state == MSAACandidateState::Possible) {
1374+
rtvtex->SetPrivateData(IID_MSAACandidate, sizeof(state), &MSAACandidateStateProbable);
1375+
log("Marking texture with ", std::dec, numIndexedDraws, " indexed draws as MSAA target");
1376+
}
1377+
rtvtex->Release();
1378+
}
1379+
if (dsv) dsv->Release();
1380+
if (rtv) rtv->Release();
1381+
}
1382+
numIndexedDraws = 0;
1383+
13291384
ID3D11RenderTargetView* msaaTex = nullptr;
13301385
ID3D11DepthStencilView* msaaDepth = nullptr;
13311386

13321387
if (config.msaaSamples > 1 && ppRTVs && RTVCount == 1 && pDSV) {
1388+
ID3D11Resource* base = nullptr;
13331389
ppRTVs[0]->GetResource(&base);
1334-
UINT info;
1335-
UINT size = sizeof(info);
1336-
if (SUCCEEDED(base->GetPrivateData(IID_MSAACandidate, &size, &info)) && info == 2) {
1390+
MSAACandidateState state = MSAACandidateState::None;
1391+
UINT size = sizeof(state);
1392+
if (SUCCEEDED(base->GetPrivateData(IID_MSAACandidate, &size, &state)) && state >= MSAACandidateState::Probable) {
13371393
ID3D11Device* dev;
13381394
ctx->GetDevice(&dev);
13391395
msaaTex = getOrCreateMSAARTV(dev, ppRTVs[0]);
13401396
msaaDepth = getOrCreateMSAADSV(dev, pDSV);
13411397
ppRTVs = &msaaTex;
13421398
pDSV = msaaDepth;
13431399
dev->Release();
1400+
// We're rendering to the texture so it's now dirty
1401+
base->SetPrivateData(IID_MSAACandidate, sizeof(state), &MSAACandidateStateDirty);
13441402
}
1403+
base->Release();
13451404
}
13461405

13471406
ctx->OMSetRenderTargets(RTVCount, ppRTVs, pDSV);
13481407

1349-
if (base && pDSV && !msaaTex) {
1350-
UINT value = 1;
1351-
ID3D11Texture2D* tex;
1352-
D3D11_TEXTURE2D_DESC desc;
1353-
base->QueryInterface(IID_PPV_ARGS(&tex));
1354-
tex->GetDesc(&desc);
1355-
tex->Release();
1356-
base->SetPrivateData(IID_MSAACandidate, sizeof(value), &value);
1357-
}
1358-
1359-
if (base) base->Release();
13601408
if (msaaTex) msaaTex->Release();
13611409
if (msaaDepth) msaaDepth->Release();
13621410
}

0 commit comments

Comments
 (0)