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:
Tilka
2019-02-26 04:21:05 +00:00
committed by GitHub
182 changed files with 8419 additions and 15984 deletions
+3
View File
@@ -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
)
-20
View File
@@ -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>
+46 -16
View File
@@ -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);
+4 -2
View File
@@ -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();
-60
View File
@@ -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
-39
View File
@@ -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
-304
View File
@@ -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
-78
View File
@@ -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
+139 -36
View File
@@ -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()
+50 -26
View File
@@ -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