Skip to content

Commit 0bf6806

Browse files
committed
Usage of unused render states for special game scenarios
- use unused RenderState 42 to assign a remix texture category for the next surface - use unused RenderState 150 to set a custom material hash for the next surface - add hidden remix option 'useUnusedRenderstates' (default: false) to enable usage of unused render states
1 parent 912a164 commit 0bf6806

File tree

4 files changed

+31
-4
lines changed

4 files changed

+31
-4
lines changed

src/d3d9/d3d9_rtx_utils.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@ namespace dxvk {
176176

177177
materialData.alphaBlendEnabled = d3d9State.renderStates[D3DRS_ALPHABLENDENABLE] != FALSE;
178178

179+
if (RtxOptions::Get()->useUnusedRenderstates()) {
180+
materialData.remixTextureCategoryFlagsFromD3D = d3d9State.renderStates[42] != 0xfefefefe ? d3d9State.renderStates[42] : 0u; // D3DRENDERSTATETYPE index 42 is not in use - unused values are set to 0xfefefefe
181+
182+
if (d3d9State.renderStates[150] != 0 && d3d9State.renderStates[150] != 0xfefefefe) { // D3DRENDERSTATETYPE index 150 is not in use - unused values are set to 0xfefefefe
183+
materialData.setHashOverride(d3d9State.renderStates[150]);
184+
}
185+
}
186+
179187
if (materialData.alphaBlendEnabled) {
180188
D3D9BlendState color;
181189
color.Src = D3DBLEND(d3d9State.renderStates[D3DRS_SRCBLEND]);

src/dxvk/rtx_render/rtx_materials.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -1451,9 +1451,15 @@ struct LegacyMaterialData {
14511451
uint32_t tFactor = 0xffffffff; // Value for D3DRS_TEXTUREFACTOR, default value of is opaque white
14521452
D3DMATERIAL9 d3dMaterial = {};
14531453
bool isTextureFactorBlend = false;
1454+
uint32_t remixTextureCategoryFlagsFromD3D = 0u;
14541455

14551456
void setHashOverride(XXH64_hash_t hash) {
14561457
m_cachedHash = hash;
1458+
m_isHashOverridden = true;
1459+
}
1460+
1461+
bool isHashOverridden() const {
1462+
return m_isHashOverridden;
14571463
}
14581464

14591465
private:
@@ -1468,7 +1474,9 @@ struct LegacyMaterialData {
14681474
// incorporate more textures used to identify a material uniquely. Note this is not the same as the
14691475
// plain data hash used by the RtSurfaceMaterial for storage in map-like data structures, but rather
14701476
// one used to identify a material and compare to user-provided hashes.
1471-
m_cachedHash = colorTextures[0].getImageHash();
1477+
if (!m_isHashOverridden) {
1478+
m_cachedHash = colorTextures[0].getImageHash();
1479+
}
14721480
}
14731481

14741482
const static uint32_t kMaxSupportedTextures = 2;
@@ -1478,6 +1486,7 @@ struct LegacyMaterialData {
14781486
uint32_t colorTextureSlot[kMaxSupportedTextures] = { kInvalidResourceSlot };
14791487

14801488
XXH64_hash_t m_cachedHash = kEmptyHash;
1489+
bool m_isHashOverridden = false;
14811490
};
14821491

14831492
struct MaterialData {

src/dxvk/rtx_render/rtx_options.h

+3
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,9 @@ namespace dxvk {
989989
RTX_OPTION("rtx", float, effectLightRadius, 5.f, "");
990990
RTX_OPTION("rtx", bool, effectLightPlasmaBall, false, "");
991991

992+
RTX_OPTION("rtx", bool, useUnusedRenderstates, false, "Enable usage of unused D3D renderstates to aid with special game scenarios whilst having game code access.\n"
993+
"(RS 42) Setting the remix texture category for the next surface. (RS 150) Setting a user defined material hash for the next surface.");
994+
992995
RTX_OPTION("rtx", bool, useObsoleteHashOnTextureUpload, false,
993996
"Whether or not to use slower XXH64 hash on texture upload.\n"
994997
"New projects should not enable this option as this solely exists for compatibility with older hashing schemes.");

src/dxvk/rtx_render/rtx_types.cpp

+10-3
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ namespace dxvk {
133133
// than doing N lookups per texture hash for each category.
134134
const XXH64_hash_t& textureHash = materialData.getColorTexture().getImageHash();
135135

136+
if (RtxOptions::Get()->useUnusedRenderstates()) {
137+
categories = CategoryFlags(materialData.remixTextureCategoryFlagsFromD3D);
138+
}
139+
136140
setCategory(InstanceCategories::WorldUI, lookupHash(RtxOptions::worldSpaceUiTextures(), textureHash));
137141
setCategory(InstanceCategories::WorldMatte, lookupHash(RtxOptions::worldSpaceUiBackgroundTextures(), textureHash));
138142

@@ -297,9 +301,12 @@ namespace dxvk {
297301
return true;
298302
}
299303

300-
// NOTE: we use color texture hash for sky detection, however the replacement is hashed with
301-
// the whole legacy material hash (which, as of 12/9/2022, equals to color texture hash). Adding a check just in case.
302-
assert(drawCallState.getMaterialData().getColorTexture().getImageHash() == drawCallState.getMaterialData().getHash() && "Texture or material hash method changed!");
304+
// NOTE: disable assert if material is using a custom hash that was set via an unused D3D RenderState
305+
if (!drawCallState.getMaterialData().isHashOverridden()) {
306+
// NOTE: we use color texture hash for sky detection, however the replacement is hashed with
307+
// the whole legacy material hash (which, as of 12/9/2022, equals to color texture hash). Adding a check just in case.
308+
assert(drawCallState.getMaterialData().getColorTexture().getImageHash() == drawCallState.getMaterialData().getHash() && "Texture or material hash method changed!");
309+
}
303310

304311
if (drawCallState.getMaterialData().usesTexture()) {
305312
if (lookupHash(RtxOptions::skyBoxTextures(), drawCallState.getMaterialData().getHash())) {

0 commit comments

Comments
 (0)