mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-07 16:54:14 +01:00
[d3d8/9] Proper (and age accurate) handling of d3d9.shaderModel = 0
This commit is contained in:
parent
48d24893d4
commit
c6dc7e0939
@ -464,6 +464,7 @@
|
||||
# capabilities that the applicatation queries.
|
||||
#
|
||||
# Supported values:
|
||||
# - 0: Fixed-function only
|
||||
# - 1: Shader Model 1
|
||||
# - 2: Shader Model 2
|
||||
# - 3: Shader Model 3
|
||||
|
@ -19,7 +19,10 @@ namespace dxvk {
|
||||
|
||||
// Max supported shader model is PS 1.4 and VS 1.1
|
||||
pCaps8->VertexShaderVersion = D3DVS_VERSION(1, 1);
|
||||
pCaps8->PixelShaderVersion = D3DPS_VERSION(1, 4);
|
||||
// Late fixed-function capable hardware will advertise VS 1.1
|
||||
// support, but will not advertise any support for PS
|
||||
if (likely(caps9.PixelShaderVersion != D3DPS_VERSION(0, 0)))
|
||||
pCaps8->PixelShaderVersion = D3DPS_VERSION(1, 4);
|
||||
|
||||
// Remove D3D9-specific caps:
|
||||
|
||||
|
@ -58,6 +58,12 @@ namespace dxvk {
|
||||
|
||||
if (m_d3d8Options.batching)
|
||||
m_batcher = new D3D8Batcher(this, GetD3D9());
|
||||
|
||||
d3d9::D3DCAPS9 caps9;
|
||||
HRESULT res = GetD3D9()->GetDeviceCaps(&caps9);
|
||||
|
||||
if (unlikely(SUCCEEDED(res) && caps9.PixelShaderVersion == D3DPS_VERSION(0, 0)))
|
||||
m_isFixedFunctionOnly = true;
|
||||
}
|
||||
|
||||
D3D8Device::~D3D8Device() {
|
||||
@ -1784,8 +1790,8 @@ namespace dxvk {
|
||||
|
||||
// Validate VS version for non-FF shaders
|
||||
if (pFunction != nullptr) {
|
||||
uint32_t majorVersion = (pFunction[0] >> 8) & 0xff;
|
||||
uint32_t minorVersion = pFunction[0] & 0xff;
|
||||
const uint32_t majorVersion = (pFunction[0] >> 8) & 0xff;
|
||||
const uint32_t minorVersion = pFunction[0] & 0xff;
|
||||
|
||||
if (unlikely(majorVersion != 1 || minorVersion > 1)) {
|
||||
Logger::err(str::format("D3D8Device::CreateVertexShader: Unsupported VS version ", majorVersion, ".", minorVersion));
|
||||
@ -2023,10 +2029,10 @@ namespace dxvk {
|
||||
if (unlikely(pFunction == nullptr || pHandle == nullptr))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
uint32_t majorVersion = (pFunction[0] >> 8) & 0xff;
|
||||
uint32_t minorVersion = pFunction[0] & 0xff;
|
||||
const uint32_t majorVersion = (pFunction[0] >> 8) & 0xff;
|
||||
const uint32_t minorVersion = pFunction[0] & 0xff;
|
||||
|
||||
if (unlikely(majorVersion != 1 || minorVersion > 4)) {
|
||||
if (unlikely(m_isFixedFunctionOnly || majorVersion != 1 || minorVersion > 4)) {
|
||||
Logger::err(str::format("D3D8Device::CreatePixelShader: Unsupported PS version ", majorVersion, ".", minorVersion));
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
|
@ -429,6 +429,9 @@ namespace dxvk {
|
||||
// Value of D3DRS_PATCHSEGMENTS
|
||||
float m_patchSegments = 1.0f;
|
||||
|
||||
// Controls fixed-function exclusive mode (no PS support)
|
||||
bool m_isFixedFunctionOnly = false;
|
||||
|
||||
D3D8StateBlock* m_recorder = nullptr;
|
||||
DWORD m_recorderToken = 0;
|
||||
DWORD m_token = 0;
|
||||
|
@ -12,7 +12,7 @@ namespace dxvk {
|
||||
|
||||
// Get the bridge interface to D3D9.
|
||||
if (FAILED(m_d3d9->QueryInterface(__uuidof(IDxvkD3D8InterfaceBridge), (void**)&m_bridge))) {
|
||||
throw DxvkError("D3D8Device: ERROR! Failed to get D3D9 Bridge. d3d9.dll might not be DXVK!");
|
||||
throw DxvkError("D3D8Interface: ERROR! Failed to get D3D9 Bridge. d3d9.dll might not be DXVK!");
|
||||
}
|
||||
|
||||
m_bridge->SetD3D8CompatibilityMode(true);
|
||||
|
@ -26,8 +26,8 @@ extern "C" {
|
||||
if (unlikely(pPixelShader == nullptr)) {
|
||||
errorMessage = "D3D8: ValidatePixelShader: Null pPixelShader";
|
||||
} else {
|
||||
uint32_t majorVersion = (pPixelShader[0] >> 8) & 0xff;
|
||||
uint32_t minorVersion = pPixelShader[0] & 0xff;
|
||||
const uint32_t majorVersion = (pPixelShader[0] >> 8) & 0xff;
|
||||
const uint32_t minorVersion = pPixelShader[0] & 0xff;
|
||||
|
||||
if (unlikely(majorVersion != 1 || minorVersion > 4)) {
|
||||
errorMessage = dxvk::str::format("D3D8: ValidatePixelShader: Unsupported PS version ",
|
||||
@ -69,8 +69,8 @@ extern "C" {
|
||||
if (unlikely(pVertexShader == nullptr)) {
|
||||
errorMessage = "D3D8: ValidateVertexShader: Null pVertexShader";
|
||||
} else {
|
||||
uint32_t majorVersion = (pVertexShader[0] >> 8) & 0xff;
|
||||
uint32_t minorVersion = pVertexShader[0] & 0xff;
|
||||
const uint32_t majorVersion = (pVertexShader[0] >> 8) & 0xff;
|
||||
const uint32_t minorVersion = pVertexShader[0] & 0xff;
|
||||
|
||||
if (unlikely(majorVersion != 1 || minorVersion > 1)) {
|
||||
errorMessage = dxvk::str::format("D3D8: ValidateVertexShader: Unsupported VS version ",
|
||||
|
@ -573,17 +573,22 @@ namespace dxvk {
|
||||
// Max Stream Stride
|
||||
pCaps->MaxStreamStride = 508; // bytes
|
||||
|
||||
const uint32_t majorVersion = options.shaderModel;
|
||||
const uint32_t minorVersion = options.shaderModel != 1 ? 0 : 4;
|
||||
// Late fixed-function capable cards, such as the GeForce 4 MX series,
|
||||
// expose support for VS 1.1, while not advertising any PS support
|
||||
const uint32_t majorVersionVS = options.shaderModel == 0 ? 1 : options.shaderModel;
|
||||
const uint32_t majorVersionPS = options.shaderModel;
|
||||
// Max supported SM1 is VS 1.1 and PS 1.4
|
||||
const uint32_t minorVersionVS = majorVersionVS != 1 ? 0 : 1;
|
||||
const uint32_t minorVersionPS = majorVersionPS != 1 ? 0 : 4;
|
||||
|
||||
// Shader Versions
|
||||
pCaps->VertexShaderVersion = D3DVS_VERSION(majorVersion, minorVersion);
|
||||
pCaps->PixelShaderVersion = D3DPS_VERSION(majorVersion, minorVersion);
|
||||
pCaps->VertexShaderVersion = D3DVS_VERSION(majorVersionVS, minorVersionVS);
|
||||
pCaps->PixelShaderVersion = D3DPS_VERSION(majorVersionPS, minorVersionPS);
|
||||
|
||||
// Max Vertex Shader Const
|
||||
pCaps->MaxVertexShaderConst = MaxFloatConstantsVS;
|
||||
// Max PS1 Value
|
||||
pCaps->PixelShader1xMaxValue = FLT_MAX;
|
||||
pCaps->PixelShader1xMaxValue = options.shaderModel > 0 ? FLT_MAX : 0.0f;
|
||||
// Dev Caps 2
|
||||
pCaps->DevCaps2 = D3DDEVCAPS2_STREAMOFFSET
|
||||
/* | D3DDEVCAPS2_DMAPNPATCH */
|
||||
@ -646,8 +651,8 @@ namespace dxvk {
|
||||
pCaps->PS20Caps.NumInstructionSlots = options.shaderModel >= 2 ? 512 : 256;
|
||||
|
||||
pCaps->VertexTextureFilterCaps = 50332416;
|
||||
pCaps->MaxVShaderInstructionsExecuted = 4294967295;
|
||||
pCaps->MaxPShaderInstructionsExecuted = 4294967295;
|
||||
pCaps->MaxVShaderInstructionsExecuted = options.shaderModel >= 2 ? 4294967295 : 0;
|
||||
pCaps->MaxPShaderInstructionsExecuted = options.shaderModel >= 2 ? 4294967295 : 0;
|
||||
|
||||
pCaps->MaxVertexShader30InstructionSlots = options.shaderModel == 3 ? 32768 : 0;
|
||||
pCaps->MaxPixelShader30InstructionSlots = options.shaderModel == 3 ? 32768 : 0;
|
||||
|
@ -3314,6 +3314,19 @@ namespace dxvk {
|
||||
if (unlikely(ppShader == nullptr))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
const uint32_t majorVersion = (pFunction[0] >> 8) & 0xff;
|
||||
const uint32_t minorVersion = pFunction[0] & 0xff;
|
||||
|
||||
// Late fixed-function capable hardware exposed support for VS 1.1
|
||||
const uint32_t shaderModelVS = m_d3d9Options.shaderModel == 0 ? 1 : m_d3d9Options.shaderModel;
|
||||
|
||||
if (unlikely(majorVersion > shaderModelVS
|
||||
|| (majorVersion == 1 && minorVersion > 1)
|
||||
|| (majorVersion > 1 && minorVersion != 0))) {
|
||||
Logger::err(str::format("D3D9DeviceEx::CreateVertexShader: Unsupported VS version ", majorVersion, ".", minorVersion));
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
DxsoModuleInfo moduleInfo;
|
||||
moduleInfo.options = m_dxsoOptions;
|
||||
|
||||
@ -3678,6 +3691,16 @@ namespace dxvk {
|
||||
if (unlikely(ppShader == nullptr))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
const uint32_t majorVersion = (pFunction[0] >> 8) & 0xff;
|
||||
const uint32_t minorVersion = pFunction[0] & 0xff;
|
||||
|
||||
if (unlikely(majorVersion > m_d3d9Options.shaderModel
|
||||
|| (majorVersion == 1 && minorVersion > 4)
|
||||
|| (majorVersion > 1 && minorVersion != 0))) {
|
||||
Logger::err(str::format("D3D9DeviceEx::CreatePixelShader: Unsupported PS version ", majorVersion, ".", minorVersion));
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
DxsoModuleInfo moduleInfo;
|
||||
moduleInfo.options = m_dxsoOptions;
|
||||
|
||||
|
@ -67,6 +67,9 @@ namespace dxvk {
|
||||
SetProcessDPIAware();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (unlikely(m_d3d9Options.shaderModel == 0))
|
||||
Logger::warn("D3D9InterfaceEx: WARNING! Fixed-function exclusive mode is enabled.");
|
||||
}
|
||||
|
||||
|
||||
|
@ -34,7 +34,7 @@ namespace dxvk {
|
||||
int32_t maxFrameRate;
|
||||
|
||||
/// Set the max shader model the device can support in the caps.
|
||||
int32_t shaderModel;
|
||||
uint32_t shaderModel;
|
||||
|
||||
/// Whether or not to set the process as DPI aware in Windows when the API interface is created.
|
||||
bool dpiAware;
|
||||
|
@ -98,9 +98,6 @@ namespace dxvk {
|
||||
|
||||
DxsoModule module(reader);
|
||||
|
||||
if (module.info().majorVersion() > pDxbcModuleInfo->options.shaderModel)
|
||||
throw DxvkError("GetShaderModule: Out of range of supported shader model");
|
||||
|
||||
if (module.info().shaderStage() != ShaderStage)
|
||||
throw DxvkError("GetShaderModule: Bytecode does not match shader stage");
|
||||
|
||||
|
@ -20,8 +20,6 @@ namespace dxvk {
|
||||
strictPow = options.strictPow;
|
||||
d3d9FloatEmulation = options.d3d9FloatEmulation;
|
||||
|
||||
shaderModel = options.shaderModel;
|
||||
|
||||
invariantPosition = options.invariantPosition;
|
||||
|
||||
forceSamplerTypeSpecConstants = options.forceSamplerTypeSpecConstants;
|
||||
|
@ -25,9 +25,6 @@ namespace dxvk {
|
||||
/// Whether or not we should care about pow(0, 0) = 1
|
||||
bool strictPow;
|
||||
|
||||
/// Max version of shader to support
|
||||
uint32_t shaderModel;
|
||||
|
||||
/// Work around a NV driver quirk
|
||||
/// Fixes flickering/z-fighting in some games.
|
||||
bool invariantPosition;
|
||||
|
Loading…
x
Reference in New Issue
Block a user