diff --git a/Build Release.bat b/Build Release.bat index c46d364f2..66d50a41a 100644 --- a/Build Release.bat +++ b/Build Release.bat @@ -2,7 +2,7 @@ RMDIR dist /S /Q -cmake -S . --preset=FLATRIM --check-stamp-file "build\CMakeFiles\generate.stamp" +cmake -S . --preset=VR --check-stamp-file "build\CMakeFiles\generate.stamp" if %ERRORLEVEL% NEQ 0 exit 1 cmake --build build --config Release if %ERRORLEVEL% NEQ 0 exit 1 diff --git a/cmake/ports/.gitkeep b/cmake/ports/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/extern/CommonLibSSE-NG b/extern/CommonLibSSE-NG index b9cd5ba8b..1abf78d62 160000 --- a/extern/CommonLibSSE-NG +++ b/extern/CommonLibSSE-NG @@ -1 +1 @@ -Subproject commit b9cd5ba8b8b9df5eecac5574efd291341e914eb6 +Subproject commit 1abf78d62b6e502f4461793a911eca9e1c44175c diff --git a/package/Shaders/RunGrass.hlsl b/package/Shaders/RunGrass.hlsl index a62930f2b..72981fd5d 100644 --- a/package/Shaders/RunGrass.hlsl +++ b/package/Shaders/RunGrass.hlsl @@ -8,6 +8,7 @@ struct VS_INPUT float4 InstanceData2 : TEXCOORD5; float4 InstanceData3 : TEXCOORD6; float4 InstanceData4 : TEXCOORD7; + uint InstanceID : SV_InstanceID0; }; struct VS_OUTPUT @@ -22,31 +23,15 @@ struct VS_OUTPUT #endif float4 WorldPosition : POSITION1; float4 PreviousWorldPosition : POSITION2; + float o7 : SV_ClipDistance0; + float p7 : SV_CullDistance0; }; #ifdef VSHADER -cbuffer PerGeometry : register(b2) -{ - row_major float4x4 WorldViewProj : packoffset(c0); - row_major float4x4 WorldView : packoffset(c4); - row_major float4x4 World : packoffset(c8); - row_major float4x4 PreviousWorld : packoffset(c12); - float4 FogNearColor : packoffset(c16); - float3 WindVector : packoffset(c17); - float WindTimer : packoffset(c17.w); - float3 DirLightDirection : packoffset(c18); - float PreviousWindTimer : packoffset(c18.w); - float3 DirLightColor : packoffset(c19); - float AlphaParam1 : packoffset(c19.w); - float3 AmbientColor : packoffset(c20); - float AlphaParam2 : packoffset(c20.w); - float3 ScaleMask : packoffset(c21); - float ShadowClampValue : packoffset(c21.w); -} -cbuffer cb7 : register(b7) -{ - float4 cb7[1]; +cbuffer cb7 : register(b7) +{ + float4 cb7[1]; } cbuffer cb8 : register(b8) @@ -54,6 +39,27 @@ cbuffer cb8 : register(b8) float4 cb8[240]; } +cbuffer PerGeometry : register(b2) +{ + float4 cb2[32] : packoffset(c0); + float4 FogNearColor : packoffset(c32); + float3 WindVector : packoffset(c33); + float WindTimer : packoffset(c33.w); + float3 DirLightDirection : packoffset(c34); + float PreviousWindTimer : packoffset(c34.w); + float3 DirLightColor : packoffset(c35); + float AlphaParam1 : packoffset(c35.w); + float3 AmbientColor : packoffset(c36); + float AlphaParam2 : packoffset(c36.w); + float3 ScaleMask : packoffset(c37); + float ShadowClampValue : packoffset(c37.w); +} + +cbuffer cb13 : register(b13) +{ + float4 cb13[3]; +} + #define M_PI 3.1415925 // PI #define M_2PI 6.283185 // PI * 2 @@ -98,10 +104,24 @@ VS_OUTPUT main(VS_INPUT input) { VS_OUTPUT vsout; + float4 r0,r1,r2,r3,r4,r5,r6; + uint4 bitmask, uiDest; + float4 fDest; + + r0.x = (int)input.InstanceID & 1; + r0.x = (uint)r0.x; + r0.x = cb13[0].y * r0.x; + r0.x = (uint)r0.x; + r0.z = (uint)r0.x << 2; + r0.y = (uint)r0.x << 2; + float4 msPosition = GetMSPosition(input, WindTimer); - float4 projSpacePosition = mul(WorldViewProj, msPosition); - vsout.HPosition = projSpacePosition; + float4 projSpacePosition; + projSpacePosition.x = dot(cb2[r0.z+0].xyzw, msPosition.xyzw); + projSpacePosition.y = dot(cb2[r0.z+1].xyzw, msPosition.xyzw); + projSpacePosition.z = dot(cb2[r0.z+2].xyzw, msPosition.xyzw); + projSpacePosition.w = dot(cb2[r0.z+3].xyzw, msPosition.xyzw); #if defined(RENDER_DEPTH) vsout.Depth = projSpacePosition.zw; @@ -123,12 +143,38 @@ VS_OUTPUT main(VS_INPUT input) vsout.AmbientColor.xyz = input.InstanceData1.www * (AmbientColor.xyz * input.Color.xyz); vsout.AmbientColor.w = ShadowClampValue; - vsout.ViewSpacePosition = mul(WorldView, msPosition).xyz; - vsout.WorldPosition = mul(World, msPosition); + vsout.WorldPosition.x = dot(cb2[r0.z+16].xyzw, msPosition.xyzw); + vsout.WorldPosition.y = dot(cb2[r0.z+17].xyzw, msPosition.xyzw); + vsout.WorldPosition.z = dot(cb2[r0.z+18].xyzw, msPosition.xyzw); + vsout.WorldPosition.w = dot(cb2[r0.z+19].xyzw, msPosition.xyzw); float4 previousMsPosition = GetMSPosition(input, PreviousWindTimer); + + vsout.PreviousWorldPosition.x = dot(cb2[r0.z+24].xyzw, previousMsPosition.xyzw); + vsout.PreviousWorldPosition.y = dot(cb2[r0.z+25].xyzw, previousMsPosition.xyzw); + vsout.PreviousWorldPosition.z = dot(cb2[r0.z+26].xyzw, previousMsPosition.xyzw); + vsout.PreviousWorldPosition.w = dot(cb2[r0.z+27].xyzw, previousMsPosition.xyzw); + + vsout.ViewSpacePosition.x = dot(cb2[r0.z+8].xyzw, msPosition.xyzw); + vsout.ViewSpacePosition.y = dot(cb2[r0.z+9].xyzw, msPosition.xyzw); + vsout.ViewSpacePosition.z = dot(cb2[r0.z+10].xyzw, msPosition.xyzw); + + if (0 < cb13[0].y) { + r0.yz = dot(projSpacePosition, cb13[r0.x+1].xyzw); + } else { + r0.yz = float2(1,1); + } + + r0.w = 2 + -cb13[0].y; + r0.x = dot(cb13[0].zw, M_IdentityMatrix[r0.x+0].xy); + r0.xw = r0.xw * projSpacePosition.wx; + r0.x = cb13[0].y * r0.x; + + vsout.HPosition.x = r0.w * 0.5 + r0.x; + vsout.HPosition.yzw = projSpacePosition.yzw; - vsout.PreviousWorldPosition = mul(PreviousWorld, previousMsPosition); + vsout.o7.x = r0.z; + vsout.p7.x = r0.y; return vsout; } @@ -154,18 +200,27 @@ SamplerState SampShadowMaskSampler : register(s1); Texture2D TexBaseSampler : register(t0); Texture2D TexShadowMaskSampler : register(t1); -cbuffer AlphaTestRefCB : register(b11) +cbuffer AlphaTestRefCB : register(b13) { float AlphaTestRefRS : packoffset(c0); } -cbuffer PerFrame : register(b12) +cbuffer cb0 : register(b0) { - float4 UnknownPerFrame1[12] : packoffset(c0); - row_major float4x4 ScreenProj : packoffset(c12); - row_major float4x4 PreviousScreenProj : packoffset(c16); + float4 cb0[10]; +} + +struct PerEye +{ + row_major float4x4 ScreenProj; + row_major float4x4 PreviousScreenProj; }; +cbuffer cb12 : register(b12) +{ + float4 cb12[87]; +} + PS_OUTPUT main(PS_INPUT input) { PS_OUTPUT psout; @@ -195,12 +250,24 @@ PS_OUTPUT main(PS_INPUT input) psout.Albedo.xyz = input.TexCoord.zzz * (diffuseColor * diffuseFraction + ambientColor); psout.Albedo.w = 1; - float4 screenPosition = mul(ScreenProj, input.WorldPosition); - screenPosition.xy = screenPosition.xy / screenPosition.ww; - float4 previousScreenPosition = mul(PreviousScreenProj, input.PreviousWorldPosition); - previousScreenPosition.xy = previousScreenPosition.xy / previousScreenPosition.ww; - float2 screenMotionVector = float2(-0.5, 0.5) * (screenPosition.xy - previousScreenPosition.xy); + float stereoUV = input.HPosition.x * cb0[9].x + cb0[9].z; + stereoUV = stereoUV * cb12[86].x; + + uint eyeIndex = (stereoUV >= 0.5); + + float3 screenPosition; + screenPosition.x = dot(cb12[eyeIndex+24].xyzw, input.WorldPosition); + screenPosition.y = dot(cb12[eyeIndex+25].xyzw, input.WorldPosition); + screenPosition.z = dot(cb12[eyeIndex+27].xyzw, input.WorldPosition); + screenPosition.xy = screenPosition.xy / screenPosition.zz; + float3 previousScreenPosition; + previousScreenPosition.x = dot(cb12[eyeIndex+32].xyzw, input.PreviousWorldPosition); + previousScreenPosition.y = dot(cb12[eyeIndex+33].xyzw, input.PreviousWorldPosition); + previousScreenPosition.z = dot(cb12[eyeIndex+35].xyzw, input.PreviousWorldPosition); + previousScreenPosition.xy = previousScreenPosition.xy / previousScreenPosition.zz; + + float2 screenMotionVector = float2(-0.5, 0.5) * (screenPosition.xy - previousScreenPosition.xy); psout.MotionVectors = screenMotionVector; float3 ddx = ddx_coarse(input.ViewSpacePosition); @@ -209,6 +276,7 @@ PS_OUTPUT main(PS_INPUT input) float normalScale = max(1.0 / 1000.0, sqrt(normal.z * -8 + 8)); psout.Normal.xy = float2(0.5, 0.5) + normal.xy / normalScale; psout.Normal.zw = float2(0, 0); + #endif return psout; diff --git a/src/Buffer.h b/src/Buffer.h index 30dfb508f..c84a1791b 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -9,6 +9,7 @@ #include "RE/BSGraphics.h" #include "RE/BSGraphicsTypes.h" +#include "RE/R/Renderer.h" template D3D11_BUFFER_DESC StructuredBufferDesc(uint64_t count, bool uav = true, bool dynamic = false) @@ -48,7 +49,7 @@ class ConstantBuffer ConstantBuffer(D3D11_BUFFER_DESC const& a_desc) { desc = a_desc; - auto device = RE::BSRenderManager::GetSingleton()->GetRuntimeData().forwarder; + auto device = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().forwarder; DX::ThrowIfFailed(device->CreateBuffer(&desc, nullptr, resource.ReleaseAndGetAddressOf())); } @@ -56,7 +57,7 @@ class ConstantBuffer void Update(void const* src_data, size_t data_size) { - ID3D11DeviceContext* ctx = RE::BSRenderManager::GetSingleton()->GetRuntimeData().context; + ID3D11DeviceContext* ctx = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().context; if (desc.Usage & D3D11_USAGE_DYNAMIC) { D3D11_MAPPED_SUBRESOURCE mapped_buffer{}; ZeroMemory(&mapped_buffer, sizeof(D3D11_MAPPED_SUBRESOURCE)); @@ -85,7 +86,7 @@ class StructuredBuffer { desc = a_desc; count = a_count; - auto device = RE::BSRenderManager::GetSingleton()->GetRuntimeData().forwarder; + auto device = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().forwarder; DX::ThrowIfFailed(device->CreateBuffer(&desc, nullptr, resource.ReleaseAndGetAddressOf())); } @@ -94,7 +95,7 @@ class StructuredBuffer virtual void CreateSRV() { - ID3D11Device* device = RE::BSRenderManager::GetSingleton()->GetRuntimeData().forwarder; + ID3D11Device* device = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().forwarder; D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc{}; srv_desc.Format = DXGI_FORMAT_UNKNOWN; srv_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX; @@ -107,7 +108,7 @@ class StructuredBuffer virtual void CreateUAV() { - ID3D11Device* device = RE::BSRenderManager::GetSingleton()->GetRuntimeData().forwarder; + ID3D11Device* device = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().forwarder; D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc{}; uav_desc.Format = DXGI_FORMAT_UNKNOWN; uav_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; @@ -121,7 +122,7 @@ class StructuredBuffer void Update(void const* src_data, [[maybe_unused]] size_t data_size) { - ID3D11DeviceContext* ctx = RE::BSRenderManager::GetSingleton()->GetRuntimeData().context; + ID3D11DeviceContext* ctx = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().context; D3D11_MAPPED_SUBRESOURCE mapped_buffer{}; ZeroMemory(&mapped_buffer, sizeof(D3D11_MAPPED_SUBRESOURCE)); DX::ThrowIfFailed(ctx->Map(resource.Get(), 0u, D3D11_MAP_WRITE_DISCARD, 0u, &mapped_buffer)); @@ -148,18 +149,18 @@ class Buffer Buffer(D3D11_BUFFER_DESC const& a_desc, D3D11_SUBRESOURCE_DATA* a_init = nullptr) { desc = a_desc; - auto device = RE::BSRenderManager::GetSingleton()->GetRuntimeData().forwarder; + auto device = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().forwarder; DX::ThrowIfFailed(device->CreateBuffer(&desc, a_init, resource.put())); } void CreateSRV(D3D11_SHADER_RESOURCE_VIEW_DESC const& a_desc) { - ID3D11Device* device = RE::BSRenderManager::GetSingleton()->GetRuntimeData().forwarder; + ID3D11Device* device = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().forwarder; DX::ThrowIfFailed(device->CreateShaderResourceView(resource.get(), &a_desc, srv.put())); } void CreateUAV(D3D11_UNORDERED_ACCESS_VIEW_DESC const& a_desc) { - ID3D11Device* device = RE::BSRenderManager::GetSingleton()->GetRuntimeData().forwarder; + ID3D11Device* device = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().forwarder; DX::ThrowIfFailed(device->CreateUnorderedAccessView(resource.get(), &a_desc, uav.put())); } @@ -175,18 +176,18 @@ class Texture2D Texture2D(D3D11_TEXTURE2D_DESC const& a_desc) { desc = a_desc; - auto device = RE::BSRenderManager::GetSingleton()->GetRuntimeData().forwarder; + auto device = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().forwarder; DX::ThrowIfFailed(device->CreateTexture2D(&desc, nullptr, resource.put())); } void CreateSRV(D3D11_SHADER_RESOURCE_VIEW_DESC const& a_desc) { - ID3D11Device* device = RE::BSRenderManager::GetSingleton()->GetRuntimeData().forwarder; + ID3D11Device* device = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().forwarder; DX::ThrowIfFailed(device->CreateShaderResourceView(resource.get(), &a_desc, srv.put())); } void CreateUAV(D3D11_UNORDERED_ACCESS_VIEW_DESC const& a_desc) { - ID3D11Device* device = RE::BSRenderManager::GetSingleton()->GetRuntimeData().forwarder; + ID3D11Device* device = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().forwarder; DX::ThrowIfFailed(device->CreateUnorderedAccessView(resource.get(), &a_desc, uav.put())); } diff --git a/src/Features/Clustered.cpp b/src/Features/Clustered.cpp index c4fdb62e0..badde2fda 100644 --- a/src/Features/Clustered.cpp +++ b/src/Features/Clustered.cpp @@ -14,11 +14,11 @@ void Clustered::Bind(bool a_update) } if (lights) { - auto context = RE::BSRenderManager::GetSingleton()->GetRuntimeData().context; - auto renderer = BSGraphics::Renderer::QInstance(); + auto renderer = RE::BSGraphics::Renderer::GetSingleton(); + auto context = renderer->GetRuntimeData().context; ID3D11ShaderResourceView* views[2]{}; - views[0] = lights->srv.get(); - views[1] = renderer->pDepthStencils[DEPTH_STENCIL_POST_ZPREPASS_COPY].DepthSRV; + views[0] = lights.get()->srv.get(); + views[1] = renderer->GetDepthStencilData().depthStencils[RE::RENDER_TARGET_DEPTHSTENCIL::kPOST_ZPREPASS_COPY].depthSRV; context->PSSetShaderResources(17, ARRAYSIZE(views), views); } } @@ -27,13 +27,62 @@ void Clustered::UpdateLights() { std::uint32_t currentLightCount = 0; // Max number of lights is 4294967295 - auto accumulator = BSGraphics::BSShaderAccumulator::GetCurrentAccumulator(); - auto shadowSceneNode = accumulator->m_ActiveShadowSceneNode; - auto state = BSGraphics::RendererShadowState::QInstance(); + auto accumulator = RE::BSGraphics::BSShaderAccumulator::GetCurrentAccumulator(); + + //auto shadowSceneNode = RE::BSShaderManager::State::GetSingleton().shadowSceneNode[0]; + auto shadowSceneNode = accumulator->GetRuntimeData().activeShadowSceneNode; + auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); std::vector lights_data{}; - for (auto& e : shadowSceneNode->GetRuntimeData().activePointLights) { + auto& runtimeData = shadowSceneNode->GetRuntimeData(); + auto processLights = [&](RE::NiLight* niLight, RE::BSLight* bsLight, RE::BSShadowLight* bsShadowLight) { + RE::NiPoint3 worldPos = niLight->world.translate; + + float lodDimmer = 0; + if (bsLight) + lodDimmer = bsLight->lodDimmer; + else if (bsShadowLight) + lodDimmer = bsShadowLight->lodDimmer; + float dimmer = niLight->GetLightRuntimeData().fade * lodDimmer; + logger::trace("Found {}light {} at ({} {} {})", bsShadowLight ? "shadow" : "", niLight->name, worldPos.x, worldPos.y, worldPos.z); + + LightSData light{}; + + DirectX::XMFLOAT3 color{}; + color.x = dimmer * niLight->GetLightRuntimeData().diffuse.red; + color.y = dimmer * niLight->GetLightRuntimeData().diffuse.green; + color.z = dimmer * niLight->GetLightRuntimeData().diffuse.blue; + light.color = XMLoadFloat3(&color); + + RE::NiPoint3 eyePosition{}; + if (REL::Module::IsVR()) { + // find center of eye position + eyePosition = state->GetVRRuntimeData2().posAdjust.getEye() + state->GetVRRuntimeData2().posAdjust.getEye(1); + eyePosition /= 2; + } else + eyePosition = state->GetRuntimeData2().posAdjust.getEye(); + + worldPos = worldPos - eyePosition; + logger::trace("Set {}light {} at ({} {} {}) because of eye ({} {} {})", bsShadowLight ? "shadow" : "", niLight->name, worldPos.x, worldPos.y, worldPos.z, + eyePosition.x, eyePosition.y, eyePosition.z); + + DirectX::XMFLOAT3 position{}; + position.x = worldPos.x; + position.y = worldPos.y; + position.z = worldPos.z; + light.positionWS = XMLoadFloat3(&position); + light.positionVS = XMVector3TransformCoord(light.positionWS, state->GetVRRuntimeData2().cameraData.getEye().viewMat); + + light.radius = niLight->GetLightRuntimeData().radius.x; + + light.active = true; + light.shadow = (bool)bsShadowLight; + light.mask = bsShadowLight ? (float)bsShadowLight->maskSelect : -1; + lights_data.push_back(light); + currentLightCount++; + }; + for (auto& e : runtimeData.activePointLights) { if (auto bsLight = e.get()) { if (auto niLight = bsLight->light.get()) { // See ShadowSceneNode::GetLuminanceAtPoint_1412BC190 @@ -66,71 +115,17 @@ void Clustered::UpdateLights() continue; } - RE::NiPoint3 worldPos = niLight->world.translate; - float dimmer = niLight->GetLightRuntimeData().fade * bsLight->lodDimmer; - - LightSData light{}; - - DirectX::XMFLOAT3 color{}; - color.x = dimmer * niLight->GetLightRuntimeData().diffuse.red; - color.y = dimmer * niLight->GetLightRuntimeData().diffuse.green; - color.z = dimmer * niLight->GetLightRuntimeData().diffuse.blue; - light.color = XMLoadFloat3(&color); - - worldPos = worldPos - BSGraphics::RendererShadowState::QInstance()->m_PosAdjust; - - DirectX::XMFLOAT3 position{}; - position.x = worldPos.x; - position.y = worldPos.y; - position.z = worldPos.z; - light.positionWS = XMLoadFloat3(&position); - light.positionVS = XMVector3TransformCoord(light.positionWS, state->m_CameraData.m_ViewMat); - - light.radius = niLight->GetLightRuntimeData().radius.x; - - light.active = true; - light.shadow = false; - light.mask = -1; - - lights_data.push_back(light); - currentLightCount++; + processLights(niLight, bsLight, nullptr); } } } // See ShadowSceneNode::CalculateActiveShadowCasterLights_1412E2F60 // Whilst there is another shadow caster list, it includes ones that aren't being used due to the shadow caster limit. - for (auto& e : shadowSceneNode->GetRuntimeData().activeShadowLights) { + for (auto& e : runtimeData.activeShadowLights) { if (auto bsShadowLight = (RE::BSShadowLight*)e.get()) { - if (auto& niLight = bsShadowLight->light) { - RE::NiPoint3 worldPos = niLight->world.translate; - float dimmer = niLight->GetLightRuntimeData().fade * bsShadowLight->lodDimmer; - - LightSData light{}; - - DirectX::XMFLOAT3 color{}; - color.x = dimmer * niLight->GetLightRuntimeData().diffuse.red; - color.y = dimmer * niLight->GetLightRuntimeData().diffuse.green; - color.z = dimmer * niLight->GetLightRuntimeData().diffuse.blue; - light.color = XMLoadFloat3(&color); - - worldPos = worldPos - BSGraphics::RendererShadowState::QInstance()->m_PosAdjust; - - DirectX::XMFLOAT3 position{}; - position.x = worldPos.x; - position.y = worldPos.y; - position.z = worldPos.z; - light.positionWS = XMLoadFloat3(&position); - light.positionVS = XMVector3TransformCoord(light.positionWS, state->m_CameraData.m_ViewMat); - - light.radius = niLight->GetLightRuntimeData().radius.x; - - light.active = true; - light.shadow = true; - light.mask = (float)bsShadowLight->maskSelect; - - lights_data.push_back(light); - currentLightCount++; + if (auto niLight = bsShadowLight->light.get()) { + processLights(niLight, nullptr, bsShadowLight); } } } @@ -165,7 +160,7 @@ void Clustered::UpdateLights() lights->CreateSRV(srvDesc); } - auto context = RE::BSRenderManager::GetSingleton()->GetRuntimeData().context; + auto context = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().context; D3D11_MAPPED_SUBRESOURCE mapped; DX::ThrowIfFailed(context->Map(lights->resource.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)); size_t bytes = sizeof(LightSData) * lightCount; diff --git a/src/Features/DistantTreeLighting.cpp b/src/Features/DistantTreeLighting.cpp index 4ac80ad67..86eecbcd3 100644 --- a/src/Features/DistantTreeLighting.cpp +++ b/src/Features/DistantTreeLighting.cpp @@ -90,27 +90,35 @@ void DistantTreeLighting::ModifyDistantTree(const RE::BSShader*, const uint32_t PerPass perPassData{}; ZeroMemory(&perPassData, sizeof(perPassData)); - auto shaderState = BSGraphics::ShaderState::QInstance(); - RE::NiTransform& dalcTransform = shaderState->DirectionalAmbientTransform; + auto& shaderState = RE::BSShaderManager::State::GetSingleton(); + RE::NiTransform& dalcTransform = shaderState.directionalAmbientTransform; Util::StoreTransform3x4NoScale(perPassData.DirectionalAmbient, dalcTransform); - auto accumulator = BSGraphics::BSShaderAccumulator::GetCurrentAccumulator(); - auto& position = accumulator->m_EyePosition; - auto state = BSGraphics::RendererShadowState::QInstance(); + auto accumulator = RE::BSGraphics::BSShaderAccumulator::GetCurrentAccumulator(); - perPassData.EyePosition.x = position.x - state->m_PosAdjust.x; - perPassData.EyePosition.y = position.y - state->m_PosAdjust.y; - perPassData.EyePosition.z = position.z - state->m_PosAdjust.z; + auto& position = accumulator->GetRuntimeData().eyePosition; + auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); - if (auto sunLight = (NiDirectionalLight*)accumulator->m_ActiveShadowSceneNode->sunLight->light.get()) { - auto imageSpaceManager = BSGraphics::TESImagespaceManager::GetSingleton(); + RE::NiPoint3 eyePosition{}; + if (REL::Module::IsVR()) { + // find center of eye position + eyePosition = state->GetVRRuntimeData2().posAdjust.getEye() + state->GetVRRuntimeData2().posAdjust.getEye(1); + eyePosition /= 2; + } else + eyePosition = state->GetRuntimeData2().posAdjust.getEye(); + perPassData.EyePosition.x = position.x - eyePosition.x; + perPassData.EyePosition.y = position.y - eyePosition.y; + perPassData.EyePosition.z = position.z - eyePosition.z; - perPassData.DirLightScale = imageSpaceManager->hdrData.hdr.sunlightScale * sunLight->fade; + if (auto sunLight = (NiDirectionalLight*)accumulator->GetRuntimeData().activeShadowSceneNode->GetRuntimeData().sunLight->light.get()) { + auto imageSpaceManager = RE::ImageSpaceManager::GetSingleton(); - perPassData.DirLightColor.x = sunLight->diffuse.red; - perPassData.DirLightColor.y = sunLight->diffuse.green; - perPassData.DirLightColor.z = sunLight->diffuse.blue; + perPassData.DirLightScale = imageSpaceManager->data.baseData.hdr.sunlightScale * sunLight->GetLightRuntimeData().fade; + + perPassData.DirLightColor.x = sunLight->GetLightRuntimeData().diffuse.red; + perPassData.DirLightColor.y = sunLight->GetLightRuntimeData().diffuse.green; + perPassData.DirLightColor.z = sunLight->GetLightRuntimeData().diffuse.blue; auto& direction = sunLight->GetWorldDirection(); perPassData.DirLightDirection.x = direction.x; @@ -124,7 +132,7 @@ void DistantTreeLighting::ModifyDistantTree(const RE::BSShader*, const uint32_t perPass->Update(perPassData); - auto context = RE::BSRenderManager::GetSingleton()->GetRuntimeData().context; + auto context = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().context; ID3D11Buffer* buffers[2]; context->VSGetConstantBuffers(2, 1, buffers); // buffers[0] @@ -132,9 +140,9 @@ void DistantTreeLighting::ModifyDistantTree(const RE::BSShader*, const uint32_t context->VSSetConstantBuffers(2, ARRAYSIZE(buffers), buffers); context->PSSetConstantBuffers(2, ARRAYSIZE(buffers), buffers); - auto renderer = BSGraphics::Renderer::QInstance(); + auto renderer = RE::BSGraphics::Renderer::GetSingleton(); ID3D11ShaderResourceView* views[1]{}; - views[0] = renderer->pRenderTargets[RENDER_TARGET_SHADOW_MASK].SRV; + views[0] = renderer->GetRuntimeData().renderTargets[RENDER_TARGET_SHADOW_MASK].SRV; context->PSSetShaderResources(17, ARRAYSIZE(views), views); } } diff --git a/src/Features/GrassCollision.cpp b/src/Features/GrassCollision.cpp index 15fcbe244..c613effab 100644 --- a/src/Features/GrassCollision.cpp +++ b/src/Features/GrassCollision.cpp @@ -110,7 +110,7 @@ static bool GetShapeBound(RE::bhkNiCollisionObject* Colliedobj, RE::NiPoint3& ce void GrassCollision::UpdateCollisions() { - auto state = BSGraphics::RendererShadowState::QInstance(); + auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); std::uint32_t currentCollisionCount = 0; @@ -125,9 +125,16 @@ void GrassCollision::UpdateCollisions() if (GetShapeBound(a_object, centerPos, radius)) { radius *= settings.RadiusMultiplier; CollisionSData data{}; - data.centre.x = centerPos.x - state->m_PosAdjust.x; - data.centre.y = centerPos.y - state->m_PosAdjust.y; - data.centre.z = centerPos.z - state->m_PosAdjust.z; + RE::NiPoint3 eyePosition{}; + if (REL::Module::IsVR()) { + // find center of eye position + eyePosition = state->GetVRRuntimeData2().posAdjust.getEye() + state->GetVRRuntimeData2().posAdjust.getEye(1); + eyePosition /= 2; + } else + eyePosition = state->GetRuntimeData2().posAdjust.getEye(); + data.centre.x = centerPos.x - eyePosition.x; + data.centre.y = centerPos.y - eyePosition.y; + data.centre.z = centerPos.z - eyePosition.z; data.radius = radius; currentCollisionCount++; collisionsData.push_back(data); @@ -167,7 +174,7 @@ void GrassCollision::UpdateCollisions() collisions->CreateSRV(srvDesc); } - auto context = RE::BSRenderManager::GetSingleton()->GetRuntimeData().context; + auto context = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().context; D3D11_MAPPED_SUBRESOURCE mapped; DX::ThrowIfFailed(context->Map(collisions->resource.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)); size_t bytes = sizeof(CollisionSData) * colllisionCount; @@ -185,13 +192,20 @@ void GrassCollision::ModifyGrass(const RE::BSShader*, const uint32_t) PerFrame perFrameData{}; ZeroMemory(&perFrameData, sizeof(perFrameData)); - auto state = BSGraphics::RendererShadowState::QInstance(); - auto shaderState = BSGraphics::ShaderState::QInstance(); - - auto bound = shaderState->kCachedPlayerBound; - perFrameData.boundCentre.x = bound.center.x - state->m_PosAdjust.x; - perFrameData.boundCentre.y = bound.center.y - state->m_PosAdjust.y; - perFrameData.boundCentre.z = bound.center.z - state->m_PosAdjust.z; + auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); + auto& shaderState = RE::BSShaderManager::State::GetSingleton(); + + auto bound = shaderState.cachedPlayerBound; + RE::NiPoint3 eyePosition{}; + if (REL::Module::IsVR()) { + // find center of eye position + eyePosition = state->GetVRRuntimeData2().posAdjust.getEye() + state->GetVRRuntimeData2().posAdjust.getEye(1); + eyePosition /= 2; + } else + eyePosition = state->GetRuntimeData2().posAdjust.getEye(); + perFrameData.boundCentre.x = bound.center.x - eyePosition.x; + perFrameData.boundCentre.y = bound.center.y - eyePosition.y; + perFrameData.boundCentre.z = bound.center.z - eyePosition.z; perFrameData.boundRadius = bound.radius * settings.RadiusMultiplier; perFrameData.Settings = settings; @@ -201,7 +215,7 @@ void GrassCollision::ModifyGrass(const RE::BSShader*, const uint32_t) updatePerFrame = false; } - auto context = RE::BSRenderManager::GetSingleton()->GetRuntimeData().context; + auto context = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().context; ID3D11ShaderResourceView* views[1]{}; views[0] = collisions->srv.get(); diff --git a/src/Features/GrassLighting.cpp b/src/Features/GrassLighting.cpp index 438fe6189..d3852a35a 100644 --- a/src/Features/GrassLighting.cpp +++ b/src/Features/GrassLighting.cpp @@ -51,21 +51,28 @@ void GrassLighting::ModifyGrass(const RE::BSShader*, const uint32_t descriptor) PerFrame perFrameData{}; ZeroMemory(&perFrameData, sizeof(perFrameData)); - auto shaderState = BSGraphics::ShaderState::QInstance(); - RE::NiTransform& dalcTransform = shaderState->DirectionalAmbientTransform; + auto& shaderState = RE::BSShaderManager::State::GetSingleton(); + RE::NiTransform& dalcTransform = shaderState.directionalAmbientTransform; Util::StoreTransform3x4NoScale(perFrameData.DirectionalAmbient, dalcTransform); - auto accumulator = BSGraphics::BSShaderAccumulator::GetCurrentAccumulator(); - auto& position = accumulator->m_EyePosition; - auto state = BSGraphics::RendererShadowState::QInstance(); + auto accumulator = RE::BSGraphics::BSShaderAccumulator::GetCurrentAccumulator(); + auto& position = accumulator->GetRuntimeData().eyePosition; + auto state = RE::BSGraphics::RendererShadowState::GetSingleton(); - perFrameData.EyePosition.x = position.x - state->m_PosAdjust.x; - perFrameData.EyePosition.y = position.y - state->m_PosAdjust.y; - perFrameData.EyePosition.z = position.z - state->m_PosAdjust.z; + RE::NiPoint3 eyePosition{}; + if (REL::Module::IsVR()) { + // find center of eye position + eyePosition = state->GetVRRuntimeData2().posAdjust.getEye() + state->GetVRRuntimeData2().posAdjust.getEye(1); + eyePosition /= 2; + } else + eyePosition = state->GetRuntimeData2().posAdjust.getEye(); + perFrameData.EyePosition.x = position.x - eyePosition.x; + perFrameData.EyePosition.y = position.y - eyePosition.y; + perFrameData.EyePosition.z = position.z - eyePosition.z; - auto manager = BSGraphics::TESImagespaceManager::GetSingleton(); - perFrameData.SunlightScale = manager->hdrData.hdr.sunlightScale; + auto manager = RE::ImageSpaceManager::GetSingleton(); + perFrameData.SunlightScale = manager->data.baseData.hdr.sunlightScale; perFrameData.Settings = settings; @@ -75,7 +82,7 @@ void GrassLighting::ModifyGrass(const RE::BSShader*, const uint32_t descriptor) } Clustered::GetSingleton()->Bind(true); - auto context = RE::BSRenderManager::GetSingleton()->GetRuntimeData().context; + auto context = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().context; ID3D11Buffer* buffers[2]; context->VSGetConstantBuffers(2, 1, buffers); // buffers[0] diff --git a/src/Hooks.cpp b/src/Hooks.cpp index 56ff1192b..ef7a0dfdf 100644 --- a/src/Hooks.cpp +++ b/src/Hooks.cpp @@ -99,7 +99,7 @@ void hk_BSShader_LoadShaders(RE::BSShader* shader, std::uintptr_t stream) } shaderCache.GetVertexShader(*shader, entry->id); } - BSShaderHooks::hk_LoadShaders((REX::BSShader*)shader, stream); + //BSShaderHooks::hk_LoadShaders((REX::BSShader*)shader, stream); }; bool hk_BSShader_BeginTechnique(RE::BSShader* shader, int vertexDescriptor, int pixelDescriptor, bool skipPIxelShader); @@ -169,10 +169,10 @@ namespace Hooks logger::info("Accessing render device information"); - auto manager = RE::BSRenderManager::GetSingleton(); + auto manager = RE::BSGraphics::Renderer::GetSingleton(); auto context = manager->GetRuntimeData().context; - auto swapchain = manager->GetRuntimeData().swapChain; + auto swapchain = manager->GetRuntimeData().renderWindows->swapChain; auto device = manager->GetRuntimeData().forwarder; logger::info("Detouring virtual function tables"); diff --git a/src/Menu.cpp b/src/Menu.cpp index b779236b8..48eeee0b9 100644 --- a/src/Menu.cpp +++ b/src/Menu.cpp @@ -351,9 +351,14 @@ void Menu::DrawSettings() auto state = State::GetSingleton(); for (int classIndex = 0; classIndex < RE::BSShader::Type::Total - 1; ++classIndex) { auto type = (RE::BSShader::Type)(classIndex + 1); - if (SIE::ShaderCache::IsSupportedShader(type)) { + if (!(SIE::ShaderCache::IsSupportedShader(type) || + // allow all shaders if debug or trace logging + (state->GetLogLevel()) <= spdlog::level::debug)) { + ImGui::BeginDisabled(); + ImGui::Checkbox(std::format("{}", magic_enum::enum_name(type)).c_str(), &state->enabledClasses[classIndex]); + ImGui::EndDisabled(); + } else ImGui::Checkbox(std::format("{}", magic_enum::enum_name(type)).c_str(), &state->enabledClasses[classIndex]); - } } } diff --git a/src/RE/BSGraphics.h b/src/RE/BSGraphics.h index 1c77dba71..ded2a32cf 100644 --- a/src/RE/BSGraphics.h +++ b/src/RE/BSGraphics.h @@ -6,32 +6,32 @@ namespace BSGraphics { struct alignas(16) ViewData { - DirectX::XMVECTOR m_ViewUp; - DirectX::XMVECTOR m_ViewRight; - DirectX::XMVECTOR m_ViewDir; - DirectX::XMMATRIX m_ViewMat; - DirectX::XMMATRIX m_ProjMat; - DirectX::XMMATRIX m_ViewProjMat; - DirectX::XMMATRIX m_UnknownMat1; - DirectX::XMMATRIX m_ViewProjMatrixUnjittered; - DirectX::XMMATRIX m_PreviousViewProjMatrixUnjittered; - DirectX::XMMATRIX m_ProjMatrixUnjittered; - DirectX::XMMATRIX m_UnknownMat2; - float m_ViewPort[4]; // NiRect { left = 0, right = 1, top = 1, bottom = 0 } - RE::NiPoint2 m_ViewDepthRange; - char _pad0[0x8]; + DirectX::XMVECTOR m_ViewUp; // 00 + DirectX::XMVECTOR m_ViewRight; // 10 + DirectX::XMVECTOR m_ViewForward; // 20 + DirectX::XMMATRIX m_ViewMat; // 30 + DirectX::XMMATRIX m_ProjMat; // 70 + DirectX::XMMATRIX m_ViewProjMat; // B0 + DirectX::XMMATRIX m_UnknownMat1; // F0 - all 0? + DirectX::XMMATRIX m_ViewProjMatrixUnjittered; // 130 + DirectX::XMMATRIX m_PreviousViewProjMatrixUnjittered; // 170 + DirectX::XMMATRIX m_ProjMatrixUnjittered; // 1B0 + DirectX::XMMATRIX m_UnknownMat2; // 1F0 - all 0? + float m_ViewPort[4]; // 230 - NiRect { left = 0, right = 1, top = 1, bottom = 0 } + RE::NiPoint2 m_ViewDepthRange; // 240 + char _pad0[0x8]; // 248 }; static_assert(sizeof(ViewData) == 0x250); struct CameraStateData { - RE::NiCamera* pReferenceCamera; - ViewData CamViewData; - RE::NiPoint3 PosAdjust; - RE::NiPoint3 CurrentPosAdjust; - RE::NiPoint3 PreviousPosAdjust; - bool UseJitter; - char _pad0[0x8]; + RE::NiCamera* pReferenceCamera; // 00 + ViewData CamViewData; // 08 VR is BSTArray, Each array has 2 elements (one for each eye?) + RE::NiPoint3 PosAdjust; // 258 + RE::NiPoint3 CurrentPosAdjust; // 264 + RE::NiPoint3 PreviousPosAdjust; // 270 + bool UseJitter; // 27c + uint32_t numData; // 28f }; static_assert(sizeof(CameraStateData) == 0x290); diff --git a/src/RE/BSGraphicsTypes.h b/src/RE/BSGraphicsTypes.h index fe8410ef8..dc5e3ba7d 100644 --- a/src/RE/BSGraphicsTypes.h +++ b/src/RE/BSGraphicsTypes.h @@ -67,7 +67,7 @@ namespace BSGraphics // // Renderer shadow state settings // - enum + enum ShaderFlags : uint32_t { DIRTY_RENDERTARGET = 0x1, DIRTY_VIEWPORT = 0x2, @@ -191,7 +191,10 @@ namespace BSGraphics struct Texture3DTargetData { - char _pad0[0x20]; + ID3D11Texture3D* texture; // 00 + ID3D11UnorderedAccessView* uav; // 08 + ID3D11ShaderResourceView* SRV; // 10 + uint64_t unkCount; // 18 }; static_assert(sizeof(Texture3DTargetData) == 0x20); @@ -531,70 +534,190 @@ namespace BSGraphics CRITICAL_SECTION RendererLock; }; - class RendererShadowState + template + class EYE_POSITION { public: - uint32_t m_StateUpdateFlags; // Flags +0x0 0xFFFFFFFF; global state updates - uint32_t m_PSResourceModifiedBits; // Flags +0x4 0xFFFF - uint32_t m_PSSamplerModifiedBits; // Flags +0x8 0xFFFF - uint32_t m_CSResourceModifiedBits; // Flags +0xC 0xFFFF - uint32_t m_CSSamplerModifiedBits; // Flags +0x10 0xFFFF - uint32_t m_CSUAVModifiedBits; // Flags +0x14 0xFF - - uint32_t m_RenderTargets[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; - uint32_t m_DepthStencil; // Index - uint32_t m_DepthStencilSlice; // Index - uint32_t m_CubeMapRenderTarget; // Index - uint32_t m_CubeMapRenderTargetView; // Index - - SetRenderTargetMode m_SetRenderTargetMode[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; - SetRenderTargetMode m_SetDepthStencilMode; - SetRenderTargetMode m_SetCubeMapRenderTargetMode; - - D3D11_VIEWPORT m_ViewPort; - - DepthStencilDepthMode m_DepthStencilDepthMode; - uint32_t m_DepthStencilUnknown; - uint32_t m_DepthStencilStencilMode; - uint32_t m_StencilRef; + /** + * Get the eye of type T + * + * @param a_index The index of the eye. By default it is set to 0. Default in SSE or Left in VR. 1 is Right. + * @throws std::out_of_range if index is greater than or equal to size. + */ + T getEye(uint32_t a_index = 0) + { + if (a_index >= size) + throw std::out_of_range("Index for eye is out of range"); + return eye[a_index]; + } - uint32_t m_RasterStateFillMode; - uint32_t m_RasterStateCullMode; - uint32_t m_RasterStateDepthBiasMode; - uint32_t m_RasterStateScissorMode; + private: + T eye[size]; // default or left eye is index 0, right eye is index 1 + }; - uint32_t m_AlphaBlendMode; - uint32_t m_AlphaBlendAlphaToCoverage; - uint32_t m_AlphaBlendWriteMode; + class RendererShadowState + { + public: + struct RUNTIME_DATA2 + { +#define RUNTIME_DATA2_CONTENT \ + EYE_POSITION m_PosAdjust; /* 35c, VR 3A4 */ \ + EYE_POSITION m_PreviousPosAdjust; /* 368, VR 3BC */ \ + EYE_POSITION m_CameraData; /* 374, VR 3E0 - size of each is 250 */ \ + uint32_t m_AlphaBlendModeExtra; /* 5c4, VR 880 */ \ + float unk5c8; /* 5c8, VR 884 */ \ + float unk5cc; /* 5cc VR 888 */ \ + uint32_t unk5d0; /* 5d0 VR 88c */ + RUNTIME_DATA2_CONTENT; + }; + static_assert(sizeof(RUNTIME_DATA2) == 0x280); + static_assert(offsetof(RUNTIME_DATA2, m_PosAdjust) == 0); + static_assert(offsetof(RUNTIME_DATA2, m_PreviousPosAdjust) == 0xc); + static_assert(offsetof(RUNTIME_DATA2, m_CameraData) == 0x20); - bool m_AlphaTestEnabled; - float m_AlphaTestRef; + struct VR_RUNTIME_DATA2 + { +#define VR_RUNTIME_DATA2_CONTENT \ + EYE_POSITION m_PosAdjust; /* 35c, VR 3A4 */ \ + EYE_POSITION m_PreviousPosAdjust; /* 368, VR 3BC */ \ + uint8_t unk3d4[0x3e0 - 0x3d4]; /* 3d4, VR only pad */ \ + EYE_POSITION m_CameraData; /* 374, VR 3E0 - size of each is 250 */ \ + uint32_t m_AlphaBlendModeExtra; /* 5c4, VR 880 */ \ + float unk5c8; /* 5c8, VR 884 */ \ + float unk5cc; /* 5cc VR 888 */ \ + uint32_t unk5d0; /* 5d0 VR 88c */ \ + ID3D11Buffer* VSConstantBuffers[12]; /* VR 890 only */ \ + ID3D11Buffer* PSConstantBuffers[12]; /* VR 8F0 only */ + VR_RUNTIME_DATA2_CONTENT; + }; + static_assert(sizeof(VR_RUNTIME_DATA2) == 0x5b0); + static_assert(offsetof(VR_RUNTIME_DATA2, m_PosAdjust) == 0); + static_assert(offsetof(VR_RUNTIME_DATA2, m_PreviousPosAdjust) == 0x18); + static_assert(offsetof(VR_RUNTIME_DATA2, m_CameraData) == 0x40); + static_assert(offsetof(VR_RUNTIME_DATA2, VSConstantBuffers) == 0x4f0); - uint32_t m_PSTextureAddressMode[16]; - uint32_t m_PSTextureFilterMode[16]; - ID3D11ShaderResourceView* m_PSTexture[16]; + struct RUNTIME_DATA + { +#ifndef ENABLE_SKYRIM_VR +# define RUNTIME_DATA_CONTENT \ + RUNTIME_DATA2_CONTENT; /* 35c, VR 3A4 */ +#elif !defined(ENABLE_SKYRIM_AE) && !defined(ENABLE_SKYRIM_SE) +# define RUNTIME_DATA_CONTENT \ + VR_RUNTIME_DATA2_CONTENT; /* 35c, VR 3A4 */ +#else +# define RUNTIME_DATA_CONTENT +#endif + uint64_t m_VertexDesc; /* 340 doesn't fit in SSE, VR 388 only? */ + VertexShader* m_CurrentVertexShader; /* 348, VR 390 */ + PixelShader* m_CurrentPixelShader; /* 350, VR 398 */ + D3D11_PRIMITIVE_TOPOLOGY m_Topology; /* 358, VR 3A0 */ + RUNTIME_DATA_CONTENT; + }; +#ifndef ENABLE_SKYRIM_VR + static_assert(sizeof(RUNTIME_DATA) == 0x2a0); + static_assert(offsetof(RUNTIME_DATA, m_Topology) == 0x18); + static_assert(offsetof(RUNTIME_DATA, m_PosAdjust) == 0x1c); + static_assert(offsetof(RUNTIME_DATA, m_PreviousPosAdjust) == 0x28); + static_assert(offsetof(RUNTIME_DATA, m_CameraData) == 0x40); +#elif !defined(ENABLE_SKYRIM_AE) && !defined(ENABLE_SKYRIM_SE) + static_assert(sizeof(RUNTIME_DATA) == 0x5d0); + static_assert(offsetof(RUNTIME_DATA, m_Topology) == 0x18); + static_assert(offsetof(RUNTIME_DATA, m_PosAdjust) == 0x1c); + static_assert(offsetof(RUNTIME_DATA, m_PreviousPosAdjust) == 0x34); + static_assert(offsetof(RUNTIME_DATA, m_CameraData) == 0x60); + static_assert(offsetof(RUNTIME_DATA, VSConstantBuffers) == 0x510); +#else + static_assert(sizeof(RUNTIME_DATA) == 0x20); + static_assert(offsetof(RUNTIME_DATA, m_Topology) == 0x18); +#endif + + ShaderFlags m_StateUpdateFlags; // 00 Flags +0x0 0xFFFFFFFF; global state updates + uint32_t m_PSResourceModifiedBits; // 04 Flags +0x4 0xFFFF + uint32_t m_PSSamplerModifiedBits; // 08 Flags +0x8 0xFFFF + uint32_t m_CSResourceModifiedBits; // 0c Flags +0xC 0xFFFF + uint32_t m_CSSamplerModifiedBits; // 10 Flags +0x10 0xFFFF + uint32_t m_CSUAVModifiedBits; // 14 Flags +0x14 0xFF + uint32_t m_OMUAVModifiedBits; // 18 Flags +0x18 0xFF + uint32_t m_SRVModifiedBits; // 1c Flags +0x1C 0xFF + + uint32_t m_RenderTargets[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; // 20 + uint32_t m_DepthStencil; // 40 - Index + uint32_t m_DepthStencilSlice; // 44 Index + uint32_t m_CubeMapRenderTarget; // 48 = Index + uint32_t m_CubeMapRenderTargetView; // 4c Index + + SetRenderTargetMode m_SetRenderTargetMode[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; // 50 + SetRenderTargetMode m_SetDepthStencilMode; // 70 + SetRenderTargetMode m_SetCubeMapRenderTargetMode; // 74 + + D3D11_VIEWPORT m_ViewPort; // 78 + + DepthStencilDepthMode m_DepthStencilDepthMode; // 90 + DepthStencilDepthMode m_DepthStencilDepthModePrevious; // 94 - also some kind of mode + uint32_t m_DepthStencilStencilMode; // 98 + uint32_t m_StencilRef; // 9c + + uint32_t m_RasterStateFillMode; // a0 + uint32_t m_RasterStateCullMode; // a4 + uint32_t m_RasterStateDepthBiasMode; // a8 + uint32_t m_RasterStateScissorMode; // ac + + uint32_t m_AlphaBlendMode; // b0 + uint32_t m_AlphaBlendAlphaToCoverage; // b4 + uint32_t m_AlphaBlendWriteMode; // b8 + + bool m_AlphaTestEnabled; // BC + float m_AlphaTestRef; // C0 + + uint32_t m_PSTextureAddressMode[16]; // c4 + uint32_t m_PSTextureFilterMode[16]; // 104 + uint32_t unk144; // 144 + ID3D11ShaderResourceView* m_PSTexture[16]; // 148 + + uint32_t m_CSTextureAddressMode[16]; // 1c8 + uint32_t m_CSTextureFilterMode[16]; // 208 + + ID3D11ShaderResourceView* m_CSTexture[16]; // 248 + uint32_t m_CSTextureMinLodMode[16]; // 2C8 + ID3D11UnorderedAccessView* m_CSUAV[8]; // 308 + + RUNTIME_DATA_CONTENT; // 340 + + [[nodiscard]] inline RUNTIME_DATA& GetRuntimeData() noexcept + { + return REL::RelocateMember(this, 0x340, 0x388); + } - uint32_t m_CSTextureAddressMode[16]; - uint32_t m_CSTextureFilterMode[16]; + [[nodiscard]] inline const RUNTIME_DATA& GetRuntimeData() const noexcept + { + return REL::RelocateMember(this, 0x340, 0x388); + } - ID3D11ShaderResourceView* m_CSTexture[16]; - uint32_t m_CSTextureMinLodMode[16]; - ID3D11UnorderedAccessView* m_CSUAV[8]; + [[nodiscard]] inline RUNTIME_DATA2& GetRuntimeData2() noexcept + { + return REL::RelocateMember(this, 0x35c, 0x3a4); + } - uint64_t m_VertexDesc; - VertexShader* m_CurrentVertexShader; - PixelShader* m_CurrentPixelShader; - D3D11_PRIMITIVE_TOPOLOGY m_Topology; + [[nodiscard]] inline const RUNTIME_DATA2& GetRuntimeData2() const noexcept + { + return REL::RelocateMember(this, 0x35c, 0x3a4); + } - RE::NiPoint3 m_PosAdjust; - RE::NiPoint3 m_PreviousPosAdjust; - ViewData m_CameraData; + [[nodiscard]] inline VR_RUNTIME_DATA2& GetVRRuntimeData2() noexcept + { + return REL::RelocateMember(this, 0x35c, 0x3a4); + } - uint32_t m_AlphaBlendModeExtra; - char _pad0[0xC]; + [[nodiscard]] inline const VR_RUNTIME_DATA2& GetVRRuntimeData2() const noexcept + { + return REL::RelocateMember(this, 0x35c, 0x3a4); + } static RendererShadowState* QInstance(); }; +#undef RUNTIME_DATA_CONTENT +#undef RUNTIME_DATA2_CONTENT +#undef VR_RUNTIME_DATA2_CONTENT class Renderer { @@ -698,37 +821,69 @@ namespace BSGraphics virtual ~BSShaderAccumulator(); virtual void StartAccumulating(RE::NiCamera const*) override; virtual void FinishAccumulatingDispatch(uint32_t RenderFlags); + struct RUNTIME_DATA + { +#define RUNTIME_DATA_CONTENT \ + RE::BSBatchRenderer* m_BatchRenderer; \ + uint32_t m_CurrentPass; \ + uint32_t m_CurrentBucket; \ + bool m_CurrentActive; \ + char _pad[0x7]; \ + RE::ShadowSceneNode* m_ActiveShadowSceneNode; \ + uint32_t m_RenderMode; \ + char _pad2[0x18]; \ + RE::NiPoint3 m_EyePosition; \ + char _pad3[0x8]; + RUNTIME_DATA_CONTENT + }; + static_assert(sizeof(RUNTIME_DATA) == 0x50); + static_assert(offsetof(RUNTIME_DATA, m_BatchRenderer) == 0); + static_assert(offsetof(RUNTIME_DATA, m_ActiveShadowSceneNode) == 0x18); - char _pad1[0xD0]; - bool m_1stPerson; - char _pad0[0x3]; - bool m_DrawDecals; - RE::BSBatchRenderer* m_BatchRenderer; - uint32_t m_CurrentPass; - uint32_t m_CurrentBucket; - bool m_CurrentActive; - char _pad[0x7]; - RE::ShadowSceneNode* m_ActiveShadowSceneNode; - uint32_t m_RenderMode; - char _pad2[0x18]; - RE::NiPoint3 m_EyePosition; - char _pad3[0x8]; + [[nodiscard]] inline RUNTIME_DATA& GetRuntimeData() noexcept + { + return REL::RelocateMember(this, 0x130, 0x158); + } + [[nodiscard]] inline const RUNTIME_DATA& GetRuntimeData() const noexcept + { + return REL::RelocateMember(this, 0x148, 0x170); + } static BSShaderAccumulator* GetCurrentAccumulator(); - }; + + //members + char _pad1[0xD0]; + bool m_1stPerson; // 128 + char _pad0[0x3]; // 129 + bool m_DrawDecals; // 130 +#ifndef ENABLE_SKYRIM_VR + RUNTIME_DATA_CONTENT; // 130 +#elif !defined(ENABLE_SKYRIM_AE) && !defined(ENABLE_SKYRIM_SE) + std::uint64_t unk000[(0x158 - 0x130) >> 3]; // 130 + RUNTIME_DATA_CONTENT; // 158 +#endif + }; +#ifndef ENABLE_SKYRIM_VR static_assert(sizeof(BSShaderAccumulator) == 0x180); + static_assert(offsetof(BSShaderAccumulator, m_BatchRenderer) == 0x130); + static_assert(offsetof(BSShaderAccumulator, m_ActiveShadowSceneNode) == 0x148); +#elif !defined(ENABLE_SKYRIM_AE) && !defined(ENABLE_SKYRIM_SE) + static_assert(offsetof(BSShaderAccumulator, m_BatchRenderer) == 0x158); + static_assert(offsetof(BSShaderAccumulator, m_ActiveShadowSceneNode) == 0x170); +#endif +#undef RUNTIME_DATA_CONTENT class TESImagespaceManager { public: float pad0[42]; - RE::ImageSpaceBaseData* baseData0; - RE::ImageSpaceBaseData* baseData1; + RE::ImageSpaceBaseData* baseData0; //a8 + RE::ImageSpaceBaseData* baseData1; //b0 float pad1; float pad2; float pad3; float pad4; - RE::ImageSpaceBaseData hdrData; + RE::ImageSpaceBaseData hdrData; // c8 static TESImagespaceManager* GetSingleton() { @@ -737,4 +892,3 @@ namespace BSGraphics } }; } - diff --git a/src/ShaderCache.h b/src/ShaderCache.h index 68757b608..290570652 100644 --- a/src/ShaderCache.h +++ b/src/ShaderCache.h @@ -75,12 +75,14 @@ namespace SIE inline static bool IsSupportedShader(const RE::BSShader::Type type) { + if (!REL::Module::IsVR()) return type == RE::BSShader::Type::Lighting || type == RE::BSShader::Type::BloodSplatter || type == RE::BSShader::Type::DistantTree || type == RE::BSShader::Type::Sky || type == RE::BSShader::Type::Grass || type == RE::BSShader::Type::Particle; + return type == RE::BSShader::Type::Grass; } inline static bool IsSupportedShader(const RE::BSShader& shader) diff --git a/src/State.cpp b/src/State.cpp index 18a96ecce..edd22f366 100644 --- a/src/State.cpp +++ b/src/State.cpp @@ -17,7 +17,7 @@ void State::Draw() auto type = currentShader->shaderType.get(); if (type > 0 && type < RE::BSShader::Type::Total) { if (enabledClasses[type - 1]) { - auto context = RE::BSRenderManager::GetSingleton()->GetRuntimeData().context; + auto context = RE::BSGraphics::Renderer::GetSingleton()->GetRuntimeData().context; if (auto vertexShader = shaderCache.GetVertexShader(*currentShader, currentVertexDescriptor)) { context->VSSetShader(vertexShader->shader, NULL, NULL); diff --git a/src/Util.cpp b/src/Util.cpp index 5594c47f0..6f60e7bf5 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -29,9 +29,9 @@ namespace Util ID3D11ShaderResourceView* GetSRVFromRTV(ID3D11RenderTargetView* a_rtv) { if (a_rtv) { - if (auto r = BSGraphics::Renderer::QInstance()) { - for (int i = 0; i < RenderTargets::RENDER_TARGET_COUNT; i++) { - auto rt = r->pRenderTargets[i]; + if (auto r = RE::BSGraphics::Renderer::GetSingleton()) { + for (int i = 0; i < RE::RENDER_TARGETS::kTOTAL; i++) { + auto rt = r->GetRuntimeData().renderTargets[i]; if (a_rtv == rt.RTV) { return rt.SRV; } @@ -44,9 +44,9 @@ namespace Util ID3D11RenderTargetView* GetRTVFromSRV(ID3D11ShaderResourceView* a_srv) { if (a_srv) { - if (auto r = BSGraphics::Renderer::QInstance()) { - for (int i = 0; i < RenderTargets::RENDER_TARGET_COUNT; i++) { - auto rt = r->pRenderTargets[i]; + if (auto r = RE::BSGraphics::Renderer::GetSingleton()) { + for (int i = 0; i < RE::RENDER_TARGETS::kTOTAL; i++) { + auto rt = r->GetRuntimeData().renderTargets[i]; if (a_srv == rt.SRV || a_srv == rt.SRVCopy) { return rt.RTV; } @@ -58,12 +58,14 @@ namespace Util std::string GetNameFromSRV(ID3D11ShaderResourceView* a_srv) { + using RENDER_TARGET = RE::RENDER_TARGETS::RENDER_TARGET; + if (a_srv) { - if (auto r = BSGraphics::Renderer::QInstance()) { - for (int i = 0; i < RenderTargets::RENDER_TARGET_COUNT; i++) { - auto rt = r->pRenderTargets[i]; + if (auto r = RE::BSGraphics::Renderer::GetSingleton()) { + for (int i = 0; i < RENDER_TARGET::kTOTAL; i++) { + auto rt = r->GetRuntimeData().renderTargets[i]; if (a_srv == rt.SRV || a_srv == rt.SRVCopy) { - return RTNames[i]; + return std::string(magic_enum::enum_name(static_cast(i))); } } } @@ -73,12 +75,13 @@ namespace Util std::string GetNameFromRTV(ID3D11RenderTargetView* a_rtv) { + using RENDER_TARGET = RE::RENDER_TARGETS::RENDER_TARGET; if (a_rtv) { - if (auto r = BSGraphics::Renderer::QInstance()) { - for (int i = 0; i < RenderTargets::RENDER_TARGET_COUNT; i++) { - auto rt = r->pRenderTargets[i]; + if (auto r = RE::BSGraphics::Renderer::GetSingleton()) { + for (int i = 0; i < RENDER_TARGET::kTOTAL; i++) { + auto rt = r->GetRuntimeData().renderTargets[i]; if (a_rtv == rt.RTV) { - return RTNames[i]; + return std::string(magic_enum::enum_name(static_cast(i))); } } } diff --git a/src/XSEPlugin.cpp b/src/XSEPlugin.cpp index 476944f30..1e9f501a8 100644 --- a/src/XSEPlugin.cpp +++ b/src/XSEPlugin.cpp @@ -1,8 +1,8 @@ #include "Hooks.h" +#include "Menu.h" #include "ShaderCache.h" #include "State.h" -#include "Menu.h" #include "ENB/ENBSeriesAPI.h" #define DLLEXPORT __declspec(dllexport)