From d9400f708a5af50a38273e25c103143968e16b67 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Tue, 21 Nov 2017 19:53:38 +1000 Subject: [PATCH] D3D: Move remaining static variables from Render.cpp to Renderer class --- Source/Core/VideoBackends/D3D/Render.cpp | 309 +++++++++++------------ Source/Core/VideoBackends/D3D/Render.h | 18 ++ 2 files changed, 166 insertions(+), 161 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 41a48e9a8d..762404d581 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -53,147 +53,11 @@ typedef struct _Nv_Stereo_Image_Header #define NVSTEREO_IMAGE_SIGNATURE 0x4433564e -static u32 s_last_multisamples = 1; -static bool s_last_stereo_mode = false; -static bool s_last_fullscreen_mode = false; - -static std::array s_clear_blend_states{}; -static std::array s_clear_depth_states{}; -static ID3D11BlendState* s_reset_blend_state = nullptr; -static ID3D11DepthStencilState* s_reset_depth_state = nullptr; -static ID3D11RasterizerState* s_reset_rast_state = nullptr; - -static ID3D11Texture2D* s_screenshot_texture = nullptr; -static D3DTexture2D* s_3d_vision_texture = nullptr; - -static void SetupDeviceObjects() -{ - HRESULT hr; - - D3D11_DEPTH_STENCIL_DESC ddesc; - ddesc.DepthEnable = FALSE; - ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - ddesc.DepthFunc = D3D11_COMPARISON_ALWAYS; - ddesc.StencilEnable = FALSE; - ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; - ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; - hr = D3D::device->CreateDepthStencilState(&ddesc, &s_clear_depth_states[0]); - CHECK(hr == S_OK, "Create depth state for Renderer::ClearScreen"); - ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - ddesc.DepthEnable = TRUE; - hr = D3D::device->CreateDepthStencilState(&ddesc, &s_clear_depth_states[1]); - CHECK(hr == S_OK, "Create depth state for Renderer::ClearScreen"); - ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - hr = D3D::device->CreateDepthStencilState(&ddesc, &s_clear_depth_states[2]); - CHECK(hr == S_OK, "Create depth state for Renderer::ClearScreen"); - D3D::SetDebugObjectName(s_clear_depth_states[0], - "depth state for Renderer::ClearScreen (depth buffer disabled)"); - D3D::SetDebugObjectName( - s_clear_depth_states[1], - "depth state for Renderer::ClearScreen (depth buffer enabled, writing enabled)"); - D3D::SetDebugObjectName( - s_clear_depth_states[2], - "depth state for Renderer::ClearScreen (depth buffer enabled, writing disabled)"); - - D3D11_BLEND_DESC blenddesc; - blenddesc.AlphaToCoverageEnable = FALSE; - blenddesc.IndependentBlendEnable = FALSE; - blenddesc.RenderTarget[0].BlendEnable = FALSE; - blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; - blenddesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; - blenddesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO; - blenddesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - hr = D3D::device->CreateBlendState(&blenddesc, &s_reset_blend_state); - CHECK(hr == S_OK, "Create blend state for Renderer::ResetAPIState"); - D3D::SetDebugObjectName(s_reset_blend_state, "blend state for Renderer::ResetAPIState"); - - s_clear_blend_states[0] = s_reset_blend_state; - s_reset_blend_state->AddRef(); - - blenddesc.RenderTarget[0].RenderTargetWriteMask = - D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN | D3D11_COLOR_WRITE_ENABLE_BLUE; - hr = D3D::device->CreateBlendState(&blenddesc, &s_clear_blend_states[1]); - CHECK(hr == S_OK, "Create blend state for Renderer::ClearScreen"); - - blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALPHA; - hr = D3D::device->CreateBlendState(&blenddesc, &s_clear_blend_states[2]); - CHECK(hr == S_OK, "Create blend state for Renderer::ClearScreen"); - - blenddesc.RenderTarget[0].RenderTargetWriteMask = 0; - hr = D3D::device->CreateBlendState(&blenddesc, &s_clear_blend_states[3]); - CHECK(hr == S_OK, "Create blend state for Renderer::ClearScreen"); - - ddesc.DepthEnable = FALSE; - ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - ddesc.DepthFunc = D3D11_COMPARISON_LESS; - ddesc.StencilEnable = FALSE; - ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; - ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; - hr = D3D::device->CreateDepthStencilState(&ddesc, &s_reset_depth_state); - CHECK(hr == S_OK, "Create depth state for Renderer::ResetAPIState"); - D3D::SetDebugObjectName(s_reset_depth_state, "depth stencil state for Renderer::ResetAPIState"); - - D3D11_RASTERIZER_DESC rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, - 0, 0.f, 0.f, false, false, false, false); - hr = D3D::device->CreateRasterizerState(&rastdesc, &s_reset_rast_state); - CHECK(hr == S_OK, "Create rasterizer state for Renderer::ResetAPIState"); - D3D::SetDebugObjectName(s_reset_rast_state, "rasterizer state for Renderer::ResetAPIState"); - - s_screenshot_texture = nullptr; -} - -// Kill off all device objects -static void TeardownDeviceObjects() -{ - g_framebuffer_manager.reset(); - - SAFE_RELEASE(s_clear_blend_states[0]); - SAFE_RELEASE(s_clear_blend_states[1]); - SAFE_RELEASE(s_clear_blend_states[2]); - SAFE_RELEASE(s_clear_blend_states[3]); - SAFE_RELEASE(s_clear_depth_states[0]); - SAFE_RELEASE(s_clear_depth_states[1]); - SAFE_RELEASE(s_clear_depth_states[2]); - SAFE_RELEASE(s_reset_blend_state); - SAFE_RELEASE(s_reset_depth_state); - SAFE_RELEASE(s_reset_rast_state); - SAFE_RELEASE(s_screenshot_texture); - SAFE_RELEASE(s_3d_vision_texture); -} - -static void Create3DVisionTexture(int width, int height) -{ - // Create a staging texture for 3D vision with signature information in the last row. - // Nvidia 3D Vision supports full SBS, so there is no loss in resolution during this process. - NVSTEREOIMAGEHEADER header; - header.dwSignature = NVSTEREO_IMAGE_SIGNATURE; - header.dwWidth = static_cast(width * 2); - header.dwHeight = static_cast(height + 1); - header.dwBPP = 32; - header.dwFlags = 0; - - const u32 pitch = static_cast(4 * width * 2); - const auto memory = std::make_unique((height + 1) * pitch); - u8* image_header_location = &memory[height * pitch]; - std::memcpy(image_header_location, &header, sizeof(header)); - - D3D11_SUBRESOURCE_DATA sys_data; - sys_data.SysMemPitch = pitch; - sys_data.pSysMem = memory.get(); - - s_3d_vision_texture = - D3DTexture2D::Create(width * 2, height + 1, D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT, - DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, &sys_data); -} - Renderer::Renderer() : ::Renderer(D3D::GetBackBufferWidth(), D3D::GetBackBufferHeight()) { - s_last_multisamples = g_ActiveConfig.iMultisamples; - s_last_stereo_mode = g_ActiveConfig.stereo_mode != StereoMode::Off; - s_last_fullscreen_mode = D3D::GetFullscreenState(); + m_last_multisamples = g_ActiveConfig.iMultisamples; + m_last_stereo_mode = g_ActiveConfig.stereo_mode != StereoMode::Off; + m_last_fullscreen_mode = D3D::GetFullscreenState(); g_framebuffer_manager = std::make_unique(m_target_width, m_target_height); SetupDeviceObjects(); @@ -228,6 +92,129 @@ Renderer::~Renderer() D3D::Close(); } +void Renderer::SetupDeviceObjects() +{ + HRESULT hr; + + D3D11_DEPTH_STENCIL_DESC ddesc; + ddesc.DepthEnable = FALSE; + ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + ddesc.DepthFunc = D3D11_COMPARISON_ALWAYS; + ddesc.StencilEnable = FALSE; + ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + hr = D3D::device->CreateDepthStencilState(&ddesc, &m_clear_depth_states[0]); + CHECK(hr == S_OK, "Create depth state for Renderer::ClearScreen"); + ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + ddesc.DepthEnable = TRUE; + hr = D3D::device->CreateDepthStencilState(&ddesc, &m_clear_depth_states[1]); + CHECK(hr == S_OK, "Create depth state for Renderer::ClearScreen"); + ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + hr = D3D::device->CreateDepthStencilState(&ddesc, &m_clear_depth_states[2]); + CHECK(hr == S_OK, "Create depth state for Renderer::ClearScreen"); + D3D::SetDebugObjectName(m_clear_depth_states[0], + "depth state for Renderer::ClearScreen (depth buffer disabled)"); + D3D::SetDebugObjectName( + m_clear_depth_states[1], + "depth state for Renderer::ClearScreen (depth buffer enabled, writing enabled)"); + D3D::SetDebugObjectName( + m_clear_depth_states[2], + "depth state for Renderer::ClearScreen (depth buffer enabled, writing disabled)"); + + D3D11_BLEND_DESC blenddesc; + blenddesc.AlphaToCoverageEnable = FALSE; + blenddesc.IndependentBlendEnable = FALSE; + blenddesc.RenderTarget[0].BlendEnable = FALSE; + blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + blenddesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; + blenddesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO; + blenddesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + hr = D3D::device->CreateBlendState(&blenddesc, &m_reset_blend_state); + CHECK(hr == S_OK, "Create blend state for Renderer::ResetAPIState"); + D3D::SetDebugObjectName(m_reset_blend_state, "blend state for Renderer::ResetAPIState"); + + m_clear_blend_states[0] = m_reset_blend_state; + m_reset_blend_state->AddRef(); + + blenddesc.RenderTarget[0].RenderTargetWriteMask = + D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN | D3D11_COLOR_WRITE_ENABLE_BLUE; + hr = D3D::device->CreateBlendState(&blenddesc, &m_clear_blend_states[1]); + CHECK(hr == S_OK, "Create blend state for Renderer::ClearScreen"); + + blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALPHA; + hr = D3D::device->CreateBlendState(&blenddesc, &m_clear_blend_states[2]); + CHECK(hr == S_OK, "Create blend state for Renderer::ClearScreen"); + + blenddesc.RenderTarget[0].RenderTargetWriteMask = 0; + hr = D3D::device->CreateBlendState(&blenddesc, &m_clear_blend_states[3]); + CHECK(hr == S_OK, "Create blend state for Renderer::ClearScreen"); + + ddesc.DepthEnable = FALSE; + ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + ddesc.DepthFunc = D3D11_COMPARISON_LESS; + ddesc.StencilEnable = FALSE; + ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + hr = D3D::device->CreateDepthStencilState(&ddesc, &m_reset_depth_state); + CHECK(hr == S_OK, "Create depth state for Renderer::ResetAPIState"); + D3D::SetDebugObjectName(m_reset_depth_state, "depth stencil state for Renderer::ResetAPIState"); + + D3D11_RASTERIZER_DESC rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, + 0, 0.f, 0.f, false, false, false, false); + hr = D3D::device->CreateRasterizerState(&rastdesc, &m_reset_rast_state); + CHECK(hr == S_OK, "Create rasterizer state for Renderer::ResetAPIState"); + D3D::SetDebugObjectName(m_reset_rast_state, "rasterizer state for Renderer::ResetAPIState"); + + m_screenshot_texture = nullptr; +} + +// Kill off all device objects +void Renderer::TeardownDeviceObjects() +{ + g_framebuffer_manager.reset(); + + SAFE_RELEASE(m_clear_blend_states[0]); + SAFE_RELEASE(m_clear_blend_states[1]); + SAFE_RELEASE(m_clear_blend_states[2]); + SAFE_RELEASE(m_clear_blend_states[3]); + SAFE_RELEASE(m_clear_depth_states[0]); + SAFE_RELEASE(m_clear_depth_states[1]); + SAFE_RELEASE(m_clear_depth_states[2]); + SAFE_RELEASE(m_reset_blend_state); + SAFE_RELEASE(m_reset_depth_state); + SAFE_RELEASE(m_reset_rast_state); + SAFE_RELEASE(m_screenshot_texture); + SAFE_RELEASE(m_3d_vision_texture); +} + +void Renderer::Create3DVisionTexture(int width, int height) +{ + // Create a staging texture for 3D vision with signature information in the last row. + // Nvidia 3D Vision supports full SBS, so there is no loss in resolution during this process. + NVSTEREOIMAGEHEADER header; + header.dwSignature = NVSTEREO_IMAGE_SIGNATURE; + header.dwWidth = static_cast(width * 2); + header.dwHeight = static_cast(height + 1); + header.dwBPP = 32; + header.dwFlags = 0; + + const u32 pitch = static_cast(4 * width * 2); + const auto memory = std::make_unique((height + 1) * pitch); + u8* image_header_location = &memory[height * pitch]; + std::memcpy(image_header_location, &header, sizeof(header)); + + D3D11_SUBRESOURCE_DATA sys_data; + sys_data.SysMemPitch = pitch; + sys_data.pSysMem = memory.get(); + + m_3d_vision_texture = + D3DTexture2D::Create(width * 2, height + 1, D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT, + DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, &sys_data); +} + void Renderer::RenderText(const std::string& text, int left, int top, u32 color) { D3D::DrawTextScaled(static_cast(left + 1), static_cast(top + 1), 20.f, 0.0f, @@ -430,8 +417,8 @@ void Renderer::PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num } else // if (type == EFBAccessType::PokeZ) { - D3D::stateman->PushBlendState(s_clear_blend_states[3]); - D3D::stateman->PushDepthState(s_clear_depth_states[1]); + D3D::stateman->PushBlendState(m_clear_blend_states[3]); + D3D::stateman->PushDepthState(m_clear_depth_states[1]); D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.0f, 0.0f, (float)GetTargetWidth(), (float)GetTargetHeight()); @@ -513,21 +500,21 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE ResetAPIState(); if (colorEnable && alphaEnable) - D3D::stateman->PushBlendState(s_clear_blend_states[0]); + D3D::stateman->PushBlendState(m_clear_blend_states[0]); else if (colorEnable) - D3D::stateman->PushBlendState(s_clear_blend_states[1]); + D3D::stateman->PushBlendState(m_clear_blend_states[1]); else if (alphaEnable) - D3D::stateman->PushBlendState(s_clear_blend_states[2]); + D3D::stateman->PushBlendState(m_clear_blend_states[2]); else - D3D::stateman->PushBlendState(s_clear_blend_states[3]); + D3D::stateman->PushBlendState(m_clear_blend_states[3]); // TODO: Should we enable Z testing here? // if (!bpmem.zmode.testenable) D3D::stateman->PushDepthState(s_clear_depth_states[0]); // else if (zEnable) - D3D::stateman->PushDepthState(s_clear_depth_states[1]); + D3D::stateman->PushDepthState(m_clear_depth_states[1]); else /*if (!zEnable)*/ - D3D::stateman->PushDepthState(s_clear_depth_states[2]); + D3D::stateman->PushDepthState(m_clear_depth_states[2]); // Update the view port for clearing the picture TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc); @@ -633,33 +620,33 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region const bool window_resized = CheckForResize(); const bool fullscreen = D3D::GetFullscreenState(); - const bool fs_changed = s_last_fullscreen_mode != fullscreen; + const bool fs_changed = m_last_fullscreen_mode != fullscreen; // Flip/present backbuffer to frontbuffer here D3D::Present(); // Resize the back buffers NOW to avoid flickering if (CalculateTargetSize() || window_resized || fs_changed || - s_last_multisamples != g_ActiveConfig.iMultisamples || - s_last_stereo_mode != (g_ActiveConfig.stereo_mode != StereoMode::Off)) + m_last_multisamples != g_ActiveConfig.iMultisamples || + m_last_stereo_mode != (g_ActiveConfig.stereo_mode != StereoMode::Off)) { - s_last_multisamples = g_ActiveConfig.iMultisamples; - s_last_fullscreen_mode = fullscreen; + m_last_multisamples = g_ActiveConfig.iMultisamples; + m_last_fullscreen_mode = fullscreen; PixelShaderCache::InvalidateMSAAShaders(); if (window_resized || fs_changed) { // TODO: Aren't we still holding a reference to the back buffer right now? D3D::Reset(); - SAFE_RELEASE(s_screenshot_texture); - SAFE_RELEASE(s_3d_vision_texture); + SAFE_RELEASE(m_screenshot_texture); + SAFE_RELEASE(m_3d_vision_texture); m_backbuffer_width = D3D::GetBackBufferWidth(); m_backbuffer_height = D3D::GetBackBufferHeight(); } UpdateDrawRectangle(); - s_last_stereo_mode = g_ActiveConfig.stereo_mode != StereoMode::Off; + m_last_stereo_mode = g_ActiveConfig.stereo_mode != StereoMode::Off; D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), nullptr); @@ -689,9 +676,9 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region // ALWAYS call RestoreAPIState for each ResetAPIState call you're doing void Renderer::ResetAPIState() { - D3D::stateman->PushBlendState(s_reset_blend_state); - D3D::stateman->PushDepthState(s_reset_depth_state); - D3D::stateman->PushRasterizerState(s_reset_rast_state); + D3D::stateman->PushBlendState(m_reset_blend_state); + D3D::stateman->PushDepthState(m_reset_depth_state); + D3D::stateman->PushRasterizerState(m_reset_rast_state); } void Renderer::RestoreAPIState() @@ -818,7 +805,7 @@ void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D } else if (g_ActiveConfig.stereo_mode == StereoMode::Nvidia3DVision) { - if (!s_3d_vision_texture) + if (!m_3d_vision_texture) Create3DVisionTexture(m_backbuffer_width, m_backbuffer_height); D3D11_VIEWPORT leftVp = CD3D11_VIEWPORT((float)dst.left, (float)dst.top, (float)dst.GetWidth(), @@ -827,7 +814,7 @@ void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D (float)dst.GetWidth(), (float)dst.GetHeight()); // Render to staging texture which is double the width of the backbuffer - D3D::context->OMSetRenderTargets(1, &s_3d_vision_texture->GetRTV(), nullptr); + D3D::context->OMSetRenderTargets(1, &m_3d_vision_texture->GetRTV(), nullptr); D3D::context->RSSetViewports(1, &leftVp); D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height, @@ -845,7 +832,7 @@ void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D // recognize the signature and automatically include the right eye frame. D3D11_BOX box = CD3D11_BOX(0, 0, 0, m_backbuffer_width, m_backbuffer_height, 1); D3D::context->CopySubresourceRegion(D3D::GetBackBuffer()->GetTex(), 0, 0, 0, 0, - s_3d_vision_texture->GetTex(), 0, &box); + m_3d_vision_texture->GetTex(), 0, &box); // Restore render target to backbuffer D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), nullptr); diff --git a/Source/Core/VideoBackends/D3D/Render.h b/Source/Core/VideoBackends/D3D/Render.h index 340802f02f..333ff9a80c 100644 --- a/Source/Core/VideoBackends/D3D/Render.h +++ b/Source/Core/VideoBackends/D3D/Render.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include "VideoBackends/D3D/D3DState.h" #include "VideoCommon/RenderBase.h" @@ -66,10 +67,27 @@ private: RasterizationState raster; }; + void SetupDeviceObjects(); + void TeardownDeviceObjects(); + void Create3DVisionTexture(int width, int height); + void BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D* src_texture, u32 src_width, u32 src_height, float Gamma); StateCache m_state_cache; GXPipelineState m_gx_state; + + std::array m_clear_blend_states{}; + std::array m_clear_depth_states{}; + ID3D11BlendState* m_reset_blend_state = nullptr; + ID3D11DepthStencilState* m_reset_depth_state = nullptr; + ID3D11RasterizerState* m_reset_rast_state = nullptr; + + ID3D11Texture2D* m_screenshot_texture = nullptr; + D3DTexture2D* m_3d_vision_texture = nullptr; + + u32 m_last_multisamples = 1; + bool m_last_stereo_mode = false; + bool m_last_fullscreen_mode = false; }; }