@@ -32,6 +32,116 @@ namespace dxvk {
3232
3333 };
3434
35+ class D3D9ShaderConverter : public DxvkIrShaderConverter {
36+
37+ public:
38+
39+ D3D9ShaderConverter (
40+ const DxvkShaderHash& ShaderKey,
41+ const D3D9ShaderOptions& Options,
42+ const void * pShaderBytecode,
43+ size_t BytecodeLength)
44+ : m_key(ShaderKey), m_options(Options) {
45+ m_dxbc.resize (BytecodeLength);
46+ std::memcpy (m_dxbc.data (), pShaderBytecode, BytecodeLength);
47+ }
48+
49+ ~D3D9ShaderConverter () { }
50+
51+ void convertShader (
52+ dxbc_spv::ir::Builder& builder) {
53+ auto debugName = m_key.toString ();
54+
55+ dxbc_spv::sm3::Converter::Options options = { };
56+ options.name = debugName.c_str ();
57+ options.includeDebugNames = true ;
58+ options.fastFloatEmulation = m_options.d3d9FloatEmulation == D3D9FloatEmulation::Enabled;
59+ options.isSWVP = m_options.isSWVP && m_key.stage () == VK_SHADER_STAGE_VERTEX_BIT;
60+
61+ dxbc_spv::util::ByteReader reader (m_dxbc.data (), m_dxbc.size ());
62+
63+ D3D9SpecializationConstantLayout specConstLayout;
64+
65+ dxbc_spv::sm3::Converter converter (reader, specConstLayout, options);
66+
67+ if (!converter.convertShader (builder))
68+ throw DxvkError (str::format (" Failed to convert shader: " , m_key.toString ()));
69+ }
70+
71+ uint32_t determineResourceIndex (
72+ dxbc_spv::ir::ShaderStage stage,
73+ dxbc_spv::ir::ScalarType type,
74+ uint32_t regSpace,
75+ uint32_t regIndex) const {
76+
77+ // D3D9ShaderType has pixel shaders at 1, dxbc_spv has vertex shaders at 1.
78+ D3D9ShaderType shaderType = stage == dxbc_spv::ir::ShaderStage::ePixel
79+ ? D3D9ShaderType::PixelShader
80+ : D3D9ShaderType::VertexShader;
81+
82+ switch (type) {
83+ case dxbc_spv::ir::ScalarType::eCbv:
84+ switch (regIndex) {
85+ case dxbc_spv::sm3::FastSpecConstCbvRegIdx:
86+ return D3D9ShaderResourceMapping::getSpecConstantBufferSlot ();
87+
88+ case dxbc_spv::sm3::PSSharedDataCbvRegIdx: {
89+ if (shaderType == D3D9ShaderType::PixelShader) {
90+ return D3D9ShaderResourceMapping::computeCbvBinding (shaderType,
91+ D3D9ShaderResourceMapping::ConstantBuffers::PSShared);
92+ } else { // case dxbc_spv::sm3::VSClipPlanesCbvRegIdx: (same index)
93+ return D3D9ShaderResourceMapping::computeCbvBinding (shaderType,
94+ D3D9ShaderResourceMapping::ConstantBuffers::VSClipPlanes);
95+ }
96+ }
97+
98+ // the index for the D3D9 constant buffer are is the same for VS and PS */
99+ case dxbc_spv::sm3::FloatIntCbvRegIdx:
100+ return D3D9ShaderResourceMapping::computeCbvBinding (shaderType,
101+ D3D9ShaderResourceMapping::ConstantBuffers::VSConstantBuffer);
102+
103+ case dxbc_spv::sm3::SWVPIntCbvRegIdx:
104+ return D3D9ShaderResourceMapping::computeCbvBinding (shaderType,
105+ D3D9ShaderResourceMapping::ConstantBuffers::VSIntConstantBuffer);
106+
107+ case dxbc_spv::sm3::SWVPBoolCbvRegIdx:
108+ return D3D9ShaderResourceMapping::computeCbvBinding (shaderType,
109+ D3D9ShaderResourceMapping::ConstantBuffers::VSBoolConstantBuffer);
110+
111+ default : break ;
112+ }
113+ break ;
114+
115+ case dxbc_spv::ir::ScalarType::eSrv:
116+ case dxbc_spv::ir::ScalarType::eSampler:
117+ return D3D9ShaderResourceMapping::computeTextureBinding (shaderType, regIndex);
118+
119+ default : break ;
120+ }
121+
122+ Logger::err (str::format (" Missing Resource index. Stage: " , stage, " , regSpace: " , regSpace, " , regIndex: " , regIndex));
123+ return -1u ;
124+ }
125+
126+ void dumpSource (const std::string& path) const {
127+ std::ofstream file (str::topath (str::format (path, " /" , m_key.toString (), " .sm3_dxbc" ).c_str ()).c_str (), std::ios_base::trunc | std::ios_base::binary);
128+ file.write (reinterpret_cast <const char *>(m_dxbc.data ()), m_dxbc.size ());
129+ }
130+
131+ std::string getDebugName () const {
132+ return m_key.toString ();
133+ }
134+
135+ private:
136+
137+ std::vector<uint8_t > m_dxbc;
138+
139+ DxvkShaderHash m_key;
140+
141+ D3D9ShaderOptions m_options;
142+
143+ };
144+
35145 D3D9CommonShader::D3D9CommonShader (
36146 D3D9DeviceEx* pDevice,
37147 const DxvkShaderHash& ShaderKey,
@@ -53,7 +163,10 @@ namespace dxvk {
53163 file.write (reinterpret_cast <const char *>(pShaderBytecode), bytecodeLength);
54164 }
55165
56- CreateLegacyShader (pDevice, ShaderKey, ModuleInfo, pShaderBytecode);
166+ if (pDevice->GetOptions ()->useDxbcSpirv )
167+ CreateIrShader (pDevice, ShaderKey, ModuleInfo, pShaderBytecode, m_analysis.GetLength ());
168+ else
169+ CreateLegacyShader (pDevice, ShaderKey, ModuleInfo, pShaderBytecode);
57170
58171 if (!dumpPath.empty ()) {
59172 std::ofstream dumpStream (
@@ -66,6 +179,25 @@ namespace dxvk {
66179 }
67180
68181
182+ void D3D9CommonShader::CreateIrShader (
183+ D3D9DeviceEx* pDevice,
184+ const DxvkShaderHash& ShaderKey,
185+ const D3D9ShaderCreateInfo& ModuleInfo,
186+ const void * pShaderBytecode,
187+ size_t BytecodeLength) {
188+ m_shader = pDevice->GetDXVKDevice ()->createCachedShader (
189+ ShaderKey.toString (), ModuleInfo.irCreateInfo , nullptr );
190+
191+ if (!m_shader) {
192+ Rc<D3D9ShaderConverter> converter = new D3D9ShaderConverter (ShaderKey, ModuleInfo.shaderOptions ,
193+ pShaderBytecode, BytecodeLength);
194+
195+ m_shader = pDevice->GetDXVKDevice ()->createCachedShader (
196+ ShaderKey.toString (), ModuleInfo.irCreateInfo , std::move (converter));
197+ }
198+ }
199+
200+
69201 void D3D9CommonShader::CreateLegacyShader (
70202 D3D9DeviceEx* pDevice,
71203 const DxvkShaderHash& ShaderKey,
0 commit comments