mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge pull request #7753 from stenzek/videocommon-all-the-things
Move a significant amount of video backend logic to VideoCommon
This commit is contained in:
@@ -10,6 +10,9 @@
|
||||
|
||||
class GLContext;
|
||||
|
||||
// Texture which we use to not disturb the other bindings.
|
||||
constexpr GLenum GL_MUTABLE_TEXTURE_INDEX = GL_TEXTURE10;
|
||||
|
||||
namespace GLUtil
|
||||
{
|
||||
GLuint CompileProgram(const std::string& vertexShader, const std::string& fragmentShader);
|
||||
|
||||
@@ -137,8 +137,6 @@ const ConfigInfo<int> GFX_STEREO_DEPTH_PERCENTAGE{
|
||||
|
||||
const ConfigInfo<bool> GFX_HACK_EFB_ACCESS_ENABLE{{System::GFX, "Hacks", "EFBAccessEnable"}, true};
|
||||
const ConfigInfo<bool> GFX_HACK_BBOX_ENABLE{{System::GFX, "Hacks", "BBoxEnable"}, false};
|
||||
const ConfigInfo<bool> GFX_HACK_BBOX_PREFER_STENCIL_IMPLEMENTATION{
|
||||
{System::GFX, "Hacks", "BBoxPreferStencilImplementation"}, false};
|
||||
const ConfigInfo<bool> GFX_HACK_FORCE_PROGRESSIVE{{System::GFX, "Hacks", "ForceProgressive"}, true};
|
||||
const ConfigInfo<bool> GFX_HACK_SKIP_EFB_COPY_TO_RAM{{System::GFX, "Hacks", "EFBToTextureEnable"},
|
||||
true};
|
||||
|
||||
@@ -102,7 +102,6 @@ extern const ConfigInfo<int> GFX_STEREO_DEPTH_PERCENTAGE;
|
||||
|
||||
extern const ConfigInfo<bool> GFX_HACK_EFB_ACCESS_ENABLE;
|
||||
extern const ConfigInfo<bool> GFX_HACK_BBOX_ENABLE;
|
||||
extern const ConfigInfo<bool> GFX_HACK_BBOX_PREFER_STENCIL_IMPLEMENTATION;
|
||||
extern const ConfigInfo<bool> GFX_HACK_FORCE_PROGRESSIVE;
|
||||
extern const ConfigInfo<bool> GFX_HACK_SKIP_EFB_COPY_TO_RAM;
|
||||
extern const ConfigInfo<bool> GFX_HACK_SKIP_XFB_COPY_TO_RAM;
|
||||
|
||||
@@ -114,7 +114,6 @@ bool IsSettingSaveable(const Config::ConfigLocation& config_location)
|
||||
|
||||
Config::GFX_HACK_EFB_ACCESS_ENABLE.location,
|
||||
Config::GFX_HACK_BBOX_ENABLE.location,
|
||||
Config::GFX_HACK_BBOX_PREFER_STENCIL_IMPLEMENTATION.location,
|
||||
Config::GFX_HACK_FORCE_PROGRESSIVE.location,
|
||||
Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM.location,
|
||||
Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM.location,
|
||||
|
||||
@@ -152,10 +152,9 @@ void EnhancementsWidget::ConnectWidgets()
|
||||
void EnhancementsWidget::LoadPPShaders()
|
||||
{
|
||||
const bool anaglyph = g_Config.stereo_mode == StereoMode::Anaglyph;
|
||||
std::vector<std::string> shaders =
|
||||
anaglyph ? PostProcessingShaderImplementation::GetAnaglyphShaderList(
|
||||
g_Config.backend_info.api_type) :
|
||||
PostProcessingShaderImplementation::GetShaderList(g_Config.backend_info.api_type);
|
||||
std::vector<std::string> shaders = anaglyph ?
|
||||
VideoCommon::PostProcessing::GetAnaglyphShaderList() :
|
||||
VideoCommon::PostProcessing::GetShaderList();
|
||||
|
||||
m_pp_effect->clear();
|
||||
|
||||
@@ -187,7 +186,7 @@ void EnhancementsWidget::LoadPPShaders()
|
||||
tr("%1 doesn't support this feature.")
|
||||
.arg(tr(g_video_backend->GetDisplayName().c_str())));
|
||||
|
||||
PostProcessingShaderConfiguration pp_shader;
|
||||
VideoCommon::PostProcessingConfiguration pp_shader;
|
||||
if (selected_shader != "(off)" && supports_postprocessing)
|
||||
{
|
||||
pp_shader.LoadShader(selected_shader);
|
||||
@@ -266,7 +265,7 @@ void EnhancementsWidget::SaveSettings()
|
||||
"(off)" :
|
||||
m_pp_effect->currentText().toStdString());
|
||||
|
||||
PostProcessingShaderConfiguration pp_shader;
|
||||
VideoCommon::PostProcessingConfiguration pp_shader;
|
||||
if (Config::Get(Config::GFX_ENHANCE_POST_SHADER) != "(off)")
|
||||
{
|
||||
pp_shader.LoadShader(Config::Get(Config::GFX_ENHANCE_POST_SHADER));
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
using ConfigurationOption = PostProcessingShaderConfiguration::ConfigurationOption;
|
||||
using ConfigurationOption = VideoCommon::PostProcessingConfiguration::ConfigurationOption;
|
||||
using OptionType = ConfigurationOption::OptionType;
|
||||
|
||||
PostProcessingConfigWindow::PostProcessingConfigWindow(EnhancementsWidget* parent,
|
||||
@@ -38,7 +38,7 @@ PostProcessingConfigWindow::PostProcessingConfigWindow(EnhancementsWidget* paren
|
||||
}
|
||||
else
|
||||
{
|
||||
m_post_processor = new PostProcessingShaderConfiguration();
|
||||
m_post_processor = new VideoCommon::PostProcessingConfiguration();
|
||||
m_post_processor->LoadShader(m_shader);
|
||||
}
|
||||
|
||||
@@ -61,7 +61,8 @@ PostProcessingConfigWindow::~PostProcessingConfigWindow()
|
||||
|
||||
void PostProcessingConfigWindow::PopulateGroups()
|
||||
{
|
||||
const PostProcessingShaderConfiguration::ConfigMap& config_map = m_post_processor->GetOptions();
|
||||
const VideoCommon::PostProcessingConfiguration::ConfigMap& config_map =
|
||||
m_post_processor->GetOptions();
|
||||
|
||||
auto config_groups = std::vector<std::unique_ptr<ConfigGroup>>();
|
||||
for (const auto& it : config_map)
|
||||
|
||||
@@ -35,7 +35,7 @@ private:
|
||||
{
|
||||
public:
|
||||
explicit ConfigGroup(
|
||||
const PostProcessingShaderConfiguration::ConfigurationOption* config_option);
|
||||
const VideoCommon::PostProcessingConfiguration::ConfigurationOption* config_option);
|
||||
|
||||
const std::string& GetGUIName() const noexcept;
|
||||
const std::string& GetParent() const noexcept;
|
||||
@@ -57,7 +57,7 @@ private:
|
||||
std::vector<QSlider*> m_sliders;
|
||||
std::vector<QLineEdit*> m_value_boxes;
|
||||
|
||||
const PostProcessingShaderConfiguration::ConfigurationOption* m_config_option;
|
||||
const VideoCommon::PostProcessingConfiguration::ConfigurationOption* m_config_option;
|
||||
std::vector<std::unique_ptr<ConfigGroup>> m_subgroups;
|
||||
};
|
||||
void Create();
|
||||
@@ -72,7 +72,7 @@ private:
|
||||
QDialogButtonBox* m_buttons;
|
||||
|
||||
const std::string& m_shader;
|
||||
PostProcessingShaderConfiguration* m_post_processor;
|
||||
VideoCommon::PostProcessingConfiguration* m_post_processor;
|
||||
std::unordered_map<std::string, ConfigGroup*> m_config_map;
|
||||
std::vector<std::unique_ptr<ConfigGroup>> m_config_groups;
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "VideoBackends/D3D/BoundingBox.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "VideoBackends/D3D/D3DState.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
namespace DX11
|
||||
@@ -54,6 +55,7 @@ void BBox::Init()
|
||||
hr = D3D::device->CreateUnorderedAccessView(s_bbox_buffer, &UAVdesc, &s_bbox_uav);
|
||||
CHECK(SUCCEEDED(hr), "Create BoundingBox UAV.");
|
||||
D3D::SetDebugObjectName(s_bbox_uav, "BoundingBox UAV");
|
||||
D3D::stateman->SetOMUAV(s_bbox_uav);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,4 +85,4 @@ int BBox::Get(int index)
|
||||
D3D::context->Unmap(s_bbox_staging_buffer, 0);
|
||||
return data;
|
||||
}
|
||||
};
|
||||
}; // namespace DX11
|
||||
|
||||
@@ -3,42 +3,22 @@ add_library(videod3d
|
||||
BoundingBox.h
|
||||
D3DBase.cpp
|
||||
D3DBase.h
|
||||
D3DBlob.cpp
|
||||
D3DBlob.h
|
||||
D3DShader.cpp
|
||||
D3DShader.h
|
||||
D3DState.cpp
|
||||
D3DState.h
|
||||
D3DTexture.cpp
|
||||
D3DTexture.h
|
||||
D3DUtil.cpp
|
||||
D3DUtil.h
|
||||
DXPipeline.cpp
|
||||
DXPipeline.h
|
||||
DXShader.cpp
|
||||
DXShader.h
|
||||
DXTexture.cpp
|
||||
DXTexture.h
|
||||
FramebufferManager.cpp
|
||||
FramebufferManager.h
|
||||
GeometryShaderCache.cpp
|
||||
GeometryShaderCache.h
|
||||
main.cpp
|
||||
NativeVertexFormat.cpp
|
||||
PerfQuery.cpp
|
||||
PerfQuery.h
|
||||
PixelShaderCache.cpp
|
||||
PixelShaderCache.h
|
||||
PSTextureEncoder.cpp
|
||||
PSTextureEncoder.h
|
||||
Render.cpp
|
||||
Render.h
|
||||
TextureCache.cpp
|
||||
TextureCache.h
|
||||
VertexManager.cpp
|
||||
VertexManager.h
|
||||
VertexShaderCache.cpp
|
||||
VertexShaderCache.h
|
||||
VideoBackend.h
|
||||
)
|
||||
|
||||
|
||||
@@ -38,46 +38,26 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="BoundingBox.cpp" />
|
||||
<ClCompile Include="D3DBase.cpp" />
|
||||
<ClCompile Include="D3DBlob.cpp" />
|
||||
<ClCompile Include="D3DShader.cpp" />
|
||||
<ClCompile Include="D3DState.cpp" />
|
||||
<ClCompile Include="D3DTexture.cpp" />
|
||||
<ClCompile Include="D3DUtil.cpp" />
|
||||
<ClCompile Include="DXPipeline.cpp" />
|
||||
<ClCompile Include="DXShader.cpp" />
|
||||
<ClCompile Include="DXTexture.cpp" />
|
||||
<ClCompile Include="FramebufferManager.cpp" />
|
||||
<ClCompile Include="GeometryShaderCache.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="NativeVertexFormat.cpp" />
|
||||
<ClCompile Include="PerfQuery.cpp" />
|
||||
<ClCompile Include="PixelShaderCache.cpp" />
|
||||
<ClCompile Include="PSTextureEncoder.cpp" />
|
||||
<ClCompile Include="Render.cpp" />
|
||||
<ClCompile Include="TextureCache.cpp" />
|
||||
<ClCompile Include="VertexManager.cpp" />
|
||||
<ClCompile Include="VertexShaderCache.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="BoundingBox.h" />
|
||||
<ClInclude Include="D3DBase.h" />
|
||||
<ClInclude Include="D3DBlob.h" />
|
||||
<ClInclude Include="D3DShader.h" />
|
||||
<ClInclude Include="D3DState.h" />
|
||||
<ClInclude Include="D3DTexture.h" />
|
||||
<ClInclude Include="D3DUtil.h" />
|
||||
<ClInclude Include="DXPipeline.h" />
|
||||
<ClInclude Include="DXShader.h" />
|
||||
<ClInclude Include="DXTexture.h" />
|
||||
<ClInclude Include="FramebufferManager.h" />
|
||||
<ClInclude Include="GeometryShaderCache.h" />
|
||||
<ClInclude Include="PerfQuery.h" />
|
||||
<ClInclude Include="PixelShaderCache.h" />
|
||||
<ClInclude Include="PSTextureEncoder.h" />
|
||||
<ClInclude Include="Render.h" />
|
||||
<ClInclude Include="TextureCache.h" />
|
||||
<ClInclude Include="VertexManager.h" />
|
||||
<ClInclude Include="VertexShaderCache.h" />
|
||||
<ClInclude Include="VideoBackend.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -12,51 +12,21 @@
|
||||
<ClCompile Include="D3DBase.cpp">
|
||||
<Filter>D3D</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="D3DBlob.cpp">
|
||||
<Filter>D3D</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="D3DShader.cpp">
|
||||
<Filter>D3D</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="D3DTexture.cpp">
|
||||
<Filter>D3D</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="D3DUtil.cpp">
|
||||
<Filter>D3D</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="D3DState.cpp">
|
||||
<Filter>D3D</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FramebufferManager.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeometryShaderCache.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NativeVertexFormat.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PerfQuery.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PixelShaderCache.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PSTextureEncoder.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Render.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TextureCache.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VertexManager.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VertexShaderCache.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="BoundingBox.cpp">
|
||||
<Filter>Render</Filter>
|
||||
@@ -75,48 +45,18 @@
|
||||
<ClInclude Include="D3DBase.h">
|
||||
<Filter>D3D</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3DBlob.h">
|
||||
<Filter>D3D</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3DShader.h">
|
||||
<Filter>D3D</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3DTexture.h">
|
||||
<Filter>D3D</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3DUtil.h">
|
||||
<Filter>D3D</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3DState.h">
|
||||
<Filter>D3D</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FramebufferManager.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GeometryShaderCache.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PerfQuery.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PixelShaderCache.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PSTextureEncoder.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Render.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TextureCache.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="VertexManager.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="VertexShaderCache.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="VideoBackend.h" />
|
||||
<ClInclude Include="BoundingBox.h">
|
||||
<Filter>Render</Filter>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "VideoBackends/D3D/D3DBase.h"
|
||||
#include "VideoBackends/D3D/D3DState.h"
|
||||
#include "VideoBackends/D3D/D3DTexture.h"
|
||||
#include "VideoBackends/D3D/DXTexture.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
namespace DX11
|
||||
@@ -42,7 +42,8 @@ IDXGISwapChain1* swapchain = nullptr;
|
||||
static IDXGIFactory2* s_dxgi_factory;
|
||||
static ID3D11Debug* s_debug;
|
||||
static D3D_FEATURE_LEVEL s_featlevel;
|
||||
static D3DTexture2D* s_backbuf;
|
||||
static std::unique_ptr<DXTexture> s_swap_chain_texture;
|
||||
static std::unique_ptr<DXFramebuffer> s_swap_chain_framebuffer;
|
||||
|
||||
static std::vector<DXGI_SAMPLE_DESC> s_aa_modes; // supported AA modes of the current adapter
|
||||
|
||||
@@ -244,18 +245,40 @@ static bool SupportsBPTCTextures(ID3D11Device* dev)
|
||||
return (bc7_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
|
||||
}
|
||||
|
||||
static bool CreateSwapChainTextures()
|
||||
static bool CreateSwapChainFramebuffer()
|
||||
{
|
||||
ID3D11Texture2D* buf;
|
||||
HRESULT hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf);
|
||||
ID3D11Texture2D* texture;
|
||||
HRESULT hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&texture);
|
||||
CHECK(SUCCEEDED(hr), "GetBuffer for swap chain failed with HRESULT %08X", hr);
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
s_backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
|
||||
SAFE_RELEASE(buf);
|
||||
SetDebugObjectName(s_backbuf->GetTex(), "backbuffer texture");
|
||||
SetDebugObjectName(s_backbuf->GetRTV(), "backbuffer render target view");
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
texture->GetDesc(&desc);
|
||||
|
||||
s_swap_chain_texture = std::make_unique<DXTexture>(
|
||||
TextureConfig(desc.Width, desc.Height, desc.MipLevels, desc.ArraySize, desc.SampleDesc.Count,
|
||||
AbstractTextureFormat::RGBA8, AbstractTextureFlag_RenderTarget),
|
||||
texture, nullptr, nullptr);
|
||||
|
||||
ID3D11RenderTargetView* rtv;
|
||||
CD3D11_RENDER_TARGET_VIEW_DESC rtv_desc(texture, D3D11_RTV_DIMENSION_TEXTURE2DARRAY, desc.Format,
|
||||
0, 0, desc.ArraySize);
|
||||
hr = device->CreateRenderTargetView(texture, &rtv_desc, &rtv);
|
||||
CHECK(SUCCEEDED(hr), "Create render target view for swap chain");
|
||||
if (FAILED(hr))
|
||||
{
|
||||
s_swap_chain_texture.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
SetDebugObjectName(texture, "backbuffer texture");
|
||||
SetDebugObjectName(rtv, "backbuffer render target view");
|
||||
s_swap_chain_framebuffer = std::make_unique<DXFramebuffer>(
|
||||
s_swap_chain_texture.get(), nullptr, AbstractTextureFormat::RGBA8,
|
||||
AbstractTextureFormat::Undefined, desc.Width, desc.Height, desc.ArraySize,
|
||||
desc.SampleDesc.Count, rtv, nullptr, nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -300,7 +323,7 @@ static bool CreateSwapChain(HWND hWnd)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CreateSwapChainTextures())
|
||||
if (!CreateSwapChainFramebuffer())
|
||||
{
|
||||
SAFE_RELEASE(swapchain);
|
||||
return false;
|
||||
@@ -451,7 +474,8 @@ void Close()
|
||||
|
||||
// release all bound resources
|
||||
context->ClearState();
|
||||
SAFE_RELEASE(s_backbuf);
|
||||
s_swap_chain_framebuffer.reset();
|
||||
s_swap_chain_texture.reset();
|
||||
SAFE_RELEASE(swapchain);
|
||||
SAFE_DELETE(stateman);
|
||||
context->Flush(); // immediately destroy device objects
|
||||
@@ -527,9 +551,13 @@ const char* ComputeShaderVersionString()
|
||||
return "cs_4_0";
|
||||
}
|
||||
|
||||
D3DTexture2D* GetBackBuffer()
|
||||
DXTexture* GetSwapChainTexture()
|
||||
{
|
||||
return s_backbuf;
|
||||
return s_swap_chain_texture.get();
|
||||
}
|
||||
DXFramebuffer* GetSwapChainFramebuffer()
|
||||
{
|
||||
return s_swap_chain_framebuffer.get();
|
||||
}
|
||||
bool BGRATexturesSupported()
|
||||
{
|
||||
@@ -568,7 +596,8 @@ u32 GetMaxTextureSize(D3D_FEATURE_LEVEL feature_level)
|
||||
|
||||
void Reset(HWND new_wnd)
|
||||
{
|
||||
SAFE_RELEASE(s_backbuf);
|
||||
s_swap_chain_framebuffer.reset();
|
||||
s_swap_chain_texture.reset();
|
||||
|
||||
if (swapchain)
|
||||
{
|
||||
@@ -583,10 +612,11 @@ void Reset(HWND new_wnd)
|
||||
|
||||
void ResizeSwapChain()
|
||||
{
|
||||
SAFE_RELEASE(s_backbuf);
|
||||
s_swap_chain_framebuffer.reset();
|
||||
s_swap_chain_texture.reset();
|
||||
const UINT swap_chain_flags = AllowTearingSupported() ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;
|
||||
swapchain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_R8G8B8A8_UNORM, swap_chain_flags);
|
||||
if (!CreateSwapChainTextures())
|
||||
if (!CreateSwapChainFramebuffer())
|
||||
{
|
||||
PanicAlert("Failed to get swap chain textures");
|
||||
SAFE_RELEASE(swapchain);
|
||||
|
||||
@@ -38,7 +38,8 @@ namespace DX11
|
||||
PanicAlert("%s failed in %s at line %d: " Message, __func__, __FILE__, __LINE__, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
class D3DTexture2D;
|
||||
class DXTexture;
|
||||
class DXFramebuffer;
|
||||
|
||||
namespace D3D
|
||||
{
|
||||
@@ -64,7 +65,8 @@ void Reset(HWND new_wnd);
|
||||
void ResizeSwapChain();
|
||||
void Present();
|
||||
|
||||
D3DTexture2D* GetBackBuffer();
|
||||
DXTexture* GetSwapChainTexture();
|
||||
DXFramebuffer* GetSwapChainFramebuffer();
|
||||
const char* PixelShaderVersionString();
|
||||
const char* GeometryShaderVersionString();
|
||||
const char* VertexShaderVersionString();
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
// Copyright 2010 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
#include "VideoBackends/D3D/D3DBlob.h"
|
||||
|
||||
namespace DX11
|
||||
{
|
||||
D3DBlob::D3DBlob(unsigned int blob_size, const u8* init_data)
|
||||
: ref(1), size(blob_size), blob(nullptr)
|
||||
{
|
||||
data = new u8[blob_size];
|
||||
if (init_data)
|
||||
memcpy(data, init_data, size);
|
||||
}
|
||||
|
||||
D3DBlob::D3DBlob(ID3D10Blob* d3dblob) : ref(1)
|
||||
{
|
||||
blob = d3dblob;
|
||||
data = (u8*)blob->GetBufferPointer();
|
||||
size = (unsigned int)blob->GetBufferSize();
|
||||
d3dblob->AddRef();
|
||||
}
|
||||
|
||||
D3DBlob::~D3DBlob()
|
||||
{
|
||||
if (blob)
|
||||
blob->Release();
|
||||
else
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void D3DBlob::AddRef()
|
||||
{
|
||||
++ref;
|
||||
}
|
||||
|
||||
unsigned int D3DBlob::Release()
|
||||
{
|
||||
if (--ref == 0)
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
unsigned int D3DBlob::Size() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
u8* D3DBlob::Data()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
} // namespace DX11
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright 2008 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
struct ID3D10Blob;
|
||||
|
||||
namespace DX11
|
||||
{
|
||||
// use this class instead ID3D10Blob or ID3D11Blob whenever possible
|
||||
class D3DBlob
|
||||
{
|
||||
public:
|
||||
// memory will be copied into an own buffer
|
||||
D3DBlob(unsigned int blob_size, const u8* init_data = nullptr);
|
||||
|
||||
// d3dblob will be AddRef'd
|
||||
D3DBlob(ID3D10Blob* d3dblob);
|
||||
|
||||
void AddRef();
|
||||
unsigned int Release();
|
||||
|
||||
unsigned int Size() const;
|
||||
u8* Data();
|
||||
|
||||
private:
|
||||
~D3DBlob();
|
||||
|
||||
unsigned int ref;
|
||||
unsigned int size;
|
||||
|
||||
u8* data;
|
||||
ID3D10Blob* blob;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -1,304 +0,0 @@
|
||||
// Copyright 2010 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "VideoBackends/D3D/D3DBase.h"
|
||||
#include "VideoBackends/D3D/D3DShader.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
namespace DX11
|
||||
{
|
||||
namespace D3D
|
||||
{
|
||||
// bytecode->shader
|
||||
ID3D11VertexShader* CreateVertexShaderFromByteCode(const void* bytecode, size_t len)
|
||||
{
|
||||
ID3D11VertexShader* v_shader;
|
||||
HRESULT hr = D3D::device->CreateVertexShader(bytecode, len, nullptr, &v_shader);
|
||||
if (FAILED(hr))
|
||||
return nullptr;
|
||||
|
||||
return v_shader;
|
||||
}
|
||||
|
||||
// code->bytecode
|
||||
bool CompileVertexShader(const std::string& code, D3DBlob** blob)
|
||||
{
|
||||
ID3D10Blob* shaderBuffer = nullptr;
|
||||
ID3D10Blob* errorBuffer = nullptr;
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY | D3D10_SHADER_DEBUG;
|
||||
#else
|
||||
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY | D3D10_SHADER_OPTIMIZATION_LEVEL3 |
|
||||
D3D10_SHADER_SKIP_VALIDATION;
|
||||
#endif
|
||||
HRESULT hr = PD3DCompile(code.c_str(), code.length(), nullptr, nullptr, nullptr, "main",
|
||||
D3D::VertexShaderVersionString(), flags, 0, &shaderBuffer, &errorBuffer);
|
||||
if (errorBuffer)
|
||||
{
|
||||
INFO_LOG(VIDEO, "Vertex shader compiler messages:\n%s",
|
||||
(const char*)errorBuffer->GetBufferPointer());
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
static int num_failures = 0;
|
||||
std::string filename = StringFromFormat("%sbad_vs_%04i.txt",
|
||||
File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++);
|
||||
std::ofstream file;
|
||||
File::OpenFStream(file, filename, std::ios_base::out);
|
||||
file << code;
|
||||
file.close();
|
||||
|
||||
PanicAlert("Failed to compile vertex shader: %s\nDebug info (%s):\n%s", filename.c_str(),
|
||||
D3D::VertexShaderVersionString(), (const char*)errorBuffer->GetBufferPointer());
|
||||
|
||||
*blob = nullptr;
|
||||
errorBuffer->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
*blob = new D3DBlob(shaderBuffer);
|
||||
shaderBuffer->Release();
|
||||
}
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
// bytecode->shader
|
||||
ID3D11GeometryShader* CreateGeometryShaderFromByteCode(const void* bytecode, size_t len)
|
||||
{
|
||||
ID3D11GeometryShader* g_shader;
|
||||
HRESULT hr = D3D::device->CreateGeometryShader(bytecode, len, nullptr, &g_shader);
|
||||
if (FAILED(hr))
|
||||
return nullptr;
|
||||
|
||||
return g_shader;
|
||||
}
|
||||
|
||||
// code->bytecode
|
||||
bool CompileGeometryShader(const std::string& code, D3DBlob** blob,
|
||||
const D3D_SHADER_MACRO* pDefines)
|
||||
{
|
||||
ID3D10Blob* shaderBuffer = nullptr;
|
||||
ID3D10Blob* errorBuffer = nullptr;
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY | D3D10_SHADER_DEBUG;
|
||||
#else
|
||||
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY | D3D10_SHADER_OPTIMIZATION_LEVEL3 |
|
||||
D3D10_SHADER_SKIP_VALIDATION;
|
||||
#endif
|
||||
HRESULT hr =
|
||||
PD3DCompile(code.c_str(), code.length(), nullptr, pDefines, nullptr, "main",
|
||||
D3D::GeometryShaderVersionString(), flags, 0, &shaderBuffer, &errorBuffer);
|
||||
|
||||
if (errorBuffer)
|
||||
{
|
||||
INFO_LOG(VIDEO, "Geometry shader compiler messages:\n%s",
|
||||
(const char*)errorBuffer->GetBufferPointer());
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
static int num_failures = 0;
|
||||
std::string filename = StringFromFormat("%sbad_gs_%04i.txt",
|
||||
File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++);
|
||||
std::ofstream file;
|
||||
File::OpenFStream(file, filename, std::ios_base::out);
|
||||
file << code;
|
||||
file.close();
|
||||
|
||||
PanicAlert("Failed to compile geometry shader: %s\nDebug info (%s):\n%s", filename.c_str(),
|
||||
D3D::GeometryShaderVersionString(), (const char*)errorBuffer->GetBufferPointer());
|
||||
|
||||
*blob = nullptr;
|
||||
errorBuffer->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
*blob = new D3DBlob(shaderBuffer);
|
||||
shaderBuffer->Release();
|
||||
}
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
// bytecode->shader
|
||||
ID3D11PixelShader* CreatePixelShaderFromByteCode(const void* bytecode, size_t len)
|
||||
{
|
||||
ID3D11PixelShader* p_shader;
|
||||
HRESULT hr = D3D::device->CreatePixelShader(bytecode, len, nullptr, &p_shader);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
PanicAlert("CreatePixelShaderFromByteCode failed at %s %d\n", __FILE__, __LINE__);
|
||||
p_shader = nullptr;
|
||||
}
|
||||
return p_shader;
|
||||
}
|
||||
|
||||
// code->bytecode
|
||||
bool CompilePixelShader(const std::string& code, D3DBlob** blob, const D3D_SHADER_MACRO* pDefines)
|
||||
{
|
||||
ID3D10Blob* shaderBuffer = nullptr;
|
||||
ID3D10Blob* errorBuffer = nullptr;
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
UINT flags = D3D10_SHADER_DEBUG;
|
||||
#else
|
||||
UINT flags = D3D10_SHADER_OPTIMIZATION_LEVEL3;
|
||||
#endif
|
||||
HRESULT hr = PD3DCompile(code.c_str(), code.length(), nullptr, pDefines, nullptr, "main",
|
||||
D3D::PixelShaderVersionString(), flags, 0, &shaderBuffer, &errorBuffer);
|
||||
|
||||
if (errorBuffer)
|
||||
{
|
||||
INFO_LOG(VIDEO, "Pixel shader compiler messages:\n%s",
|
||||
(const char*)errorBuffer->GetBufferPointer());
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
static int num_failures = 0;
|
||||
std::string filename = StringFromFormat("%sbad_ps_%04i.txt",
|
||||
File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++);
|
||||
std::ofstream file;
|
||||
File::OpenFStream(file, filename, std::ios_base::out);
|
||||
file << code;
|
||||
file.close();
|
||||
|
||||
PanicAlert("Failed to compile pixel shader: %s\nDebug info (%s):\n%s", filename.c_str(),
|
||||
D3D::PixelShaderVersionString(), (const char*)errorBuffer->GetBufferPointer());
|
||||
|
||||
*blob = nullptr;
|
||||
errorBuffer->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
*blob = new D3DBlob(shaderBuffer);
|
||||
shaderBuffer->Release();
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
// bytecode->shader
|
||||
ID3D11ComputeShader* CreateComputeShaderFromByteCode(const void* bytecode, size_t len)
|
||||
{
|
||||
ID3D11ComputeShader* shader;
|
||||
HRESULT hr = D3D::device->CreateComputeShader(bytecode, len, nullptr, &shader);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
PanicAlert("CreateComputeShaderFromByteCode failed at %s %d\n", __FILE__, __LINE__);
|
||||
return nullptr;
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
// code->bytecode
|
||||
bool CompileComputeShader(const std::string& code, D3DBlob** blob, const D3D_SHADER_MACRO* pDefines)
|
||||
{
|
||||
ID3D10Blob* shaderBuffer = nullptr;
|
||||
ID3D10Blob* errorBuffer = nullptr;
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
UINT flags = D3D10_SHADER_DEBUG;
|
||||
#else
|
||||
UINT flags = D3D10_SHADER_OPTIMIZATION_LEVEL3;
|
||||
#endif
|
||||
HRESULT hr =
|
||||
PD3DCompile(code.c_str(), code.length(), nullptr, pDefines, nullptr, "main",
|
||||
D3D::ComputeShaderVersionString(), flags, 0, &shaderBuffer, &errorBuffer);
|
||||
|
||||
if (errorBuffer)
|
||||
{
|
||||
INFO_LOG(VIDEO, "Compute shader compiler messages:\n%s",
|
||||
(const char*)errorBuffer->GetBufferPointer());
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
static int num_failures = 0;
|
||||
std::string filename = StringFromFormat("%sbad_cs_%04i.txt",
|
||||
File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++);
|
||||
std::ofstream file;
|
||||
File::OpenFStream(file, filename, std::ios_base::out);
|
||||
file << code;
|
||||
file.close();
|
||||
|
||||
PanicAlert("Failed to compile compute shader: %s\nDebug info (%s):\n%s", filename.c_str(),
|
||||
D3D::ComputeShaderVersionString(),
|
||||
reinterpret_cast<const char*>(errorBuffer->GetBufferPointer()));
|
||||
|
||||
*blob = nullptr;
|
||||
errorBuffer->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
*blob = new D3DBlob(shaderBuffer);
|
||||
shaderBuffer->Release();
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
ID3D11VertexShader* CompileAndCreateVertexShader(const std::string& code)
|
||||
{
|
||||
D3DBlob* blob = nullptr;
|
||||
if (CompileVertexShader(code, &blob))
|
||||
{
|
||||
ID3D11VertexShader* v_shader = CreateVertexShaderFromByteCode(blob);
|
||||
blob->Release();
|
||||
return v_shader;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ID3D11GeometryShader* CompileAndCreateGeometryShader(const std::string& code,
|
||||
const D3D_SHADER_MACRO* pDefines)
|
||||
{
|
||||
D3DBlob* blob = nullptr;
|
||||
if (CompileGeometryShader(code, &blob, pDefines))
|
||||
{
|
||||
ID3D11GeometryShader* g_shader = CreateGeometryShaderFromByteCode(blob);
|
||||
blob->Release();
|
||||
return g_shader;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ID3D11PixelShader* CompileAndCreatePixelShader(const std::string& code)
|
||||
{
|
||||
D3DBlob* blob = nullptr;
|
||||
CompilePixelShader(code, &blob);
|
||||
if (blob)
|
||||
{
|
||||
ID3D11PixelShader* p_shader = CreatePixelShaderFromByteCode(blob);
|
||||
blob->Release();
|
||||
return p_shader;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ID3D11ComputeShader* CompileAndCreateComputeShader(const std::string& code)
|
||||
{
|
||||
D3DBlob* blob = nullptr;
|
||||
CompileComputeShader(code, &blob);
|
||||
if (blob)
|
||||
{
|
||||
ID3D11ComputeShader* shader = CreateComputeShaderFromByteCode(blob);
|
||||
blob->Release();
|
||||
return shader;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace DX11
|
||||
@@ -1,78 +0,0 @@
|
||||
// Copyright 2010 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "VideoBackends/D3D/D3DBase.h"
|
||||
#include "VideoBackends/D3D/D3DBlob.h"
|
||||
|
||||
struct ID3D11PixelShader;
|
||||
struct ID3D11VertexShader;
|
||||
|
||||
namespace DX11
|
||||
{
|
||||
namespace D3D
|
||||
{
|
||||
ID3D11VertexShader* CreateVertexShaderFromByteCode(const void* bytecode, size_t len);
|
||||
ID3D11GeometryShader* CreateGeometryShaderFromByteCode(const void* bytecode, size_t len);
|
||||
ID3D11PixelShader* CreatePixelShaderFromByteCode(const void* bytecode, size_t len);
|
||||
ID3D11ComputeShader* CreateComputeShaderFromByteCode(const void* bytecode, size_t len);
|
||||
|
||||
// The returned bytecode buffers should be Release()d.
|
||||
bool CompileVertexShader(const std::string& code, D3DBlob** blob);
|
||||
bool CompileGeometryShader(const std::string& code, D3DBlob** blob,
|
||||
const D3D_SHADER_MACRO* pDefines = nullptr);
|
||||
bool CompilePixelShader(const std::string& code, D3DBlob** blob,
|
||||
const D3D_SHADER_MACRO* pDefines = nullptr);
|
||||
bool CompileComputeShader(const std::string& code, D3DBlob** blob,
|
||||
const D3D_SHADER_MACRO* pDefines = nullptr);
|
||||
|
||||
// Utility functions
|
||||
ID3D11VertexShader* CompileAndCreateVertexShader(const std::string& code);
|
||||
ID3D11GeometryShader* CompileAndCreateGeometryShader(const std::string& code,
|
||||
const D3D_SHADER_MACRO* pDefines = nullptr);
|
||||
ID3D11PixelShader* CompileAndCreatePixelShader(const std::string& code);
|
||||
ID3D11ComputeShader* CompileAndCreateComputeShader(const std::string& code);
|
||||
|
||||
inline ID3D11VertexShader* CreateVertexShaderFromByteCode(D3DBlob* bytecode)
|
||||
{
|
||||
return CreateVertexShaderFromByteCode(bytecode->Data(), bytecode->Size());
|
||||
}
|
||||
inline ID3D11GeometryShader* CreateGeometryShaderFromByteCode(D3DBlob* bytecode)
|
||||
{
|
||||
return CreateGeometryShaderFromByteCode(bytecode->Data(), bytecode->Size());
|
||||
}
|
||||
inline ID3D11PixelShader* CreatePixelShaderFromByteCode(D3DBlob* bytecode)
|
||||
{
|
||||
return CreatePixelShaderFromByteCode(bytecode->Data(), bytecode->Size());
|
||||
}
|
||||
inline ID3D11ComputeShader* CreateComputeShaderFromByteCode(D3DBlob* bytecode)
|
||||
{
|
||||
return CreateComputeShaderFromByteCode(bytecode->Data(), bytecode->Size());
|
||||
}
|
||||
|
||||
inline ID3D11VertexShader* CompileAndCreateVertexShader(D3DBlob* code)
|
||||
{
|
||||
return CompileAndCreateVertexShader(reinterpret_cast<const char*>(code->Data()));
|
||||
}
|
||||
|
||||
inline ID3D11GeometryShader*
|
||||
CompileAndCreateGeometryShader(D3DBlob* code, const D3D_SHADER_MACRO* pDefines = nullptr)
|
||||
{
|
||||
return CompileAndCreateGeometryShader(reinterpret_cast<const char*>(code->Data()), pDefines);
|
||||
}
|
||||
|
||||
inline ID3D11PixelShader* CompileAndCreatePixelShader(D3DBlob* code)
|
||||
{
|
||||
return CompileAndCreatePixelShader(reinterpret_cast<const char*>(code->Data()));
|
||||
}
|
||||
inline ID3D11ComputeShader* CompileAndCreateComputeShader(D3DBlob* code)
|
||||
{
|
||||
return CompileAndCreateComputeShader(reinterpret_cast<const char*>(code->Data()));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace DX11
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "VideoBackends/D3D/D3DBase.h"
|
||||
#include "VideoBackends/D3D/D3DState.h"
|
||||
#include "VideoBackends/D3D/DXTexture.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
namespace DX11
|
||||
@@ -28,19 +29,31 @@ void StateManager::Apply()
|
||||
if (!m_dirtyFlags)
|
||||
return;
|
||||
|
||||
const int textureMaskShift = Common::LeastSignificantSetBit((u32)DirtyFlag_Texture0);
|
||||
const int samplerMaskShift = Common::LeastSignificantSetBit((u32)DirtyFlag_Sampler0);
|
||||
// Framebuffer changes must occur before texture changes, otherwise the D3D runtime messes with
|
||||
// our bindings and sets them to null to prevent hazards.
|
||||
if (m_dirtyFlags & DirtyFlag_Framebuffer)
|
||||
{
|
||||
if (g_ActiveConfig.backend_info.bSupportsBBox)
|
||||
{
|
||||
D3D::context->OMSetRenderTargetsAndUnorderedAccessViews(
|
||||
m_pending.framebuffer->GetNumRTVs(),
|
||||
m_pending.use_integer_rtv ? m_pending.framebuffer->GetIntegerRTVArray() :
|
||||
m_pending.framebuffer->GetRTVArray(),
|
||||
m_pending.framebuffer->GetDSV(), 2, 1, &m_pending.uav, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D::context->OMSetRenderTargets(m_pending.framebuffer->GetNumRTVs(),
|
||||
m_pending.use_integer_rtv ?
|
||||
m_pending.framebuffer->GetIntegerRTVArray() :
|
||||
m_pending.framebuffer->GetRTVArray(),
|
||||
m_pending.framebuffer->GetDSV());
|
||||
}
|
||||
m_current.framebuffer = m_pending.framebuffer;
|
||||
m_current.uav = m_pending.uav;
|
||||
m_current.use_integer_rtv = m_pending.use_integer_rtv;
|
||||
}
|
||||
|
||||
u32 dirtyTextures =
|
||||
(m_dirtyFlags &
|
||||
(DirtyFlag_Texture0 | DirtyFlag_Texture1 | DirtyFlag_Texture2 | DirtyFlag_Texture3 |
|
||||
DirtyFlag_Texture4 | DirtyFlag_Texture5 | DirtyFlag_Texture6 | DirtyFlag_Texture7)) >>
|
||||
textureMaskShift;
|
||||
u32 dirtySamplers =
|
||||
(m_dirtyFlags &
|
||||
(DirtyFlag_Sampler0 | DirtyFlag_Sampler1 | DirtyFlag_Sampler2 | DirtyFlag_Sampler3 |
|
||||
DirtyFlag_Sampler4 | DirtyFlag_Sampler5 | DirtyFlag_Sampler6 | DirtyFlag_Sampler7)) >>
|
||||
samplerMaskShift;
|
||||
u32 dirtyConstants = m_dirtyFlags & (DirtyFlag_PixelConstants | DirtyFlag_VertexConstants |
|
||||
DirtyFlag_GeometryConstants);
|
||||
u32 dirtyShaders =
|
||||
@@ -103,30 +116,6 @@ void StateManager::Apply()
|
||||
}
|
||||
}
|
||||
|
||||
while (dirtyTextures)
|
||||
{
|
||||
const int index = Common::LeastSignificantSetBit(dirtyTextures);
|
||||
if (m_current.textures[index] != m_pending.textures[index])
|
||||
{
|
||||
D3D::context->PSSetShaderResources(index, 1, &m_pending.textures[index]);
|
||||
m_current.textures[index] = m_pending.textures[index];
|
||||
}
|
||||
|
||||
dirtyTextures &= ~(1 << index);
|
||||
}
|
||||
|
||||
while (dirtySamplers)
|
||||
{
|
||||
const int index = Common::LeastSignificantSetBit(dirtySamplers);
|
||||
if (m_current.samplers[index] != m_pending.samplers[index])
|
||||
{
|
||||
D3D::context->PSSetSamplers(index, 1, &m_pending.samplers[index]);
|
||||
m_current.samplers[index] = m_pending.samplers[index];
|
||||
}
|
||||
|
||||
dirtySamplers &= ~(1 << index);
|
||||
}
|
||||
|
||||
if (dirtyShaders)
|
||||
{
|
||||
if (m_current.pixelShader != m_pending.pixelShader)
|
||||
@@ -164,9 +153,51 @@ void StateManager::Apply()
|
||||
m_current.rasterizerState = m_pending.rasterizerState;
|
||||
}
|
||||
|
||||
ApplyTextures();
|
||||
|
||||
m_dirtyFlags = 0;
|
||||
}
|
||||
|
||||
void StateManager::ApplyTextures()
|
||||
{
|
||||
const int textureMaskShift = Common::LeastSignificantSetBit((u32)DirtyFlag_Texture0);
|
||||
const int samplerMaskShift = Common::LeastSignificantSetBit((u32)DirtyFlag_Sampler0);
|
||||
|
||||
u32 dirtyTextures =
|
||||
(m_dirtyFlags &
|
||||
(DirtyFlag_Texture0 | DirtyFlag_Texture1 | DirtyFlag_Texture2 | DirtyFlag_Texture3 |
|
||||
DirtyFlag_Texture4 | DirtyFlag_Texture5 | DirtyFlag_Texture6 | DirtyFlag_Texture7)) >>
|
||||
textureMaskShift;
|
||||
u32 dirtySamplers =
|
||||
(m_dirtyFlags &
|
||||
(DirtyFlag_Sampler0 | DirtyFlag_Sampler1 | DirtyFlag_Sampler2 | DirtyFlag_Sampler3 |
|
||||
DirtyFlag_Sampler4 | DirtyFlag_Sampler5 | DirtyFlag_Sampler6 | DirtyFlag_Sampler7)) >>
|
||||
samplerMaskShift;
|
||||
while (dirtyTextures)
|
||||
{
|
||||
const int index = Common::LeastSignificantSetBit(dirtyTextures);
|
||||
if (m_current.textures[index] != m_pending.textures[index])
|
||||
{
|
||||
D3D::context->PSSetShaderResources(index, 1, &m_pending.textures[index]);
|
||||
m_current.textures[index] = m_pending.textures[index];
|
||||
}
|
||||
|
||||
dirtyTextures &= ~(1 << index);
|
||||
}
|
||||
|
||||
while (dirtySamplers)
|
||||
{
|
||||
const int index = Common::LeastSignificantSetBit(dirtySamplers);
|
||||
if (m_current.samplers[index] != m_pending.samplers[index])
|
||||
{
|
||||
D3D::context->PSSetSamplers(index, 1, &m_pending.samplers[index]);
|
||||
m_current.samplers[index] = m_pending.samplers[index];
|
||||
}
|
||||
|
||||
dirtySamplers &= ~(1 << index);
|
||||
}
|
||||
}
|
||||
|
||||
u32 StateManager::UnsetTexture(ID3D11ShaderResourceView* srv)
|
||||
{
|
||||
u32 mask = 0;
|
||||
@@ -193,6 +224,78 @@ void StateManager::SetTextureByMask(u32 textureSlotMask, ID3D11ShaderResourceVie
|
||||
}
|
||||
}
|
||||
|
||||
void StateManager::SetComputeUAV(ID3D11UnorderedAccessView* uav)
|
||||
{
|
||||
if (m_compute_image == uav)
|
||||
return;
|
||||
|
||||
m_compute_image = uav;
|
||||
D3D::context->CSSetUnorderedAccessViews(0, 1, &uav, nullptr);
|
||||
}
|
||||
|
||||
void StateManager::SetComputeShader(ID3D11ComputeShader* shader)
|
||||
{
|
||||
if (m_compute_shader == shader)
|
||||
return;
|
||||
|
||||
m_compute_shader = shader;
|
||||
D3D::context->CSSetShader(shader, nullptr, 0);
|
||||
}
|
||||
|
||||
void StateManager::SyncComputeBindings()
|
||||
{
|
||||
if (m_compute_constants != m_pending.pixelConstants[0])
|
||||
{
|
||||
m_compute_constants = m_pending.pixelConstants[0];
|
||||
D3D::context->CSSetConstantBuffers(0, 1, &m_compute_constants);
|
||||
}
|
||||
|
||||
for (u32 start = 0; start < static_cast<u32>(m_compute_textures.size());)
|
||||
{
|
||||
if (m_compute_textures[start] == m_pending.textures[start])
|
||||
{
|
||||
start++;
|
||||
continue;
|
||||
}
|
||||
|
||||
m_compute_textures[start] = m_pending.textures[start];
|
||||
|
||||
u32 end = start + 1;
|
||||
for (; end < static_cast<u32>(m_compute_textures.size()); end++)
|
||||
{
|
||||
if (m_compute_textures[end] == m_pending.textures[end])
|
||||
break;
|
||||
|
||||
m_compute_textures[end] = m_pending.textures[end];
|
||||
}
|
||||
|
||||
D3D::context->CSSetShaderResources(start, end - start, &m_compute_textures[start]);
|
||||
start = end;
|
||||
}
|
||||
|
||||
for (u32 start = 0; start < static_cast<u32>(m_compute_samplers.size());)
|
||||
{
|
||||
if (m_compute_samplers[start] == m_pending.samplers[start])
|
||||
{
|
||||
start++;
|
||||
continue;
|
||||
}
|
||||
|
||||
m_compute_samplers[start] = m_pending.samplers[start];
|
||||
|
||||
u32 end = start + 1;
|
||||
for (; end < static_cast<u32>(m_compute_samplers.size()); end++)
|
||||
{
|
||||
if (m_compute_samplers[end] == m_pending.samplers[end])
|
||||
break;
|
||||
|
||||
m_compute_samplers[end] = m_pending.samplers[end];
|
||||
}
|
||||
|
||||
D3D::context->CSSetSamplers(start, end - start, &m_compute_samplers[start]);
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
} // namespace D3D
|
||||
|
||||
StateCache::~StateCache()
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
namespace DX11
|
||||
{
|
||||
class DXFramebuffer;
|
||||
|
||||
class StateCache
|
||||
{
|
||||
public:
|
||||
@@ -112,14 +114,6 @@ public:
|
||||
m_pending.geometryConstants = buffer;
|
||||
}
|
||||
|
||||
void SetComputeConstants(ID3D11Buffer* buffer)
|
||||
{
|
||||
if (m_current.computeConstants != buffer)
|
||||
m_dirtyFlags |= DirtyFlag_ComputeConstants;
|
||||
|
||||
m_pending.computeConstants = buffer;
|
||||
}
|
||||
|
||||
void SetVertexBuffer(ID3D11Buffer* buffer, u32 stride, u32 offset)
|
||||
{
|
||||
if (m_current.vertexBuffer != buffer || m_current.vertexBufferStride != stride ||
|
||||
@@ -187,22 +181,45 @@ public:
|
||||
m_pending.geometryShader = shader;
|
||||
}
|
||||
|
||||
void SetComputeShader(ID3D11ComputeShader* shader)
|
||||
void SetFramebuffer(DXFramebuffer* fb)
|
||||
{
|
||||
if (m_current.computeShader != shader)
|
||||
m_dirtyFlags |= DirtyFlag_ComputeShader;
|
||||
if (m_current.framebuffer != fb)
|
||||
m_dirtyFlags |= DirtyFlag_Framebuffer;
|
||||
|
||||
m_pending.computeShader = shader;
|
||||
m_pending.framebuffer = fb;
|
||||
}
|
||||
|
||||
void SetOMUAV(ID3D11UnorderedAccessView* uav)
|
||||
{
|
||||
if (m_current.uav != uav)
|
||||
m_dirtyFlags |= DirtyFlag_Framebuffer;
|
||||
|
||||
m_pending.uav = uav;
|
||||
}
|
||||
|
||||
void SetIntegerRTV(bool enable)
|
||||
{
|
||||
if (m_current.use_integer_rtv != enable)
|
||||
m_dirtyFlags |= DirtyFlag_Framebuffer;
|
||||
|
||||
m_pending.use_integer_rtv = enable;
|
||||
}
|
||||
|
||||
// removes currently set texture from all slots, returns mask of previously bound slots
|
||||
u32 UnsetTexture(ID3D11ShaderResourceView* srv);
|
||||
void SetTextureByMask(u32 textureSlotMask, ID3D11ShaderResourceView* srv);
|
||||
void ApplyTextures();
|
||||
|
||||
// call this immediately before any drawing operation or to explicitly apply pending resource
|
||||
// state changes
|
||||
void Apply();
|
||||
|
||||
// Binds constant buffers/textures/samplers to the compute shader stage.
|
||||
// We don't track these explicitly because it's not often-used.
|
||||
void SetComputeUAV(ID3D11UnorderedAccessView* uav);
|
||||
void SetComputeShader(ID3D11ComputeShader* shader);
|
||||
void SyncComputeBindings();
|
||||
|
||||
private:
|
||||
enum DirtyFlags
|
||||
{
|
||||
@@ -227,20 +244,19 @@ private:
|
||||
DirtyFlag_PixelConstants = 1 << 16,
|
||||
DirtyFlag_VertexConstants = 1 << 17,
|
||||
DirtyFlag_GeometryConstants = 1 << 18,
|
||||
DirtyFlag_ComputeConstants = 1 << 19,
|
||||
|
||||
DirtyFlag_VertexBuffer = 1 << 20,
|
||||
DirtyFlag_IndexBuffer = 1 << 21,
|
||||
DirtyFlag_VertexBuffer = 1 << 19,
|
||||
DirtyFlag_IndexBuffer = 1 << 20,
|
||||
|
||||
DirtyFlag_PixelShader = 1 << 22,
|
||||
DirtyFlag_VertexShader = 1 << 23,
|
||||
DirtyFlag_GeometryShader = 1 << 24,
|
||||
DirtyFlag_ComputeShader = 1 << 25,
|
||||
DirtyFlag_PixelShader = 1 << 21,
|
||||
DirtyFlag_VertexShader = 1 << 22,
|
||||
DirtyFlag_GeometryShader = 1 << 23,
|
||||
|
||||
DirtyFlag_InputAssembler = 1 << 26,
|
||||
DirtyFlag_BlendState = 1 << 27,
|
||||
DirtyFlag_DepthState = 1 << 28,
|
||||
DirtyFlag_RasterizerState = 1 << 29,
|
||||
DirtyFlag_InputAssembler = 1 << 24,
|
||||
DirtyFlag_BlendState = 1 << 25,
|
||||
DirtyFlag_DepthState = 1 << 26,
|
||||
DirtyFlag_RasterizerState = 1 << 27,
|
||||
DirtyFlag_Framebuffer = 1 << 28
|
||||
};
|
||||
|
||||
u32 m_dirtyFlags = ~0u;
|
||||
@@ -252,7 +268,6 @@ private:
|
||||
std::array<ID3D11Buffer*, 2> pixelConstants;
|
||||
ID3D11Buffer* vertexConstants;
|
||||
ID3D11Buffer* geometryConstants;
|
||||
ID3D11Buffer* computeConstants;
|
||||
ID3D11Buffer* vertexBuffer;
|
||||
ID3D11Buffer* indexBuffer;
|
||||
u32 vertexBufferStride;
|
||||
@@ -262,18 +277,27 @@ private:
|
||||
ID3D11PixelShader* pixelShader;
|
||||
ID3D11VertexShader* vertexShader;
|
||||
ID3D11GeometryShader* geometryShader;
|
||||
ID3D11ComputeShader* computeShader;
|
||||
ID3D11BlendState* blendState;
|
||||
ID3D11DepthStencilState* depthState;
|
||||
ID3D11RasterizerState* rasterizerState;
|
||||
DXFramebuffer* framebuffer;
|
||||
ID3D11UnorderedAccessView* uav;
|
||||
bool use_integer_rtv;
|
||||
};
|
||||
|
||||
Resources m_pending = {};
|
||||
Resources m_current = {};
|
||||
|
||||
// Compute resources are synced with the graphics resources when we need them.
|
||||
ID3D11Buffer* m_compute_constants = nullptr;
|
||||
std::array<ID3D11ShaderResourceView*, 8> m_compute_textures{};
|
||||
std::array<ID3D11SamplerState*, 8> m_compute_samplers{};
|
||||
ID3D11UnorderedAccessView* m_compute_image = nullptr;
|
||||
ID3D11ComputeShader* m_compute_shader = nullptr;
|
||||
};
|
||||
|
||||
extern StateManager* stateman;
|
||||
|
||||
} // namespace
|
||||
} // namespace D3D
|
||||
|
||||
} // namespace DX11
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
// Copyright 2010 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "VideoBackends/D3D/D3DBase.h"
|
||||
#include "VideoBackends/D3D/D3DTexture.h"
|
||||
|
||||
namespace DX11
|
||||
{
|
||||
D3DTexture2D* D3DTexture2D::Create(unsigned int width, unsigned int height, D3D11_BIND_FLAG bind,
|
||||
D3D11_USAGE usage, DXGI_FORMAT fmt, unsigned int levels,
|
||||
unsigned int slices, D3D11_SUBRESOURCE_DATA* data)
|
||||
{
|
||||
ID3D11Texture2D* pTexture = nullptr;
|
||||
HRESULT hr;
|
||||
|
||||
D3D11_CPU_ACCESS_FLAG cpuflags;
|
||||
if (usage == D3D11_USAGE_STAGING)
|
||||
cpuflags = (D3D11_CPU_ACCESS_FLAG)((int)D3D11_CPU_ACCESS_WRITE | (int)D3D11_CPU_ACCESS_READ);
|
||||
else if (usage == D3D11_USAGE_DYNAMIC)
|
||||
cpuflags = D3D11_CPU_ACCESS_WRITE;
|
||||
else
|
||||
cpuflags = (D3D11_CPU_ACCESS_FLAG)0;
|
||||
D3D11_TEXTURE2D_DESC texdesc =
|
||||
CD3D11_TEXTURE2D_DESC(fmt, width, height, slices, levels, bind, usage, cpuflags);
|
||||
hr = D3D::device->CreateTexture2D(&texdesc, data, &pTexture);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
PanicAlert("Failed to create texture at %s, line %d: hr=%#x\n", __FILE__, __LINE__, hr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
D3DTexture2D* ret = new D3DTexture2D(pTexture, bind);
|
||||
SAFE_RELEASE(pTexture);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void D3DTexture2D::AddRef()
|
||||
{
|
||||
++ref;
|
||||
}
|
||||
|
||||
UINT D3DTexture2D::Release()
|
||||
{
|
||||
--ref;
|
||||
if (ref == 0)
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
ID3D11Texture2D*& D3DTexture2D::GetTex()
|
||||
{
|
||||
return tex;
|
||||
}
|
||||
ID3D11ShaderResourceView*& D3DTexture2D::GetSRV()
|
||||
{
|
||||
return srv;
|
||||
}
|
||||
ID3D11RenderTargetView*& D3DTexture2D::GetRTV()
|
||||
{
|
||||
return rtv;
|
||||
}
|
||||
ID3D11DepthStencilView*& D3DTexture2D::GetDSV()
|
||||
{
|
||||
return dsv;
|
||||
}
|
||||
|
||||
D3DTexture2D::D3DTexture2D(ID3D11Texture2D* texptr, D3D11_BIND_FLAG bind, DXGI_FORMAT srv_format,
|
||||
DXGI_FORMAT dsv_format, DXGI_FORMAT rtv_format, bool multisampled)
|
||||
: tex{texptr}
|
||||
{
|
||||
D3D11_SRV_DIMENSION srv_dim =
|
||||
multisampled ? D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY : D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
|
||||
D3D11_DSV_DIMENSION dsv_dim =
|
||||
multisampled ? D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY : D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
|
||||
D3D11_RTV_DIMENSION rtv_dim =
|
||||
multisampled ? D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY : D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = CD3D11_SHADER_RESOURCE_VIEW_DESC(srv_dim, srv_format);
|
||||
D3D11_DEPTH_STENCIL_VIEW_DESC dsv_desc = CD3D11_DEPTH_STENCIL_VIEW_DESC(dsv_dim, dsv_format);
|
||||
D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = CD3D11_RENDER_TARGET_VIEW_DESC(rtv_dim, rtv_format);
|
||||
if (bind & D3D11_BIND_SHADER_RESOURCE)
|
||||
D3D::device->CreateShaderResourceView(tex, &srv_desc, &srv);
|
||||
if (bind & D3D11_BIND_RENDER_TARGET)
|
||||
D3D::device->CreateRenderTargetView(tex, &rtv_desc, &rtv);
|
||||
if (bind & D3D11_BIND_DEPTH_STENCIL)
|
||||
D3D::device->CreateDepthStencilView(tex, &dsv_desc, &dsv);
|
||||
tex->AddRef();
|
||||
}
|
||||
|
||||
D3DTexture2D::~D3DTexture2D()
|
||||
{
|
||||
SAFE_RELEASE(srv);
|
||||
SAFE_RELEASE(rtv);
|
||||
SAFE_RELEASE(dsv);
|
||||
SAFE_RELEASE(tex);
|
||||
}
|
||||
|
||||
} // namespace DX11
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user