mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff9da17498 | ||
|
|
722bc94270 | ||
|
|
d51a5db5b1 | ||
|
|
04541ae2ab | ||
|
|
c58a67815b | ||
|
|
085f964cd9 | ||
|
|
a8b6e448eb | ||
|
|
78ab8381d9 | ||
|
|
49a5d82086 | ||
|
|
4ed129ccac | ||
|
|
ed09dca17e | ||
|
|
e64fbb2f0e | ||
|
|
e37f8a6521 | ||
|
|
b54bcc0e20 | ||
|
|
db37d51bb1 | ||
|
|
197b9fc560 | ||
|
|
fd30b00205 | ||
|
|
f182379d24 | ||
|
|
32ba08980d | ||
|
|
1e1f08abb9 | ||
|
|
cbe20c0eed | ||
|
|
ec288ffa62 | ||
|
|
7e18c02c7e | ||
|
|
4a505cc239 | ||
|
|
35c81106c6 |
1
.github/workflows/linux_build_qt.yml
vendored
1
.github/workflows/linux_build_qt.yml
vendored
@@ -144,6 +144,7 @@ jobs:
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DENABLE_SETCAP=OFF \
|
||||
-DDISABLE_ADVANCE_SIMD=TRUE \
|
||||
-DUSE_LINKED_FFMPEG=ON \
|
||||
-DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON \
|
||||
$ADDITIONAL_CMAKE_ARGS
|
||||
|
||||
|
||||
@@ -2409,6 +2409,7 @@ SCAJ-20179:
|
||||
autoFlush: 1 # Fixes shadows.
|
||||
halfPixelOffset: 4 # Fixes lighting misalignment.
|
||||
nativeScaling: 2 # Fixes lighting smoothness.
|
||||
textureInsideRT: 1 # Fixes broken crystalline surface textures.
|
||||
SCAJ-20180:
|
||||
name: "Xenosaga Episode III - Also Sprach Zarathustra [Disc 2 of 2]"
|
||||
region: "NTSC-Unk"
|
||||
@@ -2416,6 +2417,7 @@ SCAJ-20180:
|
||||
autoFlush: 1 # Fixes shadows.
|
||||
halfPixelOffset: 4 # Fixes lighting misalignment.
|
||||
nativeScaling: 2 # Fixes lighting smoothness.
|
||||
textureInsideRT: 1 # Fixes broken crystalline surface textures.
|
||||
SCAJ-20181:
|
||||
name: "Minna no Tennis"
|
||||
region: "NTSC-Unk"
|
||||
@@ -6072,6 +6074,8 @@ SCES-53409:
|
||||
SCES-53422:
|
||||
name: "Stuart Little 3 - Big Photo Adventure"
|
||||
region: "PAL-M9"
|
||||
gameFixes:
|
||||
- InstantDMAHack # Fixes loading screen corruption.
|
||||
gsHWFixes:
|
||||
autoFlush: 2 # Fixes missing effects.
|
||||
SCES-53449:
|
||||
@@ -7549,8 +7553,11 @@ SCKA-20066:
|
||||
name: "EyeToy - Play 3"
|
||||
region: "NTSC-K"
|
||||
SCKA-20067:
|
||||
name: "Stuart Little 3 - Big Photo Adventure"
|
||||
name: "스튜어트 리틀 3 - 빅 포토 어드벤처"
|
||||
name-en: "Stuart Little 3 - Big Photo Adventure"
|
||||
region: "NTSC-K"
|
||||
gameFixes:
|
||||
- InstantDMAHack # Fixes loading screen corruption.
|
||||
gsHWFixes:
|
||||
autoFlush: 2 # Fixes missing effects.
|
||||
SCKA-20068:
|
||||
@@ -21810,7 +21817,6 @@ SLES-53028:
|
||||
halfPixelOffset: 5 # Fixes alignment of shuffles and post-processing.
|
||||
autoFlush: 1 # Fixes sun intensity.
|
||||
textureInsideRT: 1 # Fixes post-processing.
|
||||
getSkipCount: "GSC_HitmanBloodMoney"
|
||||
SLES-53029:
|
||||
name: "Hitman - Blood Money"
|
||||
region: "PAL-F"
|
||||
@@ -21821,7 +21827,6 @@ SLES-53029:
|
||||
halfPixelOffset: 5 # Fixes alignment of shuffles and post-processing.
|
||||
autoFlush: 1 # Fixes sun intensity.
|
||||
textureInsideRT: 1 # Fixes post-processing.
|
||||
getSkipCount: "GSC_HitmanBloodMoney"
|
||||
SLES-53030:
|
||||
name: "Hitman - Blood Money"
|
||||
region: "PAL-G"
|
||||
@@ -21832,7 +21837,6 @@ SLES-53030:
|
||||
halfPixelOffset: 5 # Fixes alignment of shuffles and post-processing.
|
||||
autoFlush: 1 # Fixes sun intensity.
|
||||
textureInsideRT: 1 # Fixes post-processing.
|
||||
getSkipCount: "GSC_HitmanBloodMoney"
|
||||
SLES-53031:
|
||||
name: "Hitman - Blood Money"
|
||||
region: "PAL-I"
|
||||
@@ -21843,7 +21847,6 @@ SLES-53031:
|
||||
halfPixelOffset: 5 # Fixes alignment of shuffles and post-processing.
|
||||
autoFlush: 1 # Fixes sun intensity.
|
||||
textureInsideRT: 1 # Fixes post-processing.
|
||||
getSkipCount: "GSC_HitmanBloodMoney"
|
||||
SLES-53032:
|
||||
name: "Hitman - Blood Money"
|
||||
region: "PAL-S"
|
||||
@@ -21854,7 +21857,6 @@ SLES-53032:
|
||||
halfPixelOffset: 5 # Fixes alignment of shuffles and post-processing.
|
||||
autoFlush: 1 # Fixes sun intensity.
|
||||
textureInsideRT: 1 # Fixes post-processing.
|
||||
getSkipCount: "GSC_HitmanBloodMoney"
|
||||
SLES-53035:
|
||||
name: "Masters of the Universe - He-Man - Defender of Greyskull"
|
||||
region: "PAL-E"
|
||||
@@ -35734,6 +35736,7 @@ SLPM-61147:
|
||||
autoFlush: 1 # Fixes shadows.
|
||||
halfPixelOffset: 4 # Fixes lighting misalignment.
|
||||
nativeScaling: 2 # Fixes lighting smoothness.
|
||||
textureInsideRT: 1 # Fixes broken crystalline surface textures.
|
||||
SLPM-61148:
|
||||
name: "グローランサーⅤ ジェネレーションズ [体験版]"
|
||||
name-sort: "ぐろーらんさー5 じぇねれーしょんず [たいけんばん]"
|
||||
@@ -59562,6 +59565,7 @@ SLPS-25640:
|
||||
autoFlush: 1 # Fixes shadows.
|
||||
halfPixelOffset: 4 # Fixes lighting misalignment.
|
||||
nativeScaling: 2 # Fixes lighting smoothness.
|
||||
textureInsideRT: 1 # Fixes broken crystalline surface textures.
|
||||
memcardFilters: # Allows import of Xenosaga II save data.
|
||||
- "SLPS-25640"
|
||||
- "SLPS-25368"
|
||||
@@ -59575,6 +59579,7 @@ SLPS-25641:
|
||||
autoFlush: 1 # Fixes shadows.
|
||||
halfPixelOffset: 4 # Fixes lighting misalignment.
|
||||
nativeScaling: 2 # Fixes lighting smoothness.
|
||||
textureInsideRT: 1 # Fixes broken crystalline surface textures.
|
||||
memcardFilters:
|
||||
- "SLPS-25640"
|
||||
- "SLPS-25368"
|
||||
@@ -68427,7 +68432,6 @@ SLUS-21108:
|
||||
halfPixelOffset: 5 # Fixes alignment of shuffles and post-processing.
|
||||
autoFlush: 1 # Fixes sun intensity.
|
||||
textureInsideRT: 1 # Fixes post-processing.
|
||||
getSkipCount: "GSC_HitmanBloodMoney"
|
||||
SLUS-21109:
|
||||
name: "Drive to Survive"
|
||||
region: "NTSC-U"
|
||||
@@ -69974,6 +69978,11 @@ SLUS-21338:
|
||||
halfPixelOffset: 2 # Corrects shadow alignment and reduces blurriness.
|
||||
recommendedBlendingLevel: 3 # Fixes level and map menu brightness.
|
||||
preloadFrameData: 1 # Fixes glowing emblems.
|
||||
memcardFilters: # Convert savegames from AC: Nexus and AC: Nine Breaker.
|
||||
- "SLUS-21338"
|
||||
- "SLUS-21200"
|
||||
- "SLUS-20986"
|
||||
- "SLUS-21079"
|
||||
SLUS-21339:
|
||||
name: "Puzzle Challenge - Crosswords and More!"
|
||||
region: "NTSC-U"
|
||||
@@ -69986,6 +69995,8 @@ SLUS-21341:
|
||||
name: "Stuart Little 3 - Big Photo Adventure"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- InstantDMAHack # Fixes loading screen corruption.
|
||||
gsHWFixes:
|
||||
autoFlush: 2 # Fixes missing effects.
|
||||
SLUS-21342:
|
||||
@@ -70356,6 +70367,7 @@ SLUS-21389:
|
||||
autoFlush: 1 # Fixes shadows.
|
||||
halfPixelOffset: 4 # Fixes lighting misalignment.
|
||||
nativeScaling: 2 # Fixes lighting smoothness.
|
||||
textureInsideRT: 1 # Fixes broken crystalline surface textures.
|
||||
memcardFilters: # Allows import of Xenosaga II save data.
|
||||
- "SLUS-21389"
|
||||
- "SLUS-20892"
|
||||
@@ -70525,6 +70537,7 @@ SLUS-21417:
|
||||
autoFlush: 1 # Fixes shadows.
|
||||
halfPixelOffset: 4 # Fixes lighting misalignment.
|
||||
nativeScaling: 2 # Fixes lighting smoothness.
|
||||
textureInsideRT: 1 # Fixes broken crystalline surface textures.
|
||||
memcardFilters:
|
||||
- "SLUS-21389"
|
||||
- "SLUS-20892"
|
||||
@@ -74341,8 +74354,8 @@ SLUS-29191:
|
||||
vuClampMode: 0 # Fixes bump mapping issues
|
||||
gsHWFixes:
|
||||
textureInsideRT: 1 # Fixes post-processing.
|
||||
autoFlush: 1 # Fixes sun intensity in Hitman.
|
||||
halfPixelOffset: 5 # Fixes alignment of shuffles and post-processing in Hitman.
|
||||
getSkipCount: "GSC_HitmanBloodMoney"
|
||||
SLUS-29192:
|
||||
name: "Test Drive Unlimited [Public Beta Vol.1.0]"
|
||||
region: "NTSC-U"
|
||||
|
||||
@@ -329,6 +329,7 @@
|
||||
030000000d0f0000ee00000000000000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||
030000000d0f0000c100000000000000,Horipad Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
030000000d0f0000f600000000000000,Horipad Nintendo Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||
030000000d0f00000202000000000000,Horipad O Nintendo Switch 2 Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,misc2:b14,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
|
||||
030000000d0f00006700000000000000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||
030000000d0f00009601000000000000,Horipad Steam,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc2:b2,paddle1:b5,paddle2:b15,paddle3:b18,paddle4:b19,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
030000000d0f0000dc00000000000000,Horipad Switch,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -575,7 +575,7 @@ void GSState::GIFPackedRegHandlerSTQ(const GIFPackedReg* RESTRICT r)
|
||||
|
||||
// Vexx (character shadow)
|
||||
// q = 0 (st also 0 on the first 16 vertices), setting it to 1.0f to avoid div by zero later
|
||||
q = q.blend8(GSVector4i::cast(GSVector4::m_one), q == GSVector4i::zero());
|
||||
q = q.blend8(GSVector4i::cast(GSVector4(FLT_MIN)), q == GSVector4i::zero());
|
||||
|
||||
// Suikoden 4
|
||||
// creates some nan for Q. Let's avoid undefined behavior (See GIFRegHandlerRGBAQ)
|
||||
@@ -671,7 +671,7 @@ void GSState::GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, u3
|
||||
GSVector4i q = GSVector4i::loadl(&r[0].U64[1]);
|
||||
const GSVector4i rgba = (GSVector4i::load<false>(&r[1]) & GSVector4i::x000000ff()).ps32().pu16();
|
||||
|
||||
q = q.blend8(GSVector4i::cast(GSVector4::m_one), q == GSVector4i::zero()); // see GIFPackedRegHandlerSTQ
|
||||
q = q.blend8(GSVector4i::cast(GSVector4(FLT_MIN)), q == GSVector4i::zero()); // see GIFPackedRegHandlerSTQ
|
||||
|
||||
m_v.m[0] = st.upl64(rgba.upl32(q)); // TODO: only store the last one
|
||||
|
||||
@@ -705,7 +705,7 @@ void GSState::GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, u32
|
||||
GSVector4i q = GSVector4i::loadl(&r[0].U64[1]);
|
||||
const GSVector4i rgba = (GSVector4i::load<false>(&r[1]) & GSVector4i::x000000ff()).ps32().pu16();
|
||||
|
||||
q = q.blend8(GSVector4i::cast(GSVector4::m_one), q == GSVector4i::zero()); // see GIFPackedRegHandlerSTQ
|
||||
q = q.blend8(GSVector4i::cast(GSVector4(FLT_MIN)), q == GSVector4i::zero()); // see GIFPackedRegHandlerSTQ
|
||||
|
||||
m_v.m[0] = st.upl64(rgba.upl32(q)); // TODO: only store the last one
|
||||
|
||||
|
||||
@@ -1105,14 +1105,14 @@ float GSDevice11::GetAndResetAccumulatedGPUTime()
|
||||
void GSDevice11::DrawPrimitive()
|
||||
{
|
||||
g_perfmon.Put(GSPerfMon::DrawCalls, 1);
|
||||
PSUpdateShaderState();
|
||||
PSUpdateShaderState(true, true);
|
||||
m_ctx->Draw(m_vertex.count, m_vertex.start);
|
||||
}
|
||||
|
||||
void GSDevice11::DrawIndexedPrimitive()
|
||||
{
|
||||
g_perfmon.Put(GSPerfMon::DrawCalls, 1);
|
||||
PSUpdateShaderState();
|
||||
PSUpdateShaderState(true, true);
|
||||
m_ctx->DrawIndexed(m_index.count, m_index.start, m_vertex.start);
|
||||
}
|
||||
|
||||
@@ -1120,7 +1120,7 @@ void GSDevice11::DrawIndexedPrimitive(int offset, int count)
|
||||
{
|
||||
pxAssert(offset + count <= (int)m_index.count);
|
||||
g_perfmon.Put(GSPerfMon::DrawCalls, 1);
|
||||
PSUpdateShaderState();
|
||||
PSUpdateShaderState(true, true);
|
||||
m_ctx->DrawIndexed(count, m_index.start + offset, m_vertex.start);
|
||||
}
|
||||
|
||||
@@ -1280,6 +1280,9 @@ void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
|
||||
GSVector2i ds;
|
||||
if (dTex)
|
||||
{
|
||||
// ps unbind conflicting srvs
|
||||
PSUnbindConflictingSRVs(dTex);
|
||||
|
||||
ds = dTex->GetSize();
|
||||
if (draw_in_depth)
|
||||
OMSetRenderTargets(nullptr, dTex);
|
||||
@@ -1292,6 +1295,7 @@ void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
|
||||
}
|
||||
|
||||
// om
|
||||
|
||||
if (draw_in_depth)
|
||||
OMSetDepthStencilState(m_convert.dss_write.get(), 0);
|
||||
else
|
||||
@@ -1329,7 +1333,7 @@ void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
|
||||
PSSetSamplerState(linear ? m_convert.ln.get() : m_convert.pt.get());
|
||||
PSSetShader(ps, ps_cb);
|
||||
|
||||
//
|
||||
// draw
|
||||
|
||||
DrawPrimitive();
|
||||
}
|
||||
@@ -1341,6 +1345,9 @@ void GSDevice11::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
|
||||
GSVector2i ds;
|
||||
if (dTex)
|
||||
{
|
||||
// ps unbind conflicting srvs
|
||||
PSUnbindConflictingSRVs(dTex);
|
||||
|
||||
ds = dTex->GetSize();
|
||||
OMSetRenderTargets(dTex, nullptr);
|
||||
}
|
||||
@@ -1356,6 +1363,7 @@ void GSDevice11::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
|
||||
m_ctx->UpdateSubresource(m_present.ps_cb.get(), 0, nullptr, &cb, 0, 0);
|
||||
|
||||
// om
|
||||
|
||||
OMSetDepthStencilState(m_convert.dss.get(), 0);
|
||||
OMSetBlendState(m_convert.bs[D3D11_COLOR_WRITE_ENABLE_ALL].get(), 0);
|
||||
|
||||
@@ -1388,7 +1396,7 @@ void GSDevice11::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
|
||||
PSSetSamplerState(linear ? m_convert.ln.get() : m_convert.pt.get());
|
||||
PSSetShader(m_present.ps[static_cast<u32>(shader)].get(), m_present.ps_cb.get());
|
||||
|
||||
//
|
||||
// draw
|
||||
|
||||
DrawPrimitive();
|
||||
}
|
||||
@@ -1454,6 +1462,7 @@ void GSDevice11::DrawMultiStretchRects(const MultiStretchRect* rects, u32 num_re
|
||||
|
||||
VSSetShader(m_convert.vs.get(), nullptr);
|
||||
PSSetShader(m_convert.ps[static_cast<int>(shader)].get(), nullptr);
|
||||
PSUnbindConflictingSRVs(dTex);
|
||||
|
||||
OMSetDepthStencilState(dTex->IsRenderTarget() ? m_convert.dss.get() : m_convert.dss_write.get(), 0);
|
||||
OMSetRenderTargets(dTex->IsRenderTarget() ? dTex : nullptr, dTex->IsDepthStencil() ? dTex : nullptr);
|
||||
@@ -2110,7 +2119,7 @@ void GSDevice11::RenderImGui()
|
||||
|
||||
// Since we don't have the GSTexture...
|
||||
m_state.ps_sr_views[0] = reinterpret_cast<ID3D11ShaderResourceView*>(pcmd->GetTexID());
|
||||
PSUpdateShaderState();
|
||||
PSUpdateShaderState(true, true);
|
||||
|
||||
m_ctx->DrawIndexed(pcmd->ElemCount, m_index.start + pcmd->IdxOffset, vertex_offset + pcmd->VtxOffset);
|
||||
}
|
||||
@@ -2130,6 +2139,10 @@ void GSDevice11::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vert
|
||||
|
||||
m_ctx->ClearDepthStencilView(*static_cast<GSTexture11*>(ds), D3D11_CLEAR_STENCIL, 0.0f, 0);
|
||||
|
||||
// ps unbind conflicting srvs
|
||||
|
||||
PSUnbindConflictingSRVs(ds);
|
||||
|
||||
// om
|
||||
|
||||
OMSetDepthStencilState(m_date.dss.get(), 1);
|
||||
@@ -2147,11 +2160,12 @@ void GSDevice11::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vert
|
||||
VSSetShader(m_convert.vs.get(), nullptr);
|
||||
|
||||
// ps
|
||||
|
||||
PSSetShaderResource(0, rt);
|
||||
PSSetSamplerState(m_convert.pt.get());
|
||||
PSSetShader(m_convert.ps[SetDATMShader(datm)].get(), nullptr);
|
||||
|
||||
//
|
||||
// draw
|
||||
|
||||
DrawPrimitive();
|
||||
}
|
||||
@@ -2357,10 +2371,63 @@ void GSDevice11::PSSetShader(ID3D11PixelShader* ps, ID3D11Buffer* ps_cb)
|
||||
}
|
||||
}
|
||||
|
||||
void GSDevice11::PSUpdateShaderState()
|
||||
void GSDevice11::PSUpdateShaderState(const bool sr_update, const bool ss_update)
|
||||
{
|
||||
m_ctx->PSSetShaderResources(0, m_state.ps_sr_views.size(), m_state.ps_sr_views.data());
|
||||
m_ctx->PSSetSamplers(0, m_state.ps_ss.size(), m_state.ps_ss.data());
|
||||
// Shader resource caching requires srv/rtv hazards to be resolved, ensure PSUnbindConflictingSRVs handle.
|
||||
if (sr_update)
|
||||
{
|
||||
bool sr_changed = false;
|
||||
for (size_t i = 0; i < m_state.ps_sr_views.size(); ++i)
|
||||
{
|
||||
if (m_state.ps_cached_sr_views[i] != m_state.ps_sr_views[i])
|
||||
{
|
||||
sr_changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sr_changed)
|
||||
{
|
||||
m_state.ps_cached_sr_views = m_state.ps_sr_views;
|
||||
m_ctx->PSSetShaderResources(0, m_state.ps_sr_views.size(), m_state.ps_sr_views.data());
|
||||
}
|
||||
}
|
||||
|
||||
if (ss_update)
|
||||
{
|
||||
bool ss_changed = false;
|
||||
for (size_t i = 0; i < m_state.ps_ss.size(); ++i)
|
||||
{
|
||||
if (m_state.ps_cached_ss[i] != m_state.ps_ss[i])
|
||||
{
|
||||
ss_changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ss_changed)
|
||||
{
|
||||
m_state.ps_cached_ss = m_state.ps_ss;
|
||||
m_ctx->PSSetSamplers(0, m_state.ps_ss.size(), m_state.ps_ss.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GSDevice11::PSUnbindConflictingSRVs(GSTexture* tex1, GSTexture* tex2)
|
||||
{
|
||||
// Make sure no SRVs are bound using the same texture before binding it to a RTV.
|
||||
bool changed = false;
|
||||
for (size_t i = 0; i < m_state.ps_sr_views.size(); i++)
|
||||
{
|
||||
if ((tex1 && m_state.ps_sr_views[i] == *(GSTexture11*)tex1) || (tex2 && m_state.ps_sr_views[i] == *(GSTexture11*)tex2))
|
||||
{
|
||||
m_state.ps_sr_views[i] = nullptr;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
PSUpdateShaderState(true, false);
|
||||
}
|
||||
|
||||
void GSDevice11::OMSetDepthStencilState(ID3D11DepthStencilState* dss, u8 sref)
|
||||
@@ -2523,18 +2590,18 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
}
|
||||
}
|
||||
|
||||
GSTexture* primid_tex = nullptr;
|
||||
GSTexture* primid_texture = nullptr;
|
||||
if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking)
|
||||
{
|
||||
primid_tex = CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::PrimID, false);
|
||||
if (!primid_tex)
|
||||
primid_texture = CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::PrimID, false);
|
||||
if (!primid_texture)
|
||||
{
|
||||
Console.WriteLn("D3D11: Failed to allocate DATE image, aborting draw.");
|
||||
Console.Warning("D3D11: Failed to allocate DATE image, aborting draw.");
|
||||
return;
|
||||
}
|
||||
|
||||
StretchRect(colclip_rt ? colclip_rt : config.rt, GSVector4(config.drawarea) / GSVector4(rtsize).xyxy(),
|
||||
primid_tex, GSVector4(config.drawarea), m_date.primid_init_ps[static_cast<u8>(config.datm)].get(), nullptr, false);
|
||||
primid_texture, GSVector4(config.drawarea), m_date.primid_init_ps[static_cast<u8>(config.datm)].get(), nullptr, false);
|
||||
}
|
||||
else if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil ||
|
||||
config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne)
|
||||
@@ -2596,6 +2663,9 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
}
|
||||
IASetPrimitiveTopology(topology);
|
||||
|
||||
// Should be called before changing local srv state.
|
||||
PSUnbindConflictingSRVs(colclip_rt ? colclip_rt : config.rt, config.ds);
|
||||
|
||||
if (config.tex)
|
||||
{
|
||||
CommitClear(config.tex);
|
||||
@@ -2645,20 +2715,20 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
SetupVS(config.vs, &config.cb_vs);
|
||||
SetupPS(config.ps, &config.cb_ps, config.sampler);
|
||||
|
||||
if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking)
|
||||
if (primid_texture)
|
||||
{
|
||||
OMDepthStencilSelector dss = config.depth;
|
||||
dss.zwe = 0;
|
||||
const OMBlendSelector blend(GSHWDrawConfig::ColorMaskSelector(1),
|
||||
GSHWDrawConfig::BlendState(true, CONST_ONE, CONST_ONE, 3 /* MIN */, CONST_ONE, CONST_ZERO, false, 0));
|
||||
SetupOM(dss, blend, 0);
|
||||
OMSetRenderTargets(primid_tex, config.ds, &config.scissor);
|
||||
OMSetRenderTargets(primid_texture, config.ds, &config.scissor);
|
||||
DrawIndexedPrimitive();
|
||||
|
||||
config.ps.date = 3;
|
||||
config.alpha_second_pass.ps.date = 3;
|
||||
SetupPS(config.ps, nullptr, config.sampler);
|
||||
PSSetShaderResource(3, primid_tex);
|
||||
PSSetShaderResource(3, primid_texture);
|
||||
}
|
||||
|
||||
SetupOM(config.depth, OMBlendSelector(config.colormask, config.blend), config.blend.constant);
|
||||
@@ -2697,8 +2767,8 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
if (draw_ds_clone)
|
||||
Recycle(draw_ds_clone);
|
||||
|
||||
if (primid_tex)
|
||||
Recycle(primid_tex);
|
||||
if (primid_texture)
|
||||
Recycle(primid_texture);
|
||||
|
||||
if (colclip_rt)
|
||||
{
|
||||
|
||||
@@ -145,9 +145,11 @@ private:
|
||||
ID3D11VertexShader* vs;
|
||||
ID3D11Buffer* vs_cb;
|
||||
std::array<ID3D11ShaderResourceView*, MAX_TEXTURES> ps_sr_views;
|
||||
std::array<ID3D11ShaderResourceView*, MAX_TEXTURES> ps_cached_sr_views;
|
||||
ID3D11PixelShader* ps;
|
||||
ID3D11Buffer* ps_cb;
|
||||
std::array<ID3D11SamplerState*, MAX_SAMPLERS> ps_ss;
|
||||
std::array<ID3D11SamplerState*, MAX_SAMPLERS> ps_cached_ss;
|
||||
GSVector2i viewport;
|
||||
GSVector4i scissor;
|
||||
u32 vb_stride;
|
||||
@@ -324,7 +326,8 @@ public:
|
||||
|
||||
void PSSetShaderResource(int i, GSTexture* sr);
|
||||
void PSSetShader(ID3D11PixelShader* ps, ID3D11Buffer* ps_cb);
|
||||
void PSUpdateShaderState();
|
||||
void PSUpdateShaderState(const bool sr_update, const bool ss_update);
|
||||
void PSUnbindConflictingSRVs(GSTexture* tex1 = nullptr, GSTexture* tex2 = nullptr);
|
||||
void PSSetSamplerState(ID3D11SamplerState* ss0);
|
||||
|
||||
void OMSetDepthStencilState(ID3D11DepthStencilState* dss, u8 sref);
|
||||
|
||||
@@ -3903,7 +3903,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
config.rt = backup_rt;
|
||||
if (!date_image)
|
||||
{
|
||||
Console.WriteLn("D3D12: Failed to allocate DATE image, aborting draw.");
|
||||
Console.Warning("D3D12: Failed to allocate DATE image, aborting draw.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8185,7 +8185,7 @@ bool GSRendererHW::CanUseSwPrimRender(bool no_rt, bool no_ds, bool draw_sprite_t
|
||||
|
||||
if (start_bp < dirty_end_bp && end_bp > dirty_start_bp)
|
||||
{
|
||||
if (dirty_start_bp > start_bp || dirty_end_bp < end_bp)
|
||||
if (dirty_start_bp <= start_bp && dirty_end_bp >= end_bp)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -228,19 +228,22 @@ bool GSTextureCache::CanTranslate(u32 bp, u32 bw, u32 spsm, GSVector4i r, u32 db
|
||||
{
|
||||
const GSVector2i src_page_size = GSLocalMemory::m_psm[spsm].pgs;
|
||||
const GSVector2i dst_page_size = GSLocalMemory::m_psm[dpsm].pgs;
|
||||
const u32 src_bw = std::max(1U, bw);
|
||||
const u32 dst_bw = std::max(1U, dbw);
|
||||
const bool block_layout_match = GSLocalMemory::m_psm[spsm].bpp == GSLocalMemory::m_psm[dpsm].bpp;
|
||||
const bool bp_page_aligned_bp = ((bp & ~((1 << 5) - 1)) == bp) || bp == dbp || (block_layout_match && bw == dbw);
|
||||
const bool bp_page_aligned_bp = ((bp & ~((1 << 5) - 1)) == bp) || bp == dbp || (block_layout_match && src_bw == dst_bw);
|
||||
const GSVector4i page_mask(GSVector4i((src_page_size.x - 1), (src_page_size.y - 1)).xyxy());
|
||||
const GSVector4i masked_rect(r & ~page_mask);
|
||||
const int src_pixel_width = static_cast<int>(bw * 64);
|
||||
const int src_pixel_width = src_bw * 64;
|
||||
const int dst_pixel_width = dst_bw * 64;
|
||||
// We can do this if:
|
||||
// The page width matches.
|
||||
// The rect width is less than the width of the destination texture and the height is less than or equal to 1 page high.
|
||||
// The rect width and height is equal to the page size and it covers the width of the incoming bw, so lines are sequential.
|
||||
const bool page_aligned_rect = masked_rect.xyxy().eq(r.xyxy());
|
||||
const bool width_match = ((bw * 64) / src_page_size.x) == ((dbw * 64) / dst_page_size.x);
|
||||
const bool width_match = (src_pixel_width / src_page_size.x) == (dst_pixel_width / dst_page_size.x);
|
||||
const bool sequential_pages = page_aligned_rect && r.x == 0 && r.z == src_pixel_width;
|
||||
const bool single_row = (((bw * 64) / src_page_size.x) <= ((dbw * 64) / dst_page_size.x)) && r.width() <= src_pixel_width && r.height() <= src_page_size.y;
|
||||
const bool single_row = ((src_pixel_width / src_page_size.x) <= (dst_pixel_width / dst_page_size.x)) && r.width() <= src_pixel_width && r.height() <= src_page_size.y;
|
||||
const bool single_page_aligned = page_aligned_rect && r.z <= src_page_size.x && r.w <= src_page_size.y;
|
||||
if (block_layout_match)
|
||||
{
|
||||
@@ -300,7 +303,7 @@ GSVector4i GSTextureCache::TranslateAlignedRectByPage(u32 tbp, u32 tebp, u32 tbw
|
||||
return GSVector4i::zero();
|
||||
}
|
||||
|
||||
const bool block_matched_format = s_psm.bpp == t_psm.bpp && (sbw == tbw || sbw == 1);
|
||||
const bool block_matched_format = s_psm.bpp == t_psm.bpp && (clamped_sbw == clamped_tbw || clamped_sbw == 1);
|
||||
// If there is block offset left over, try to adjust to that.
|
||||
if (block_matched_format)
|
||||
{
|
||||
@@ -431,6 +434,8 @@ GSVector4i GSTextureCache::TranslateAlignedRectByPage(u32 tbp, u32 tebp, u32 tbw
|
||||
GSVector4i offset_rect(horizontal_dst_page_offset * t_psm.pgs.x, vertical_dst_page_offset * t_psm.pgs.y);
|
||||
new_rect = in_rect + offset_rect.xyxy();
|
||||
}
|
||||
else
|
||||
new_rect = in_rect;
|
||||
|
||||
if (new_rect.z > dst_bw)
|
||||
{
|
||||
@@ -1320,7 +1325,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
||||
// If the BP is offset in to a page and the format does not match, trying to match up the correct position is very difficult since we don't swizzle.
|
||||
// Tomb Raider Legends does a block level BP in PSMT8 over a C16 target, which is just a nightmare to get right.
|
||||
// Baldurs Gate used to have this too, but now we can translate HW moves inside targets when the format matches.
|
||||
if (((bp & (BLOCKS_PER_PAGE - 1)) != (t->m_TEX0.TBP0 & (BLOCKS_PER_PAGE - 1))) && (bp & (BLOCKS_PER_PAGE - 1)) && !CanTranslate(bp, bw, psm, block_boundary_rect, t->m_TEX0.TBP0, t->m_TEX0.PSM, t->m_TEX0.TBW))
|
||||
if (((bp & (BLOCKS_PER_PAGE - 1)) != (t->m_TEX0.TBP0 & (BLOCKS_PER_PAGE - 1))) && (bp & (BLOCKS_PER_PAGE - 1)))
|
||||
continue;
|
||||
|
||||
const bool width_match = (std::max(64U, bw * 64U) >> GSLocalMemory::m_psm[psm].info.pageShiftX()) ==
|
||||
|
||||
@@ -2475,7 +2475,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
||||
primid_texture = InitPrimDateTexture(colclip_rt ? colclip_rt : config.rt, config.drawarea, config.datm);
|
||||
if (!primid_texture)
|
||||
{
|
||||
Console.WriteLn("GL: Failed to allocate DATE image, aborting draw.");
|
||||
Console.Warning("GL: Failed to allocate DATE image, aborting draw.");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@@ -2585,6 +2585,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
||||
{
|
||||
// Ensure all depth writes are finished before sampling
|
||||
GL_INS("GL: Texture barrier to flush depth or rt before reading");
|
||||
g_perfmon.Put(GSPerfMon::Barriers, 1);
|
||||
glTextureBarrier();
|
||||
}
|
||||
// additional non-pipeline config stuff
|
||||
@@ -2607,7 +2608,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
||||
}
|
||||
}
|
||||
|
||||
if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking)
|
||||
if (primid_texture)
|
||||
{
|
||||
GL_PUSH("Destination Alpha PrimID Init");
|
||||
|
||||
|
||||
@@ -5630,7 +5630,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
||||
date_image = SetupPrimitiveTrackingDATE(config);
|
||||
if (!date_image)
|
||||
{
|
||||
Console.WriteLn("VK: Failed to allocate DATE image, aborting draw.");
|
||||
Console.Warning("VK: Failed to allocate DATE image, aborting draw.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ class Error;
|
||||
#pragma clang diagnostic ignored "-Wnullability-completeness"
|
||||
#pragma clang diagnostic ignored "-Wunused-variable"
|
||||
#pragma clang diagnostic ignored "-Wunused-function"
|
||||
#pragma clang diagnostic ignored "-Wunused-private-field"
|
||||
#endif
|
||||
|
||||
#define VMA_STATIC_VULKAN_FUNCTIONS 1
|
||||
|
||||
@@ -3379,7 +3379,7 @@ void FullscreenUI::DrawSummarySettingsPage()
|
||||
|
||||
for (const std::string& name : Pad::GetInputProfileNames())
|
||||
{
|
||||
options.emplace_back(fmt::format(FSUI_FSTR(name)), (value.has_value() && !value->empty() && value == name) ? true : false);
|
||||
options.emplace_back(name, (value.has_value() && !value->empty() && value == name) ? true : false);
|
||||
names.push_back(std::move(name));
|
||||
}
|
||||
|
||||
@@ -6285,7 +6285,7 @@ void FullscreenUI::PopulateGameListEntryList()
|
||||
case 4: // CRC
|
||||
{
|
||||
if (lhs->crc != rhs->crc)
|
||||
return reverse ? (lhs->crc >= rhs->crc) : (lhs->crc < rhs->crc);
|
||||
return reverse ? (lhs->crc > rhs->crc) : (lhs->crc < rhs->crc);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -6507,24 +6507,46 @@ void FullscreenUI::DrawGameList(const ImVec2& heading_size)
|
||||
|
||||
if (BeginFullscreenColumnWindow(-530.0f, 0.0f, "game_list_info", UIPrimaryDarkColor))
|
||||
{
|
||||
const ImVec2 image_size = LayoutScale(ImVec2(275.0f, 400.0f));
|
||||
ImGui::SetCursorPos(LayoutScale(ImVec2(128.0f, 20.0f)));
|
||||
const float img_padding_y = LayoutScale(20.0f);
|
||||
// Spacing between each text item
|
||||
const float text_spacing_y = LayoutScale(8.0f);
|
||||
// Space between title/serial and details, is in addition to text_spacing_y
|
||||
const float title_padding_below_y = LayoutScale(12.0f);
|
||||
|
||||
// Estimate how much space is needed for text
|
||||
// Do this even when nothing is selected, to ensure cover/icon is in a consistant size/position
|
||||
const float title_detail_height =
|
||||
LayoutScale(LAYOUT_LARGE_FONT_SIZE) + text_spacing_y + // Title
|
||||
LayoutScale(LAYOUT_MEDIUM_FONT_SIZE) + text_spacing_y + // Serial
|
||||
title_padding_below_y +
|
||||
7.0f * (LayoutScale(LAYOUT_MEDIUM_FONT_SIZE) + text_spacing_y) + // File, CRC, Region, Compat, Time/Last Played, Size
|
||||
LayoutScale(12.0f); // Extra padding
|
||||
|
||||
// Limit cover height to avoid pushing text off the screen
|
||||
const ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
// Based on ImGui code for WorkRect, with scrolling logic removed
|
||||
const float window_height = std::trunc(window->InnerRect.GetHeight() - 2.0f * std::max(window->WindowPadding.y, window->WindowBorderSize));
|
||||
|
||||
const float free_height = window_height - title_detail_height;
|
||||
const float img_height = std::min(free_height - 2.0f * img_padding_y, LayoutScale(400.0f));
|
||||
|
||||
const ImVec2 image_size = ImVec2(LayoutScale(275.0f), img_height);
|
||||
ImGui::SetCursorPos(ImVec2(LayoutScale(128.0f), img_padding_y));
|
||||
|
||||
if (selected_entry)
|
||||
DrawGameCover(selected_entry, image_size);
|
||||
else
|
||||
DrawFallbackCover(image_size);
|
||||
|
||||
const float work_width = ImGui::GetCurrentWindow()->WorkRect.GetWidth();
|
||||
constexpr float field_margin_y = 10.0f;
|
||||
constexpr float start_x = 50.0f;
|
||||
float text_y = 440.0f;
|
||||
const float work_width = window->WorkRect.GetWidth();
|
||||
const float start_x = LayoutScale(50.0f);
|
||||
const float text_y = img_height + 2.0f * img_padding_y;
|
||||
float text_width;
|
||||
|
||||
PushPrimaryColor();
|
||||
ImGui::SetCursorPos(LayoutScale(start_x, text_y));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, field_margin_y));
|
||||
ImGui::PushTextWrapPos(LayoutScale(480.0f));
|
||||
ImGui::SetCursorPos(ImVec2(start_x, text_y));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, text_spacing_y));
|
||||
ImGui::PushTextWrapPos(LayoutScale(490.0f));
|
||||
ImGui::BeginGroup();
|
||||
|
||||
if (selected_entry)
|
||||
@@ -6533,6 +6555,8 @@ void FullscreenUI::DrawGameList(const ImVec2& heading_size)
|
||||
ImGui::PushFont(g_large_font);
|
||||
const std::string_view title(std::string_view(selected_entry->GetTitle(true)).substr(0, 37));
|
||||
text_width = ImGui::CalcTextSize(title.data(), title.data() + title.length(), false, work_width).x;
|
||||
if (title.length() != selected_entry->GetTitle(true).length())
|
||||
text_width += ImGui::CalcTextSize("...", nullptr, false, -1.0f).x;
|
||||
ImGui::SetCursorPosX((work_width - text_width) / 2.0f);
|
||||
ImGui::TextWrapped(
|
||||
"%.*s%s", static_cast<int>(title.size()), title.data(), (title.length() == selected_entry->GetTitle(true).length()) ? "" : "...");
|
||||
@@ -6544,7 +6568,7 @@ void FullscreenUI::DrawGameList(const ImVec2& heading_size)
|
||||
text_width = ImGui::CalcTextSize(selected_entry->serial.c_str(), nullptr, false, work_width).x;
|
||||
ImGui::SetCursorPosX((work_width - text_width) / 2.0f);
|
||||
ImGui::TextWrapped("%s", selected_entry->serial.c_str());
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 15.0f);
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + title_padding_below_y);
|
||||
|
||||
// file tile
|
||||
ImGui::TextWrapped("%s", SmallString::from_format(FSUI_FSTR("File: {}"), Path::GetFileName(selected_entry->path)).c_str());
|
||||
@@ -7010,6 +7034,8 @@ void FullscreenUI::DrawGameCover(const GameList::Entry* entry, const ImVec2& siz
|
||||
GSTexture* const icon_texture = GetTextureForGameListEntryType(entry->type, image_square);
|
||||
|
||||
const ImRect image_rect(CenterImage(size, image_square));
|
||||
|
||||
ImGui::SetCursorPos(origin + image_rect.Min);
|
||||
DrawSvgTexture(icon_texture, image_square);
|
||||
}
|
||||
// Pretend the image we drew was the the size passed to us
|
||||
@@ -7052,6 +7078,8 @@ void FullscreenUI::DrawFallbackCover(const ImVec2& size)
|
||||
GSTexture* const icon_texture = GetTextureForGameListEntryType(GameList::EntryType::PS2Disc, image_square);
|
||||
|
||||
const ImRect image_rect(CenterImage(size, image_square));
|
||||
|
||||
ImGui::SetCursorPos(origin + image_rect.Min);
|
||||
DrawSvgTexture(icon_texture, image_square);
|
||||
|
||||
// Pretend the image we drew was the the size passed to us
|
||||
|
||||
@@ -947,12 +947,12 @@ namespace R3000A
|
||||
return 1;
|
||||
|
||||
// maximum allowed size for our buffer before we truncate
|
||||
const unsigned int max_len = 4096;
|
||||
constexpr unsigned int max_len = 4096;
|
||||
char tmp[max_len], tmp2[max_len];
|
||||
char* ptmp = tmp;
|
||||
unsigned int printed_bytes = 0;
|
||||
int remaining_buf = max_len - 1;
|
||||
int n = 1, i = 0, j = 0;
|
||||
unsigned int n = 1, i = 0, j = 0;
|
||||
|
||||
while (fmt[i])
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user