Skip to content

Commit

Permalink
[d3d8] Add an option to respect DISCARD only for dynamic write-only b…
Browse files Browse the repository at this point in the history
…uffers
  • Loading branch information
WinterSnowfall authored and doitsujin committed Sep 26, 2024
1 parent 4fad20d commit a7b3b1e
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/d3d8/d3d8_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,21 @@ namespace dxvk {
: D3D8Resource<D3D9, D3D8> (pDevice, std::move(pBuffer))
, m_pool (Pool)
, m_usage (Usage) {
m_options = this->GetParent()->GetOptions();
}

HRESULT STDMETHODCALLTYPE Lock(
UINT OffsetToLock,
UINT SizeToLock,
BYTE** ppbData,
DWORD Flags) {

if (m_options->forceLegacyDiscard &&
(Flags & D3DLOCK_DISCARD) &&
!((m_usage & D3DUSAGE_DYNAMIC) &&
(m_usage & D3DUSAGE_WRITEONLY)))
Flags &= ~D3DLOCK_DISCARD;

return this->GetD3D9()->Lock(
OffsetToLock,
SizeToLock,
Expand All @@ -41,8 +49,9 @@ namespace dxvk {
}

protected:
const D3DPOOL m_pool;
const DWORD m_usage;
const D3D8Options* m_options;
const D3DPOOL m_pool;
const DWORD m_usage;
};


Expand Down
4 changes: 4 additions & 0 deletions src/d3d8/d3d8_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,10 @@ namespace dxvk {

public: // Internal Methods //

const D3D8Options* GetOptions() const {
return &m_d3d8Options;
}

inline bool ShouldRecord() { return m_recorder != nullptr; }
inline bool ShouldBatch() { return m_batcher != nullptr; }

Expand Down
8 changes: 8 additions & 0 deletions src/d3d8/d3d8_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,19 @@ namespace dxvk {
/// and above. Most likely ATI/AMD drivers never supported P8 in the first place.
bool placeP8InScratch = false;

/// Rayman 3 relies on D3DLOCK_DISCARD being ignored for everything except D3DUSAGE_DYNAMIC +
/// D3DUSAGE_WRITEONLY buffers, however this approach incurs a performance penalty.
///
/// Some titles might abuse this early D3D8 quirk, however at some point in its history
/// it was brought in line with standard D3D9 behavior.
bool forceLegacyDiscard = false;

D3D8Options() {}
D3D8Options(const Config& config) {
auto forceVsDeclStr = config.getOption<std::string>("d3d8.forceVsDecl", "");
batching = config.getOption<bool> ("d3d8.batching", batching);
placeP8InScratch = config.getOption<bool> ("d3d8.placeP8InScratch", placeP8InScratch);
forceLegacyDiscard = config.getOption<bool> ("d3d8.forceLegacyDiscard", forceLegacyDiscard);

parseVsDecl(forceVsDeclStr);
}
Expand Down

0 comments on commit a7b3b1e

Please sign in to comment.