mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 22:05:38 +00:00
Common: Add helper classes for D3D11
This commit is contained in:
parent
d68f7085d6
commit
f244da86a2
|
@ -1,28 +1,40 @@
|
|||
set(SRCS
|
||||
audio_stream.cpp
|
||||
audio_stream.h
|
||||
bitfield.h
|
||||
cd_image.cpp
|
||||
cd_image.h
|
||||
cd_image_bin.cpp
|
||||
cd_image_cue.cpp
|
||||
cd_xa.cpp
|
||||
cd_xa.h
|
||||
gl/program.cpp
|
||||
gl/program.h
|
||||
gl/stream_buffer.cpp
|
||||
gl/stream_buffer.h
|
||||
gl/texture.cpp
|
||||
gl/texture.h
|
||||
jit_code_buffer.cpp
|
||||
jit_code_buffer.h
|
||||
state_wrapper.cpp
|
||||
state_wrapper.h
|
||||
add_library(common
|
||||
audio_stream.cpp
|
||||
audio_stream.h
|
||||
bitfield.h
|
||||
cd_image.cpp
|
||||
cd_image.h
|
||||
cd_image_bin.cpp
|
||||
cd_image_cue.cpp
|
||||
cd_xa.cpp
|
||||
cd_xa.h
|
||||
gl/program.cpp
|
||||
gl/program.h
|
||||
gl/stream_buffer.cpp
|
||||
gl/stream_buffer.h
|
||||
gl/texture.cpp
|
||||
gl/texture.h
|
||||
jit_code_buffer.cpp
|
||||
jit_code_buffer.h
|
||||
state_wrapper.cpp
|
||||
state_wrapper.h
|
||||
types.h
|
||||
)
|
||||
|
||||
add_library(common ${SRCS})
|
||||
|
||||
target_include_directories(common PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
target_include_directories(common PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
target_link_libraries(common YBaseLib glad libcue Threads::Threads)
|
||||
target_link_libraries(common PRIVATE YBaseLib glad libcue Threads::Threads)
|
||||
|
||||
if(WIN32)
|
||||
target_sources(common PRIVATE
|
||||
d3d11/shader_compiler.cpp
|
||||
d3d11/shader_compiler.h
|
||||
d3d11/staging_texture.cpp
|
||||
d3d11/staging_texture.h
|
||||
d3d11/stream_buffer.cpp
|
||||
d3d11/stream_buffer.h
|
||||
d3d11/texture.cpp
|
||||
d3d11/texture.h
|
||||
)
|
||||
target_link_libraries(common PRIVATE d3dcompiler.lib)
|
||||
endif()
|
||||
|
|
|
@ -38,6 +38,10 @@
|
|||
<ClInclude Include="audio_stream.h" />
|
||||
<ClInclude Include="bitfield.h" />
|
||||
<ClInclude Include="cd_image.h" />
|
||||
<ClInclude Include="d3d11\shader_compiler.h" />
|
||||
<ClInclude Include="d3d11\staging_texture.h" />
|
||||
<ClInclude Include="d3d11\stream_buffer.h" />
|
||||
<ClInclude Include="d3d11\texture.h" />
|
||||
<ClInclude Include="fifo_queue.h" />
|
||||
<ClInclude Include="gl\program.h" />
|
||||
<ClInclude Include="gl\stream_buffer.h" />
|
||||
|
@ -53,6 +57,10 @@
|
|||
<ClCompile Include="cd_image.cpp" />
|
||||
<ClCompile Include="cd_image_bin.cpp" />
|
||||
<ClCompile Include="cd_image_cue.cpp" />
|
||||
<ClCompile Include="d3d11\shader_compiler.cpp" />
|
||||
<ClCompile Include="d3d11\staging_texture.cpp" />
|
||||
<ClCompile Include="d3d11\stream_buffer.cpp" />
|
||||
<ClCompile Include="d3d11\texture.cpp" />
|
||||
<ClCompile Include="gl\program.cpp" />
|
||||
<ClCompile Include="gl\stream_buffer.cpp" />
|
||||
<ClCompile Include="gl\texture.cpp" />
|
||||
|
@ -215,6 +223,7 @@
|
|||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ObjectFileName>$(IntDir)/%(RelativeDir)/</ObjectFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -223,6 +232,9 @@
|
|||
<AdditionalLibraryDirectories>$(SolutionDir)dep\msvc\lib32-debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Lib />
|
||||
<Lib>
|
||||
<AdditionalDependencies>d3dcompiler.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'">
|
||||
<ClCompile>
|
||||
|
@ -240,6 +252,7 @@
|
|||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ObjectFileName>$(IntDir)/%(RelativeDir)/</ObjectFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -248,6 +261,9 @@
|
|||
<AdditionalLibraryDirectories>$(SolutionDir)dep\msvc\lib32-debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Lib />
|
||||
<Lib>
|
||||
<AdditionalDependencies>d3dcompiler.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
|
@ -262,6 +278,7 @@
|
|||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ObjectFileName>$(IntDir)/%(RelativeDir)/</ObjectFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -270,6 +287,9 @@
|
|||
<AdditionalLibraryDirectories>$(SolutionDir)dep\msvc\lib32-debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Lib />
|
||||
<Lib>
|
||||
<AdditionalDependencies>d3dcompiler.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'">
|
||||
<ClCompile>
|
||||
|
@ -287,6 +307,7 @@
|
|||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ObjectFileName>$(IntDir)/%(RelativeDir)/</ObjectFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -295,6 +316,9 @@
|
|||
<AdditionalLibraryDirectories>$(SolutionDir)dep\msvc\lib32-debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Lib />
|
||||
<Lib>
|
||||
<AdditionalDependencies>d3dcompiler.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
|
@ -311,6 +335,7 @@
|
|||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ObjectFileName>$(IntDir)/%(RelativeDir)/</ObjectFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -321,6 +346,9 @@
|
|||
<AdditionalLibraryDirectories>$(SolutionDir)dep\msvc\lib32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Lib />
|
||||
<Lib>
|
||||
<AdditionalDependencies>d3dcompiler.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|Win32'">
|
||||
<ClCompile>
|
||||
|
@ -337,6 +365,7 @@
|
|||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ObjectFileName>$(IntDir)/%(RelativeDir)/</ObjectFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -347,6 +376,9 @@
|
|||
<AdditionalLibraryDirectories>$(SolutionDir)dep\msvc\lib32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Lib />
|
||||
<Lib>
|
||||
<AdditionalDependencies>d3dcompiler.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
|
@ -363,6 +395,7 @@
|
|||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ObjectFileName>$(IntDir)/%(RelativeDir)/</ObjectFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -373,6 +406,9 @@
|
|||
<AdditionalLibraryDirectories>$(SolutionDir)dep\msvc\lib32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Lib />
|
||||
<Lib>
|
||||
<AdditionalDependencies>d3dcompiler.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|x64'">
|
||||
<ClCompile>
|
||||
|
@ -389,6 +425,7 @@
|
|||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ObjectFileName>$(IntDir)/%(RelativeDir)/</ObjectFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -399,6 +436,9 @@
|
|||
<AdditionalLibraryDirectories>$(SolutionDir)dep\msvc\lib32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Lib />
|
||||
<Lib>
|
||||
<AdditionalDependencies>d3dcompiler.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
|
@ -19,6 +19,18 @@
|
|||
<ClInclude Include="gl\texture.h">
|
||||
<Filter>gl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="d3d11\stream_buffer.h">
|
||||
<Filter>d3d11</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="d3d11\texture.h">
|
||||
<Filter>d3d11</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="d3d11\staging_texture.h">
|
||||
<Filter>d3d11</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="d3d11\shader_compiler.h">
|
||||
<Filter>d3d11</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="jit_code_buffer.cpp" />
|
||||
|
@ -37,6 +49,18 @@
|
|||
<ClCompile Include="gl\texture.cpp">
|
||||
<Filter>gl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="d3d11\texture.cpp">
|
||||
<Filter>d3d11</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="d3d11\staging_texture.cpp">
|
||||
<Filter>d3d11</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="d3d11\stream_buffer.cpp">
|
||||
<Filter>d3d11</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="d3d11\shader_compiler.cpp">
|
||||
<Filter>d3d11</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="bitfield.natvis" />
|
||||
|
@ -45,5 +69,8 @@
|
|||
<Filter Include="gl">
|
||||
<UniqueIdentifier>{52487c57-753d-4888-ba26-ed63ab51a234}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="d3d11">
|
||||
<UniqueIdentifier>{30251086-81f3-44f5-add4-7ff9a24098ab}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
142
src/common/d3d11/shader_compiler.cpp
Normal file
142
src/common/d3d11/shader_compiler.cpp
Normal file
|
@ -0,0 +1,142 @@
|
|||
#include "shader_compiler.h"
|
||||
#include "YBaseLib/Log.h"
|
||||
#include "YBaseLib/String.h"
|
||||
#include <array>
|
||||
#include <d3dcompiler.h>
|
||||
#include <fstream>
|
||||
Log_SetChannel(D3D11);
|
||||
|
||||
namespace D3D11::ShaderCompiler {
|
||||
|
||||
static unsigned s_next_bad_shader_id = 1;
|
||||
|
||||
ComPtr<ID3DBlob> CompileShader(Type type, D3D_FEATURE_LEVEL feature_level, std::string_view code, bool debug)
|
||||
{
|
||||
const char* target;
|
||||
switch (feature_level)
|
||||
{
|
||||
case D3D_FEATURE_LEVEL_10_0:
|
||||
{
|
||||
static constexpr std::array<const char*, 3> targets = {{"vs_4_0", "ps_4_0", "cs_4_0"}};
|
||||
target = targets[static_cast<int>(type)];
|
||||
}
|
||||
break;
|
||||
|
||||
case D3D_FEATURE_LEVEL_10_1:
|
||||
{
|
||||
static constexpr std::array<const char*, 3> targets = {{"vs_4_1", "ps_4_1", "cs_4_1"}};
|
||||
target = targets[static_cast<int>(type)];
|
||||
}
|
||||
break;
|
||||
|
||||
case D3D_FEATURE_LEVEL_11_0:
|
||||
{
|
||||
static constexpr std::array<const char*, 3> targets = {{"vs_5_0", "ps_5_0", "cs_5_0"}};
|
||||
target = targets[static_cast<int>(type)];
|
||||
}
|
||||
break;
|
||||
|
||||
case D3D_FEATURE_LEVEL_11_1:
|
||||
default:
|
||||
{
|
||||
static constexpr std::array<const char*, 3> targets = {{"vs_5_1", "ps_5_1", "cs_5_1"}};
|
||||
target = targets[static_cast<int>(type)];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
static constexpr UINT flags_non_debug = D3DCOMPILE_OPTIMIZATION_LEVEL3;
|
||||
static constexpr UINT flags_debug = D3DCOMPILE_SKIP_OPTIMIZATION | D3DCOMPILE_DEBUG;
|
||||
|
||||
ComPtr<ID3DBlob> blob;
|
||||
ComPtr<ID3DBlob> error_blob;
|
||||
const HRESULT hr =
|
||||
D3DCompile(code.data(), code.size(), "0", nullptr, nullptr, "main", target, debug ? flags_debug : flags_non_debug,
|
||||
0, blob.GetAddressOf(), error_blob.GetAddressOf());
|
||||
|
||||
String error_string;
|
||||
if (error_blob)
|
||||
{
|
||||
error_string.AppendString(static_cast<const char*>(error_blob->GetBufferPointer()),
|
||||
static_cast<uint32>(error_blob->GetBufferSize()));
|
||||
error_blob.Reset();
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Failed to compile '%s':\n%s", target, error_string.GetCharArray());
|
||||
|
||||
std::ofstream ofs(SmallString::FromFormat("bad_shader_%u.txt", s_next_bad_shader_id++),
|
||||
std::ofstream::out | std::ofstream::binary);
|
||||
if (ofs.is_open())
|
||||
{
|
||||
ofs << code;
|
||||
ofs << "\n\nCompile as " << target << " failed: " << hr << "\n";
|
||||
ofs.write(error_string.GetCharArray(), error_string.GetLength());
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!error_string.IsEmpty())
|
||||
Log_WarningPrintf("'%s' compiled with warnings:\n%s", target, error_string.GetCharArray());
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
ComPtr<ID3D11VertexShader> CompileAndCreateVertexShader(ID3D11Device* device, std::string_view code, bool debug)
|
||||
{
|
||||
ComPtr<ID3DBlob> blob = CompileShader(Type::Vertex, device->GetFeatureLevel(), std::move(code), debug);
|
||||
if (!blob)
|
||||
return {};
|
||||
|
||||
ComPtr<ID3D11VertexShader> vs;
|
||||
const HRESULT hr =
|
||||
device->CreateVertexShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, vs.GetAddressOf());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Failed to create vertex shader: 0x%08X", hr);
|
||||
return {};
|
||||
}
|
||||
|
||||
return vs;
|
||||
}
|
||||
|
||||
ComPtr<ID3D11PixelShader> CompileAndCreatePixelShader(ID3D11Device* device, std::string_view code, bool debug)
|
||||
{
|
||||
ComPtr<ID3DBlob> blob = CompileShader(Type::Pixel, device->GetFeatureLevel(), std::move(code), debug);
|
||||
if (!blob)
|
||||
return {};
|
||||
|
||||
ComPtr<ID3D11PixelShader> shader;
|
||||
const HRESULT hr =
|
||||
device->CreatePixelShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, shader.GetAddressOf());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Failed to create pixel shader: 0x%08X", hr);
|
||||
return {};
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
ComPtr<ID3D11ComputeShader> CompileAndCreateComputeShader(ID3D11Device* device, std::string_view code, bool debug)
|
||||
{
|
||||
ComPtr<ID3DBlob> blob = CompileShader(Type::Compute, device->GetFeatureLevel(), std::move(code), debug);
|
||||
if (!blob)
|
||||
return {};
|
||||
|
||||
ComPtr<ID3D11ComputeShader> shader;
|
||||
const HRESULT hr =
|
||||
device->CreateComputeShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, shader.GetAddressOf());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Failed to create compute shader: 0x%08X", hr);
|
||||
return {};
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
} // namespace D3D11::ShaderCompiler
|
25
src/common/d3d11/shader_compiler.h
Normal file
25
src/common/d3d11/shader_compiler.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
#include "YBaseLib/Windows/WindowsHeaders.h"
|
||||
#include <d3d11.h>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <wrl/client.h>
|
||||
|
||||
namespace D3D11::ShaderCompiler {
|
||||
template<typename T>
|
||||
using ComPtr = Microsoft::WRL::ComPtr<T>;
|
||||
|
||||
enum class Type
|
||||
{
|
||||
Vertex,
|
||||
Pixel,
|
||||
Compute
|
||||
};
|
||||
|
||||
ComPtr<ID3DBlob> CompileShader(Type type, D3D_FEATURE_LEVEL feature_level, std::string_view code, bool debug);
|
||||
|
||||
ComPtr<ID3D11VertexShader> CompileAndCreateVertexShader(ID3D11Device* device, std::string_view code, bool debug);
|
||||
ComPtr<ID3D11PixelShader> CompileAndCreatePixelShader(ID3D11Device* device, std::string_view code, bool debug);
|
||||
ComPtr<ID3D11ComputeShader> CompileAndCreateComputeShader(ID3D11Device* device, std::string_view code, bool debug);
|
||||
|
||||
}; // namespace D3D11::ShaderCompiler
|
91
src/common/d3d11/staging_texture.cpp
Normal file
91
src/common/d3d11/staging_texture.cpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
#include "staging_texture.h"
|
||||
#include "YBaseLib/Log.h"
|
||||
Log_SetChannel(D3D11);
|
||||
|
||||
namespace D3D11 {
|
||||
|
||||
StagingTexture::StagingTexture() : m_width(0), m_height(0) {}
|
||||
|
||||
StagingTexture::~StagingTexture()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool StagingTexture::Create(ID3D11Device* device, u32 width, u32 height, DXGI_FORMAT format, bool for_uploading)
|
||||
{
|
||||
CD3D11_TEXTURE2D_DESC desc(format, width, height, 1, 1, 0, for_uploading ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_STAGING,
|
||||
0, 1, 0, 0);
|
||||
|
||||
ComPtr<ID3D11Texture2D> texture;
|
||||
const HRESULT tex_hr = device->CreateTexture2D(&desc, nullptr, texture.GetAddressOf());
|
||||
if (FAILED(tex_hr))
|
||||
{
|
||||
Log_ErrorPrintf("Create texture failed: 0x%08X", tex_hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_texture = std::move(texture);
|
||||
m_width = desc.Width;
|
||||
m_height = desc.Height;
|
||||
m_format = desc.Format;
|
||||
return true;
|
||||
}
|
||||
|
||||
void StagingTexture::Destroy()
|
||||
{
|
||||
Assert(!IsMapped());
|
||||
m_texture.Reset();
|
||||
}
|
||||
|
||||
bool StagingTexture::Map(ID3D11DeviceContext* context, bool writing)
|
||||
{
|
||||
Assert(!IsMapped());
|
||||
const HRESULT hr = context->Map(m_texture.Get(), 0, writing ? D3D11_MAP_WRITE : D3D11_MAP_READ, 0, &m_map);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Map staging texture failed: 0x%08X", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void StagingTexture::Unmap(ID3D11DeviceContext* context)
|
||||
{
|
||||
Assert(IsMapped());
|
||||
context->Unmap(m_texture.Get(), 0);
|
||||
}
|
||||
|
||||
void StagingTexture::CopyToTexture(ID3D11DeviceContext* context, u32 src_x, u32 src_y, ID3D11Texture2D* dst_texture,
|
||||
u32 dst_subresource, u32 dst_x, u32 dst_y, u32 width, u32 height)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
Assert((src_x + width) <= m_width && (src_y + height) <= m_height);
|
||||
|
||||
D3D11_TEXTURE2D_DESC dst_desc;
|
||||
dst_texture->GetDesc(&dst_desc);
|
||||
Assert((dst_x + width) <= dst_desc.Width && (dst_y + height) <= dst_desc.Height);
|
||||
#endif
|
||||
|
||||
const CD3D11_BOX box(static_cast<LONG>(src_x), static_cast<LONG>(src_y), 0, static_cast<LONG>(src_x + width),
|
||||
static_cast<LONG>(src_y + height), 1);
|
||||
context->CopySubresourceRegion(dst_texture, dst_subresource, dst_x, dst_y, 0, m_texture.Get(), 0, &box);
|
||||
}
|
||||
|
||||
void StagingTexture::CopyFromTexture(ID3D11DeviceContext* context, ID3D11Texture2D* src_texture, u32 src_subresource,
|
||||
u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
Assert((dst_x + width) <= m_width && (dst_y + height) <= m_height);
|
||||
|
||||
D3D11_TEXTURE2D_DESC src_desc;
|
||||
src_texture->GetDesc(&src_desc);
|
||||
Assert((src_x + width) <= src_desc.Width && (src_y + height) <= src_desc.Height);
|
||||
#endif
|
||||
|
||||
const CD3D11_BOX box(static_cast<LONG>(src_x), static_cast<LONG>(src_y), 0, static_cast<LONG>(src_x + width),
|
||||
static_cast<LONG>(src_y + height), 1);
|
||||
context->CopySubresourceRegion(m_texture.Get(), 0, dst_x, dst_y, 0, src_texture, src_subresource, &box);
|
||||
}
|
||||
|
||||
} // namespace D3D
|
100
src/common/d3d11/staging_texture.h
Normal file
100
src/common/d3d11/staging_texture.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
#pragma once
|
||||
#include "../types.h"
|
||||
#include "YBaseLib/Windows/WindowsHeaders.h"
|
||||
#include <cstring>
|
||||
#include <d3d11.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
namespace D3D11 {
|
||||
class StagingTexture
|
||||
{
|
||||
public:
|
||||
template<typename T>
|
||||
using ComPtr = Microsoft::WRL::ComPtr<T>;
|
||||
|
||||
StagingTexture();
|
||||
~StagingTexture();
|
||||
|
||||
ALWAYS_INLINE ID3D11Texture2D* GetD3DTexture() const { return m_texture.Get(); }
|
||||
|
||||
ALWAYS_INLINE u32 GetWidth() const { return m_width; }
|
||||
ALWAYS_INLINE u32 GetHeight() const { return m_height; }
|
||||
ALWAYS_INLINE DXGI_FORMAT GetFormat() const { return m_format; }
|
||||
ALWAYS_INLINE bool IsMapped() const { return m_map.pData != nullptr; }
|
||||
|
||||
ALWAYS_INLINE operator bool() const { return static_cast<bool>(m_texture); }
|
||||
|
||||
bool Create(ID3D11Device* device, u32 width, u32 height, DXGI_FORMAT format, bool for_uploading);
|
||||
void Destroy();
|
||||
|
||||
bool Map(ID3D11DeviceContext* context, bool writing);
|
||||
void Unmap(ID3D11DeviceContext* context);
|
||||
|
||||
void CopyToTexture(ID3D11DeviceContext* context, u32 src_x, u32 src_y, ID3D11Texture2D* dst_texture,
|
||||
u32 dst_subresource, u32 dst_x, u32 dst_y, u32 width, u32 height);
|
||||
void CopyFromTexture(ID3D11DeviceContext* context, ID3D11Texture2D* src_texture, u32 src_subresource, u32 src_x,
|
||||
u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height);
|
||||
|
||||
template<typename T>
|
||||
T ReadPixel(u32 x, u32 y)
|
||||
{
|
||||
T pixel;
|
||||
std::memcpy(&pixel, static_cast<u8*>(m_map.pData) + (y * m_map.RowPitch) + x, sizeof(T));
|
||||
return pixel;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void WritePixel(u32 x, u32 y, T pixel)
|
||||
{
|
||||
std::memcpy(static_cast<u8*>(m_map.pData) + (y * m_map.RowPitch) + x, &pixel, sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ReadPixels(u32 x, u32 y, u32 width, u32 height, u32 stride, T* data)
|
||||
{
|
||||
const u8* src_ptr = static_cast<u8*>(m_map.pData) + (y * m_map.RowPitch) + (x * sizeof(T));
|
||||
u8* dst_ptr = reinterpret_cast<u8*>(data);
|
||||
if (m_map.RowPitch != stride)
|
||||
{
|
||||
for (u32 row = 0; row < height; row++)
|
||||
{
|
||||
std::memcpy(dst_ptr, src_ptr, sizeof(T) * width);
|
||||
src_ptr += m_map.RowPitch;
|
||||
dst_ptr += stride;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::memcpy(dst_ptr, src_ptr, stride * height);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void WritePixels(u32 x, u32 y, u32 width, u32 height, u32 stride, const T* data)
|
||||
{
|
||||
const u8* src_ptr = reinterpret_cast<const u8*>(data);
|
||||
u8* dst_ptr = static_cast<u8*>(m_map.pData) + (y * m_map.RowPitch) + (x * sizeof(T));
|
||||
if (m_map.RowPitch != stride)
|
||||
{
|
||||
for (u32 row = 0; row < height; row++)
|
||||
{
|
||||
std::memcpy(dst_ptr, src_ptr, sizeof(T) * width);
|
||||
src_ptr += stride;
|
||||
dst_ptr += m_map.RowPitch;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::memcpy(dst_ptr, src_ptr, stride * height);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ComPtr<ID3D11Texture2D> m_texture;
|
||||
u32 m_width;
|
||||
u32 m_height;
|
||||
DXGI_FORMAT m_format;
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE m_map = {};
|
||||
};
|
||||
} // namespace D3D11
|
88
src/common/d3d11/stream_buffer.cpp
Normal file
88
src/common/d3d11/stream_buffer.cpp
Normal file
|
@ -0,0 +1,88 @@
|
|||
#include "stream_buffer.h"
|
||||
#include "YBaseLib/Log.h"
|
||||
Log_SetChannel(D3D11);
|
||||
|
||||
namespace D3D11 {
|
||||
|
||||
StreamBuffer::StreamBuffer() : m_size(0), m_position(0) {}
|
||||
|
||||
StreamBuffer::StreamBuffer(ComPtr<ID3D11Buffer> buffer) : m_buffer(std::move(buffer)), m_position(0)
|
||||
{
|
||||
D3D11_BUFFER_DESC desc;
|
||||
m_buffer->GetDesc(&desc);
|
||||
m_size = desc.ByteWidth;
|
||||
}
|
||||
|
||||
StreamBuffer::~StreamBuffer()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
bool StreamBuffer::Create(ID3D11Device* device, D3D11_BIND_FLAG bind_flags, u32 size)
|
||||
{
|
||||
CD3D11_BUFFER_DESC desc(size, bind_flags, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE, 0, 0);
|
||||
ComPtr<ID3D11Buffer> buffer;
|
||||
const HRESULT hr = device->CreateBuffer(&desc, nullptr, &buffer);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Creating buffer failed: 0x%08X", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_buffer = std::move(buffer);
|
||||
m_size = size;
|
||||
m_position = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void StreamBuffer::Adopt(ComPtr<ID3D11Buffer> buffer)
|
||||
{
|
||||
m_buffer = std::move(buffer);
|
||||
|
||||
D3D11_BUFFER_DESC desc;
|
||||
m_buffer->GetDesc(&desc);
|
||||
m_size = desc.ByteWidth;
|
||||
m_position = 0;
|
||||
}
|
||||
|
||||
void StreamBuffer::Release()
|
||||
{
|
||||
m_buffer.Reset();
|
||||
}
|
||||
|
||||
StreamBuffer::MappingResult StreamBuffer::Map(ID3D11DeviceContext* context, u32 alignment, u32 min_size)
|
||||
{
|
||||
m_position = Common::AlignUp(m_position, alignment);
|
||||
|
||||
D3D11_MAP map;
|
||||
if ((m_position + min_size) >= m_size)
|
||||
{
|
||||
// wrap around
|
||||
m_position = 0;
|
||||
map = D3D11_MAP_WRITE_DISCARD;
|
||||
}
|
||||
else
|
||||
{
|
||||
map = D3D11_MAP_WRITE_NO_OVERWRITE;
|
||||
}
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE sr;
|
||||
const HRESULT hr = context->Map(m_buffer.Get(), 0, map, 0, &sr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Map failed: 0x%08X", hr);
|
||||
Panic("Map failed");
|
||||
return {};
|
||||
}
|
||||
|
||||
return MappingResult{static_cast<char*>(sr.pData) + m_position, m_position, m_position / alignment,
|
||||
(m_size - m_position) / alignment};
|
||||
}
|
||||
|
||||
void StreamBuffer::Unmap(ID3D11DeviceContext* context, u32 used_size)
|
||||
{
|
||||
context->Unmap(m_buffer.Get(), 0);
|
||||
m_position += used_size;
|
||||
}
|
||||
|
||||
} // namespace D3D11
|
43
src/common/d3d11/stream_buffer.h
Normal file
43
src/common/d3d11/stream_buffer.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
#pragma once
|
||||
#include "../types.h"
|
||||
#include "YBaseLib/Windows/WindowsHeaders.h"
|
||||
#include <d3d11.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
namespace D3D11 {
|
||||
class StreamBuffer
|
||||
{
|
||||
public:
|
||||
template<typename T>
|
||||
using ComPtr = Microsoft::WRL::ComPtr<T>;
|
||||
|
||||
StreamBuffer();
|
||||
StreamBuffer(ComPtr<ID3D11Buffer> buffer);
|
||||
~StreamBuffer();
|
||||
|
||||
ALWAYS_INLINE ID3D11Buffer* GetD3DBuffer() const { return m_buffer.Get(); }
|
||||
ALWAYS_INLINE ID3D11Buffer* const* GetD3DBufferArray() const { return m_buffer.GetAddressOf(); }
|
||||
ALWAYS_INLINE u32 GetSize() const { return m_size; }
|
||||
ALWAYS_INLINE u32 GetPosition() const { return m_position; }
|
||||
|
||||
bool Create(ID3D11Device* device, D3D11_BIND_FLAG bind_flags, u32 size);
|
||||
void Adopt(ComPtr<ID3D11Buffer> buffer);
|
||||
void Release();
|
||||
|
||||
struct MappingResult
|
||||
{
|
||||
void* pointer;
|
||||
u32 buffer_offset;
|
||||
u32 index_aligned; // offset / alignment, suitable for base vertex
|
||||
u32 space_aligned; // remaining space / alignment
|
||||
};
|
||||
|
||||
MappingResult Map(ID3D11DeviceContext* context, u32 alignment, u32 min_size);
|
||||
void Unmap(ID3D11DeviceContext* context, u32 used_size);
|
||||
|
||||
private:
|
||||
ComPtr<ID3D11Buffer> m_buffer;
|
||||
u32 m_size;
|
||||
u32 m_position;
|
||||
};
|
||||
} // namespace GL
|
130
src/common/d3d11/texture.cpp
Normal file
130
src/common/d3d11/texture.cpp
Normal file
|
@ -0,0 +1,130 @@
|
|||
#include "texture.h"
|
||||
#include "YBaseLib/Log.h"
|
||||
Log_SetChannel(D3D11);
|
||||
|
||||
namespace D3D11 {
|
||||
|
||||
Texture::Texture() : m_width(0), m_height(0) {}
|
||||
|
||||
Texture::Texture(ComPtr<ID3D11Texture2D> texture, ComPtr<ID3D11ShaderResourceView> srv,
|
||||
ComPtr<ID3D11RenderTargetView> rtv)
|
||||
: m_texture(std::move(texture)), m_srv(std::move(srv)), m_rtv(std::move(rtv))
|
||||
{
|
||||
const D3D11_TEXTURE2D_DESC desc = GetDesc();
|
||||
m_width = desc.Width;
|
||||
m_height = desc.Height;
|
||||
}
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
D3D11_TEXTURE2D_DESC Texture::GetDesc() const
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
m_texture->GetDesc(&desc);
|
||||
return desc;
|
||||
}
|
||||
|
||||
bool Texture::Create(ID3D11Device* device, u32 width, u32 height, DXGI_FORMAT format, bool shader_resource,
|
||||
bool render_target, const void* initial_data, u32 initial_data_stride)
|
||||
{
|
||||
CD3D11_TEXTURE2D_DESC desc(format, width, height, 1, 1, 0, D3D11_USAGE_DEFAULT, 0, 1, 0, 0);
|
||||
if (shader_resource)
|
||||
desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
|
||||
if (render_target)
|
||||
desc.BindFlags |= D3D11_BIND_RENDER_TARGET;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA srd;
|
||||
srd.pSysMem = initial_data;
|
||||
srd.SysMemPitch = initial_data_stride;
|
||||
srd.SysMemSlicePitch = initial_data_stride * height;
|
||||
|
||||
ComPtr<ID3D11Texture2D> texture;
|
||||
const HRESULT tex_hr = device->CreateTexture2D(&desc, initial_data ? &srd : nullptr, texture.GetAddressOf());
|
||||
if (FAILED(tex_hr))
|
||||
{
|
||||
Log_ErrorPrintf("Create texture failed: 0x%08X", tex_hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
ComPtr<ID3D11ShaderResourceView> srv;
|
||||
if (shader_resource)
|
||||
{
|
||||
const CD3D11_SHADER_RESOURCE_VIEW_DESC srv_desc(D3D11_SRV_DIMENSION_TEXTURE2D, desc.Format, 0, desc.MipLevels, 0,
|
||||
desc.ArraySize);
|
||||
const HRESULT hr = device->CreateShaderResourceView(texture.Get(), &srv_desc, srv.GetAddressOf());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Create SRV for adopted texture failed: 0x%08X", hr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ComPtr<ID3D11RenderTargetView> rtv;
|
||||
if (render_target)
|
||||
{
|
||||
const CD3D11_RENDER_TARGET_VIEW_DESC rtv_desc(D3D11_RTV_DIMENSION_TEXTURE2D, desc.Format, 0, 0, desc.ArraySize);
|
||||
const HRESULT hr = device->CreateRenderTargetView(texture.Get(), &rtv_desc, rtv.GetAddressOf());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Create RTV for adopted texture failed: 0x%08X", hr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_texture = std::move(texture);
|
||||
m_srv = std::move(srv);
|
||||
m_rtv = std::move(rtv);
|
||||
m_width = desc.Width;
|
||||
m_height = desc.Height;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Texture::Adopt(ID3D11Device* device, ComPtr<ID3D11Texture2D> texture)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
texture->GetDesc(&desc);
|
||||
|
||||
ComPtr<ID3D11ShaderResourceView> srv;
|
||||
if (desc.BindFlags & D3D11_BIND_SHADER_RESOURCE)
|
||||
{
|
||||
const CD3D11_SHADER_RESOURCE_VIEW_DESC srv_desc(D3D11_SRV_DIMENSION_TEXTURE2D, desc.Format, 0, desc.MipLevels, 0,
|
||||
desc.ArraySize);
|
||||
const HRESULT hr = device->CreateShaderResourceView(texture.Get(), &srv_desc, srv.ReleaseAndGetAddressOf());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Create SRV for adopted texture failed: 0x%08X", hr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ComPtr<ID3D11RenderTargetView> rtv;
|
||||
if (desc.BindFlags & D3D11_BIND_RENDER_TARGET)
|
||||
{
|
||||
const CD3D11_RENDER_TARGET_VIEW_DESC rtv_desc(D3D11_RTV_DIMENSION_TEXTURE2D, desc.Format, 0, 0, desc.ArraySize);
|
||||
const HRESULT hr = device->CreateRenderTargetView(texture.Get(), &rtv_desc, rtv.ReleaseAndGetAddressOf());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Create RTV for adopted texture failed: 0x%08X", hr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_texture = std::move(texture);
|
||||
m_srv = std::move(srv);
|
||||
m_rtv = std::move(rtv);
|
||||
m_width = desc.Width;
|
||||
m_height = desc.Height;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Texture::Destroy()
|
||||
{
|
||||
m_rtv.Reset();
|
||||
m_srv.Reset();
|
||||
m_texture.Reset();
|
||||
}
|
||||
|
||||
} // namespace D3D11
|
47
src/common/d3d11/texture.h
Normal file
47
src/common/d3d11/texture.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
#pragma once
|
||||
#include "../types.h"
|
||||
#include "YBaseLib/Windows/WindowsHeaders.h"
|
||||
#include <d3d11.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
namespace D3D11 {
|
||||
class Texture
|
||||
{
|
||||
public:
|
||||
template<typename T>
|
||||
using ComPtr = Microsoft::WRL::ComPtr<T>;
|
||||
|
||||
Texture();
|
||||
Texture(ComPtr<ID3D11Texture2D> texture, ComPtr<ID3D11ShaderResourceView> srv, ComPtr<ID3D11RenderTargetView> rtv);
|
||||
~Texture();
|
||||
|
||||
ALWAYS_INLINE ID3D11Texture2D* GetD3DTexture() const { return m_texture.Get(); }
|
||||
ALWAYS_INLINE ID3D11ShaderResourceView* GetD3DSRV() const { return m_srv.Get(); }
|
||||
ALWAYS_INLINE ID3D11RenderTargetView* GetD3DRTV() const { return m_rtv.Get(); }
|
||||
ALWAYS_INLINE ID3D11ShaderResourceView* const* GetD3DSRVArray() const { return m_srv.GetAddressOf(); }
|
||||
ALWAYS_INLINE ID3D11RenderTargetView* const* GetD3DRTVArray() const { return m_rtv.GetAddressOf(); }
|
||||
|
||||
ALWAYS_INLINE u32 GetWidth() const { return m_width; }
|
||||
ALWAYS_INLINE u32 GetHeight() const { return m_height; }
|
||||
ALWAYS_INLINE DXGI_FORMAT GetFormat() const { return GetDesc().Format; }
|
||||
D3D11_TEXTURE2D_DESC GetDesc() const;
|
||||
|
||||
ALWAYS_INLINE operator ID3D11Texture2D*() const { return m_texture.Get(); }
|
||||
ALWAYS_INLINE operator ID3D11ShaderResourceView*() const { return m_srv.Get(); }
|
||||
ALWAYS_INLINE operator ID3D11RenderTargetView*() const { return m_rtv.Get(); }
|
||||
ALWAYS_INLINE operator bool() const { return static_cast<bool>(m_texture); }
|
||||
|
||||
bool Create(ID3D11Device* device, u32 width, u32 height, DXGI_FORMAT format, bool shader_resource, bool render_target,
|
||||
const void* initial_data = nullptr, u32 initial_data_stride = 0);
|
||||
bool Adopt(ID3D11Device* device, ComPtr<ID3D11Texture2D> texture);
|
||||
|
||||
void Destroy();
|
||||
|
||||
private:
|
||||
ComPtr<ID3D11Texture2D> m_texture;
|
||||
ComPtr<ID3D11ShaderResourceView> m_srv;
|
||||
ComPtr<ID3D11RenderTargetView> m_rtv;
|
||||
u32 m_width;
|
||||
u32 m_height;
|
||||
};
|
||||
} // namespace D3D11
|
Loading…
Reference in a new issue