Revert r7421 and r7422.
Should fix issue 4413. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7592 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
e5210de9d5
commit
8244efcc02
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
// Update this to the current SVN revision every time you change shader generation code.
|
// Update this to the current SVN revision every time you change shader generation code.
|
||||||
// We don't automatically get this from SVN_REV because that would mean regenerating the
|
// We don't automatically get this from SVN_REV because that would mean regenerating the
|
||||||
|
@ -44,15 +43,12 @@ enum
|
||||||
// value_type[value_size] value;
|
// value_type[value_size] value;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// Example reader:
|
template <typename K, typename V>
|
||||||
//
|
class LinearDiskCacheReader
|
||||||
//class LinearDiskCacheReader
|
{
|
||||||
//{
|
public:
|
||||||
//public:
|
virtual void Read(const K &key, const V *value, u32 value_size) = 0;
|
||||||
// template <typename F>
|
};
|
||||||
// void operator()(const K& key, u32 value_size, F get_data) const
|
|
||||||
// {...}
|
|
||||||
//};
|
|
||||||
|
|
||||||
// Dead simple unsorted key-value store with append functionality.
|
// Dead simple unsorted key-value store with append functionality.
|
||||||
// No random read functionality, all reading is done in OpenAndRead.
|
// No random read functionality, all reading is done in OpenAndRead.
|
||||||
|
@ -71,45 +67,48 @@ class LinearDiskCache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// return number of read entries
|
// return number of read entries
|
||||||
template <typename LinearDiskCacheReader>
|
u32 OpenAndRead(const char *filename, LinearDiskCacheReader<K, V> &reader)
|
||||||
u32 OpenAndRead(const char* filename, LinearDiskCacheReader& reader)
|
|
||||||
{
|
{
|
||||||
using std::ios;
|
using std::ios_base;
|
||||||
|
|
||||||
// close any currently opened file
|
// close any currently opened file
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
// try opening for reading/writing
|
// try opening for reading/writing
|
||||||
m_file.open(filename, ios::in | ios::out | ios::binary | ios::app);
|
m_file.open(filename, ios_base::in | ios_base::out | ios_base::binary | ios_base::app);
|
||||||
|
|
||||||
if (m_file.is_open() && ValidateHeader())
|
if (m_file.is_open() && ValidateHeader())
|
||||||
{
|
{
|
||||||
// good header, read some key/value pairs
|
// good header, read some key/value pairs
|
||||||
u32 num_entries = 0;
|
u32 num_entries = 0;
|
||||||
|
|
||||||
u32 value_size;
|
|
||||||
K key;
|
K key;
|
||||||
while (Read(&value_size) && Read(&key))
|
|
||||||
|
V *value = NULL;
|
||||||
|
u32 value_size;
|
||||||
|
|
||||||
|
while (Read(&value_size))
|
||||||
{
|
{
|
||||||
std::streamoff const pos = m_file.tellg();
|
delete[] value;
|
||||||
|
value = new V[value_size];
|
||||||
|
|
||||||
// pass key and value_size to reader with callback function to read the data
|
// read key/value and pass to reader
|
||||||
reader(key, value_size, [this, &value_size](V* data){ Read(data, value_size); });
|
if (Read(&key) && Read(value, value_size))
|
||||||
|
reader.Read(key, value, value_size);
|
||||||
// seek past data (in case reader didn't read it for whatever reason)
|
else
|
||||||
m_file.seekg(pos + (value_size * sizeof(V)), ios::beg);
|
break;
|
||||||
|
|
||||||
++num_entries;
|
++num_entries;
|
||||||
}
|
}
|
||||||
m_file.clear();
|
m_file.clear();
|
||||||
|
|
||||||
|
delete[] value;
|
||||||
return num_entries;
|
return num_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
// failed to open file for reading or bad header
|
// failed to open file for reading or bad header
|
||||||
// close and recreate file
|
// close and recreate file
|
||||||
Close();
|
Close();
|
||||||
m_file.open(filename, ios::out | ios::trunc | ios::binary);
|
m_file.open(filename, ios_base::out | ios_base::trunc | ios_base::binary);
|
||||||
WriteHeader();
|
WriteHeader();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,6 +191,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Src\D3DBase.cpp" />
|
<ClCompile Include="Src\D3DBase.cpp" />
|
||||||
|
<ClCompile Include="Src\D3DBlob.cpp" />
|
||||||
<ClCompile Include="Src\D3DShader.cpp" />
|
<ClCompile Include="Src\D3DShader.cpp" />
|
||||||
<ClCompile Include="Src\D3DTexture.cpp" />
|
<ClCompile Include="Src\D3DTexture.cpp" />
|
||||||
<ClCompile Include="Src\D3DUtil.cpp" />
|
<ClCompile Include="Src\D3DUtil.cpp" />
|
||||||
|
@ -219,6 +220,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Src\D3DBase.h" />
|
<ClInclude Include="Src\D3DBase.h" />
|
||||||
|
<ClInclude Include="Src\D3DBlob.h" />
|
||||||
<ClInclude Include="Src\D3DShader.h" />
|
<ClInclude Include="Src\D3DShader.h" />
|
||||||
<ClInclude Include="Src\D3DTexture.h" />
|
<ClInclude Include="Src\D3DTexture.h" />
|
||||||
<ClInclude Include="Src\D3DUtil.h" />
|
<ClInclude Include="Src\D3DUtil.h" />
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
<ClCompile Include="Src\D3DBase.cpp">
|
<ClCompile Include="Src\D3DBase.cpp">
|
||||||
<Filter>D3D</Filter>
|
<Filter>D3D</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Src\D3DBlob.cpp">
|
||||||
|
<Filter>D3D</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="Src\D3DShader.cpp">
|
<ClCompile Include="Src\D3DShader.cpp">
|
||||||
<Filter>D3D</Filter>
|
<Filter>D3D</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -66,6 +69,9 @@
|
||||||
<ClInclude Include="Src\D3DBase.h">
|
<ClInclude Include="Src\D3DBase.h">
|
||||||
<Filter>D3D</Filter>
|
<Filter>D3D</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Src\D3DBlob.h">
|
||||||
|
<Filter>D3D</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="Src\D3DShader.h">
|
<ClInclude Include="Src\D3DShader.h">
|
||||||
<Filter>D3D</Filter>
|
<Filter>D3D</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -43,120 +43,20 @@ int dxgi_dll_ref = 0;
|
||||||
typedef HRESULT (WINAPI* D3D11CREATEDEVICEANDSWAPCHAIN)(IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL*, UINT, UINT, CONST DXGI_SWAP_CHAIN_DESC*, IDXGISwapChain**, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext**);
|
typedef HRESULT (WINAPI* D3D11CREATEDEVICEANDSWAPCHAIN)(IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL*, UINT, UINT, CONST DXGI_SWAP_CHAIN_DESC*, IDXGISwapChain**, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext**);
|
||||||
D3D11CREATEDEVICE PD3D11CreateDevice = NULL;
|
D3D11CREATEDEVICE PD3D11CreateDevice = NULL;
|
||||||
D3D11CREATEDEVICEANDSWAPCHAIN PD3D11CreateDeviceAndSwapChain = NULL;
|
D3D11CREATEDEVICEANDSWAPCHAIN PD3D11CreateDeviceAndSwapChain = NULL;
|
||||||
D3D10CREATEBLOB PD3D10CreateBlob = NULL;
|
HINSTANCE hD3DDll = NULL;
|
||||||
|
|
||||||
HINSTANCE hD3DDll_10 = NULL;
|
|
||||||
HINSTANCE hD3DDll_11 = NULL;
|
|
||||||
|
|
||||||
int d3d_dll_ref = 0;
|
int d3d_dll_ref = 0;
|
||||||
|
|
||||||
// SharedPtr funcs
|
|
||||||
HRESULT D3D11CreateDeviceShared(IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType,
|
|
||||||
HMODULE Software, UINT Flags, const D3D_FEATURE_LEVEL *pFeatureLevels,
|
|
||||||
UINT FeatureLevels, UINT SDKVersion, SharedPtr<ID3D11Device>* _Device,
|
|
||||||
D3D_FEATURE_LEVEL *pFeatureLevel, SharedPtr<ID3D11DeviceContext>* _ImmediateContext)
|
|
||||||
{
|
|
||||||
ID3D11Device* device = nullptr;
|
|
||||||
ID3D11DeviceContext* context = nullptr;
|
|
||||||
|
|
||||||
const HRESULT hr = PD3D11CreateDevice(pAdapter, DriverType, Software, Flags, pFeatureLevels,
|
|
||||||
FeatureLevels, SDKVersion, &device, pFeatureLevel, &context);
|
|
||||||
|
|
||||||
if (_Device)
|
|
||||||
*_Device = SharedPtr<ID3D11Device>::FromPtr(device);
|
|
||||||
|
|
||||||
if (_ImmediateContext)
|
|
||||||
*_ImmediateContext = SharedPtr<ID3D11DeviceContext>::FromPtr(context);
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT D3D11CreateDeviceAndSwapChainShared(IDXGIAdapter *pAdapter,
|
|
||||||
D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, const D3D_FEATURE_LEVEL *pFeatureLevels,
|
|
||||||
UINT FeatureLevels, UINT SDKVersion, const DXGI_SWAP_CHAIN_DESC *pSwapChainDesc,
|
|
||||||
SharedPtr<IDXGISwapChain>* _SwapChain, SharedPtr<ID3D11Device>* _Device,
|
|
||||||
D3D_FEATURE_LEVEL *pFeatureLevel, SharedPtr<ID3D11DeviceContext>* _ImmediateContext)
|
|
||||||
{
|
|
||||||
ID3D11Device* device = nullptr;
|
|
||||||
IDXGISwapChain* chain = nullptr;
|
|
||||||
ID3D11DeviceContext* context = nullptr;
|
|
||||||
|
|
||||||
const HRESULT hr = PD3D11CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags,
|
|
||||||
pFeatureLevels, FeatureLevels, SDKVersion, pSwapChainDesc, &chain, &device, pFeatureLevel, &context);
|
|
||||||
|
|
||||||
if (_Device)
|
|
||||||
*_Device = SharedPtr<ID3D11Device>::FromPtr(device);
|
|
||||||
|
|
||||||
if (_SwapChain)
|
|
||||||
*_SwapChain = SharedPtr<IDXGISwapChain>::FromPtr(chain);
|
|
||||||
|
|
||||||
if (_ImmediateContext)
|
|
||||||
*_ImmediateContext = SharedPtr<ID3D11DeviceContext>::FromPtr(context);
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedPtr<ID3D11Texture2D> CreateTexture2DShared(
|
|
||||||
const D3D11_TEXTURE2D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData)
|
|
||||||
{
|
|
||||||
ID3D11Texture2D* texture = nullptr;
|
|
||||||
|
|
||||||
D3D::g_device->CreateTexture2D(pDesc, pInitialData, &texture);
|
|
||||||
|
|
||||||
return SharedPtr<ID3D11Texture2D>::FromPtr(texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedPtr<ID3D11Texture2D> SwapChainGetBufferTexture2DShared(IDXGISwapChain* swapchain, UINT buffer)
|
|
||||||
{
|
|
||||||
ID3D11Texture2D* buf = nullptr;
|
|
||||||
|
|
||||||
swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf);
|
|
||||||
|
|
||||||
return SharedPtr<ID3D11Texture2D>::FromPtr(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedPtr<ID3D11BlendState> CreateBlendStateShared(const D3D11_BLEND_DESC *pBlendStateDesc)
|
|
||||||
{
|
|
||||||
ID3D11BlendState* state = nullptr;
|
|
||||||
|
|
||||||
D3D::g_device->CreateBlendState(pBlendStateDesc, &state);
|
|
||||||
|
|
||||||
return SharedPtr<ID3D11BlendState>::FromPtr(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedPtr<ID3D11InputLayout> CreateInputLayoutShared(const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs,
|
|
||||||
UINT NumElements, const void *pShaderBytecodeWithInputSignature, SIZE_T BytecodeLength)
|
|
||||||
{
|
|
||||||
ID3D11InputLayout* layout = nullptr;
|
|
||||||
|
|
||||||
D3D::g_device->CreateInputLayout(pInputElementDescs, NumElements,
|
|
||||||
pShaderBytecodeWithInputSignature, BytecodeLength, &layout);
|
|
||||||
|
|
||||||
return SharedPtr<ID3D11InputLayout>::FromPtr(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedPtr<ID3D11Buffer> CreateBufferShared(const D3D11_BUFFER_DESC *pDesc,
|
|
||||||
const D3D11_SUBRESOURCE_DATA *pInitialData)
|
|
||||||
{
|
|
||||||
ID3D11Buffer* buffer = nullptr;
|
|
||||||
|
|
||||||
D3D::g_device->CreateBuffer(pDesc, pInitialData, &buffer);
|
|
||||||
|
|
||||||
return SharedPtr<ID3D11Buffer>::FromPtr(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
SharedPtr<ID3D11Device> g_device;
|
ID3D11Device* device = NULL;
|
||||||
SharedPtr<ID3D11DeviceContext> g_context;
|
ID3D11DeviceContext* context = NULL;
|
||||||
SharedPtr<IDXGISwapChain> g_swapchain;
|
IDXGISwapChain* swapchain = NULL;
|
||||||
|
|
||||||
D3D_FEATURE_LEVEL featlevel;
|
D3D_FEATURE_LEVEL featlevel;
|
||||||
std::unique_ptr<D3DTexture2D> backbuf;
|
D3DTexture2D* backbuf = NULL;
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
|
|
||||||
std::vector<DXGI_SAMPLE_DESC> g_aa_modes; // supported AA modes of the current adapter
|
std::vector<DXGI_SAMPLE_DESC> aa_modes; // supported AA modes of the current adapter
|
||||||
|
|
||||||
bool bgra_textures_supported;
|
bool bgra_textures_supported;
|
||||||
|
|
||||||
|
@ -191,36 +91,21 @@ HRESULT LoadDXGI()
|
||||||
|
|
||||||
HRESULT LoadD3D()
|
HRESULT LoadD3D()
|
||||||
{
|
{
|
||||||
if (d3d_dll_ref++ > 0)
|
if (d3d_dll_ref++ > 0) return S_OK;
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
hD3DDll_10 = LoadLibraryA("d3d10.dll");
|
if (hD3DDll) return S_OK;
|
||||||
if (!hD3DDll_10)
|
hD3DDll = LoadLibraryA("d3d11.dll");
|
||||||
{
|
if (!hD3DDll)
|
||||||
MessageBoxA(NULL, "Failed to load d3d10.dll", "Critical error", MB_OK | MB_ICONERROR);
|
|
||||||
--d3d_dll_ref;
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
hD3DDll_11 = LoadLibraryA("d3d11.dll");
|
|
||||||
if (!hD3DDll_11)
|
|
||||||
{
|
{
|
||||||
MessageBoxA(NULL, "Failed to load d3d11.dll", "Critical error", MB_OK | MB_ICONERROR);
|
MessageBoxA(NULL, "Failed to load d3d11.dll", "Critical error", MB_OK | MB_ICONERROR);
|
||||||
--d3d_dll_ref;
|
--d3d_dll_ref;
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
PD3D11CreateDevice = (D3D11CREATEDEVICE)GetProcAddress(hD3DDll, "D3D11CreateDevice");
|
||||||
|
if (PD3D11CreateDevice == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3D11CreateDevice!", "Critical error", MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
PD3D11CreateDevice = (D3D11CREATEDEVICE)GetProcAddress(hD3DDll_11, "D3D11CreateDevice");
|
PD3D11CreateDeviceAndSwapChain = (D3D11CREATEDEVICEANDSWAPCHAIN)GetProcAddress(hD3DDll, "D3D11CreateDeviceAndSwapChain");
|
||||||
if (PD3D11CreateDevice == NULL)
|
if (PD3D11CreateDeviceAndSwapChain == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3D11CreateDeviceAndSwapChain!", "Critical error", MB_OK | MB_ICONERROR);
|
||||||
MessageBoxA(NULL, "GetProcAddress failed for D3D11CreateDevice!", "Critical error", MB_OK | MB_ICONERROR);
|
|
||||||
|
|
||||||
PD3D11CreateDeviceAndSwapChain = (D3D11CREATEDEVICEANDSWAPCHAIN)GetProcAddress(hD3DDll_11, "D3D11CreateDeviceAndSwapChain");
|
|
||||||
if (PD3D11CreateDeviceAndSwapChain == NULL)
|
|
||||||
MessageBoxA(NULL, "GetProcAddress failed for D3D11CreateDeviceAndSwapChain!", "Critical error", MB_OK | MB_ICONERROR);
|
|
||||||
|
|
||||||
PD3D10CreateBlob = (D3D10CREATEBLOB)GetProcAddress(hD3DDll_10, "D3D10CreateBlob");
|
|
||||||
if (PD3D10CreateBlob == NULL)
|
|
||||||
MessageBoxA(NULL, "GetProcAddress failed for D3D10CreateBlob!", "Critical error", MB_OK | MB_ICONERROR);
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -316,17 +201,13 @@ void UnloadD3DX()
|
||||||
|
|
||||||
void UnloadD3D()
|
void UnloadD3D()
|
||||||
{
|
{
|
||||||
if (!d3d_dll_ref || --d3d_dll_ref != 0)
|
if (!d3d_dll_ref) return;
|
||||||
return;
|
if (--d3d_dll_ref != 0) return;
|
||||||
|
|
||||||
FreeLibrary(hD3DDll_10);
|
|
||||||
FreeLibrary(hD3DDll_11);
|
|
||||||
|
|
||||||
hD3DDll_10 = hD3DDll_11 = NULL;
|
|
||||||
|
|
||||||
|
if(hD3DDll) FreeLibrary(hD3DDll);
|
||||||
|
hD3DDll = NULL;
|
||||||
PD3D11CreateDevice = NULL;
|
PD3D11CreateDevice = NULL;
|
||||||
PD3D11CreateDeviceAndSwapChain = NULL;
|
PD3D11CreateDeviceAndSwapChain = NULL;
|
||||||
PD3D10CreateBlob = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnloadD3DCompiler()
|
void UnloadD3DCompiler()
|
||||||
|
@ -341,48 +222,45 @@ void UnloadD3DCompiler()
|
||||||
|
|
||||||
std::vector<DXGI_SAMPLE_DESC> EnumAAModes(IDXGIAdapter* adapter)
|
std::vector<DXGI_SAMPLE_DESC> EnumAAModes(IDXGIAdapter* adapter)
|
||||||
{
|
{
|
||||||
// NOTE: D3D 10.0 doesn't support multisampled resources which are bound as depth buffers AND shader resources.
|
|
||||||
// Thus, we can't have MSAA with 10.0 level hardware.
|
|
||||||
D3D_FEATURE_LEVEL feat_level;
|
|
||||||
|
|
||||||
SharedPtr<ID3D11Device> device;
|
|
||||||
SharedPtr<ID3D11DeviceContext> context;
|
|
||||||
|
|
||||||
const HRESULT hr = D3D11CreateDeviceShared(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL,
|
|
||||||
D3D11_CREATE_DEVICE_SINGLETHREADED, supported_feature_levels,
|
|
||||||
NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, std::addressof(device), &feat_level, std::addressof(context));
|
|
||||||
|
|
||||||
std::vector<DXGI_SAMPLE_DESC> aa_modes;
|
std::vector<DXGI_SAMPLE_DESC> aa_modes;
|
||||||
|
|
||||||
|
// NOTE: D3D 10.0 doesn't support multisampled resources which are bound as depth buffers AND shader resources.
|
||||||
|
// Thus, we can't have MSAA with 10.0 level hardware.
|
||||||
|
ID3D11Device* device;
|
||||||
|
ID3D11DeviceContext* context;
|
||||||
|
D3D_FEATURE_LEVEL feat_level;
|
||||||
|
HRESULT hr = PD3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &device, &feat_level, &context);
|
||||||
if (FAILED(hr) || feat_level == D3D_FEATURE_LEVEL_10_0)
|
if (FAILED(hr) || feat_level == D3D_FEATURE_LEVEL_10_0)
|
||||||
{
|
{
|
||||||
DXGI_SAMPLE_DESC desc;
|
DXGI_SAMPLE_DESC desc;
|
||||||
desc.Count = 1;
|
desc.Count = 1;
|
||||||
desc.Quality = 0;
|
desc.Quality = 0;
|
||||||
aa_modes.push_back(desc);
|
aa_modes.push_back(desc);
|
||||||
|
SAFE_RELEASE(context);
|
||||||
|
SAFE_RELEASE(device);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (UINT samples = 0; samples != D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; ++samples)
|
for (int samples = 0; samples < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; ++samples)
|
||||||
{
|
{
|
||||||
UINT quality_levels = 0;
|
UINT quality_levels = 0;
|
||||||
device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, samples, &quality_levels);
|
device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, samples, &quality_levels);
|
||||||
if (quality_levels > 0)
|
if (quality_levels > 0) {
|
||||||
{
|
|
||||||
DXGI_SAMPLE_DESC desc;
|
DXGI_SAMPLE_DESC desc;
|
||||||
desc.Count = samples;
|
desc.Count = samples;
|
||||||
for (desc.Quality = 0; desc.Quality != quality_levels; ++desc.Quality)
|
for (desc.Quality = 0; desc.Quality < quality_levels; ++desc.Quality)
|
||||||
aa_modes.push_back(desc);
|
aa_modes.push_back(desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
context->Release();
|
||||||
|
device->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
return aa_modes;
|
return aa_modes;
|
||||||
}
|
}
|
||||||
|
|
||||||
DXGI_SAMPLE_DESC GetAAMode(int index)
|
DXGI_SAMPLE_DESC GetAAMode(int index)
|
||||||
{
|
{
|
||||||
return g_aa_modes[index];
|
return aa_modes[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT Create(HWND wnd)
|
HRESULT Create(HWND wnd)
|
||||||
|
@ -409,37 +287,31 @@ HRESULT Create(HWND wnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
IDXGIFactory* factory;
|
IDXGIFactory* factory;
|
||||||
hr = PCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
|
|
||||||
if (FAILED(hr))
|
|
||||||
MessageBox(wnd, _T("Failed to create IDXGIFactory object"),
|
|
||||||
_T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
|
||||||
|
|
||||||
IDXGIAdapter* adapter;
|
IDXGIAdapter* adapter;
|
||||||
|
IDXGIOutput* output;
|
||||||
|
hr = PCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
|
||||||
|
if (FAILED(hr)) MessageBox(wnd, _T("Failed to create IDXGIFactory object"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
hr = factory->EnumAdapters(g_ActiveConfig.iAdapter, &adapter);
|
hr = factory->EnumAdapters(g_ActiveConfig.iAdapter, &adapter);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
// try using the first one
|
// try using the first one
|
||||||
hr = factory->EnumAdapters(0, &adapter);
|
hr = factory->EnumAdapters(0, &adapter);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate adapters"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
||||||
MessageBox(wnd, _T("Failed to enumerate adapters"),
|
|
||||||
_T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make this configurable
|
// TODO: Make this configurable
|
||||||
IDXGIOutput* output;
|
|
||||||
hr = adapter->EnumOutputs(0, &output);
|
hr = adapter->EnumOutputs(0, &output);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
// try using the first one
|
// try using the first one
|
||||||
hr = adapter->EnumOutputs(0, &output);
|
hr = adapter->EnumOutputs(0, &output);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate outputs"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
||||||
MessageBox(wnd, _T("Failed to enumerate outputs"),
|
|
||||||
_T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get supported AA modes
|
// get supported AA modes
|
||||||
g_aa_modes = EnumAAModes(adapter);
|
aa_modes = EnumAAModes(adapter);
|
||||||
if (g_Config.iMultisampleMode >= (int)g_aa_modes.size())
|
if (g_Config.iMultisampleMode >= (int)aa_modes.size())
|
||||||
{
|
{
|
||||||
g_Config.iMultisampleMode = 0;
|
g_Config.iMultisampleMode = 0;
|
||||||
UpdateActiveConfig();
|
UpdateActiveConfig();
|
||||||
|
@ -461,58 +333,49 @@ HRESULT Create(HWND wnd)
|
||||||
mode_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
mode_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
mode_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
mode_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||||
hr = output->FindClosestMatchingMode(&mode_desc, &swap_chain_desc.BufferDesc, NULL);
|
hr = output->FindClosestMatchingMode(&mode_desc, &swap_chain_desc.BufferDesc, NULL);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr)) MessageBox(wnd, _T("Failed to find a supported video mode"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
||||||
MessageBox(wnd, _T("Failed to find a supported video mode"),
|
|
||||||
_T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
|
||||||
|
|
||||||
// forcing buffer resolution to xres and yres.. TODO: The new video mode might not actually be supported!
|
// forcing buffer resolution to xres and yres.. TODO: The new video mode might not actually be supported!
|
||||||
swap_chain_desc.BufferDesc.Width = xres;
|
swap_chain_desc.BufferDesc.Width = xres;
|
||||||
swap_chain_desc.BufferDesc.Height = yres;
|
swap_chain_desc.BufferDesc.Height = yres;
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
const D3D11_CREATE_DEVICE_FLAG device_flags = (D3D11_CREATE_DEVICE_FLAG)(D3D11_CREATE_DEVICE_DEBUG
|
D3D11_CREATE_DEVICE_FLAG device_flags = (D3D11_CREATE_DEVICE_FLAG)(D3D11_CREATE_DEVICE_DEBUG|D3D11_CREATE_DEVICE_SINGLETHREADED);
|
||||||
| D3D11_CREATE_DEVICE_SINGLETHREADED);
|
|
||||||
#else
|
#else
|
||||||
const D3D11_CREATE_DEVICE_FLAG device_flags = D3D11_CREATE_DEVICE_SINGLETHREADED;
|
D3D11_CREATE_DEVICE_FLAG device_flags = D3D11_CREATE_DEVICE_SINGLETHREADED;
|
||||||
#endif
|
#endif
|
||||||
|
hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, device_flags,
|
||||||
SharedPtr<ID3D11Device> device;
|
supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS,
|
||||||
SharedPtr<IDXGISwapChain> swapchain;
|
D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device,
|
||||||
SharedPtr<ID3D11DeviceContext> context;
|
&featlevel, &context);
|
||||||
|
if (FAILED(hr) || !device || !context || !swapchain)
|
||||||
hr = D3D11CreateDeviceAndSwapChainShared(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, device_flags,
|
|
||||||
supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION,
|
|
||||||
&swap_chain_desc, std::addressof(swapchain), std::addressof(device), &featlevel, std::addressof(context));
|
|
||||||
|
|
||||||
if (FAILED(hr) || !device || !swapchain || !context)
|
|
||||||
{
|
{
|
||||||
MessageBox(wnd, _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"),
|
MessageBox(wnd, _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
||||||
_T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
SAFE_RELEASE(device);
|
||||||
|
SAFE_RELEASE(context);
|
||||||
|
SAFE_RELEASE(swapchain);
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
SetDebugObjectName((ID3D11DeviceChild*)context, "device context");
|
||||||
SetDebugObjectName(context, "device context");
|
|
||||||
|
|
||||||
SAFE_RELEASE(factory);
|
SAFE_RELEASE(factory);
|
||||||
SAFE_RELEASE(output);
|
SAFE_RELEASE(output);
|
||||||
SAFE_RELEASE(adapter);
|
SAFE_RELEASE(adapter);
|
||||||
|
|
||||||
auto const buf = SwapChainGetBufferTexture2DShared(swapchain, 0);
|
ID3D11Texture2D* buf;
|
||||||
if (!buf)
|
hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf);
|
||||||
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
MessageBox(wnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
MessageBox(wnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
||||||
|
SAFE_RELEASE(device);
|
||||||
|
SAFE_RELEASE(context);
|
||||||
|
SAFE_RELEASE(swapchain);
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
|
||||||
g_device = device;
|
SAFE_RELEASE(buf);
|
||||||
g_context = context;
|
|
||||||
g_swapchain = swapchain;
|
|
||||||
|
|
||||||
backbuf.reset(new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET));
|
|
||||||
|
|
||||||
CHECK(backbuf!=NULL, "Create back buffer texture");
|
CHECK(backbuf!=NULL, "Create back buffer texture");
|
||||||
SetDebugObjectName(backbuf->GetTex(), "backbuffer texture");
|
SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture");
|
||||||
SetDebugObjectName(backbuf->GetRTV(), "backbuffer render target view");
|
SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view");
|
||||||
|
|
||||||
context->OMSetRenderTargets(1, &backbuf->GetRTV(), NULL);
|
context->OMSetRenderTargets(1, &backbuf->GetRTV(), NULL);
|
||||||
|
|
||||||
|
@ -521,22 +384,30 @@ HRESULT Create(HWND wnd)
|
||||||
device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support);
|
device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support);
|
||||||
bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
|
bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
|
||||||
|
|
||||||
stateman.reset(new StateManager);
|
stateman = new StateManager;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Close()
|
void Close()
|
||||||
{
|
{
|
||||||
// release all bound resources
|
// release all bound resources
|
||||||
g_context->ClearState();
|
context->ClearState();
|
||||||
backbuf.reset();
|
SAFE_RELEASE(backbuf);
|
||||||
g_swapchain.reset();
|
SAFE_RELEASE(swapchain);
|
||||||
stateman.reset();
|
SAFE_DELETE(stateman);
|
||||||
g_context->Flush(); // immediately destroy device objects
|
context->Flush(); // immediately destroy device objects
|
||||||
|
|
||||||
g_context.reset();
|
SAFE_RELEASE(context);
|
||||||
g_device.reset();
|
ULONG references = device->Release();
|
||||||
|
if (references)
|
||||||
|
{
|
||||||
|
ERROR_LOG(VIDEO, "Unreleased references: %i.", references);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NOTICE_LOG(VIDEO, "Successfully released all device references!");
|
||||||
|
}
|
||||||
|
device = NULL;
|
||||||
|
|
||||||
// unload DLLs
|
// unload DLLs
|
||||||
UnloadD3DX();
|
UnloadD3DX();
|
||||||
|
@ -565,7 +436,7 @@ const char* PixelShaderVersionString()
|
||||||
else /*if(featlevel == D3D_FEATURE_LEVEL_10_0)*/ return "ps_4_0";
|
else /*if(featlevel == D3D_FEATURE_LEVEL_10_0)*/ return "ps_4_0";
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DTexture2D* GetBackBuffer() { return backbuf.get(); }
|
D3DTexture2D* &GetBackBuffer() { return backbuf; }
|
||||||
unsigned int GetBackBufferWidth() { return xres; }
|
unsigned int GetBackBufferWidth() { return xres; }
|
||||||
unsigned int GetBackBufferHeight() { return yres; }
|
unsigned int GetBackBufferHeight() { return yres; }
|
||||||
|
|
||||||
|
@ -598,27 +469,31 @@ unsigned int GetMaxTextureSize()
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
// release all back buffer references
|
// release all back buffer references
|
||||||
backbuf.reset();
|
SAFE_RELEASE(backbuf);
|
||||||
|
|
||||||
// resize swapchain buffers
|
// resize swapchain buffers
|
||||||
RECT client;
|
RECT client;
|
||||||
GetClientRect(hWnd, &client);
|
GetClientRect(hWnd, &client);
|
||||||
xres = client.right - client.left;
|
xres = client.right - client.left;
|
||||||
yres = client.bottom - client.top;
|
yres = client.bottom - client.top;
|
||||||
D3D::g_swapchain->ResizeBuffers(1, xres, yres, DXGI_FORMAT_R8G8B8A8_UNORM, 0);
|
D3D::swapchain->ResizeBuffers(1, xres, yres, DXGI_FORMAT_R8G8B8A8_UNORM, 0);
|
||||||
|
|
||||||
// recreate back buffer texture
|
// recreate back buffer texture
|
||||||
auto const buf = SwapChainGetBufferTexture2DShared(g_swapchain, 0);
|
ID3D11Texture2D* buf;
|
||||||
if (!buf)
|
HRESULT hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf);
|
||||||
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
MessageBox(hWnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
MessageBox(hWnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
||||||
|
SAFE_RELEASE(device);
|
||||||
|
SAFE_RELEASE(context);
|
||||||
|
SAFE_RELEASE(swapchain);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
|
||||||
backbuf.reset(new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET));
|
SAFE_RELEASE(buf);
|
||||||
CHECK(backbuf!=NULL, "Create back buffer texture");
|
CHECK(backbuf!=NULL, "Create back buffer texture");
|
||||||
SetDebugObjectName(backbuf->GetTex(), "backbuffer texture");
|
SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture");
|
||||||
SetDebugObjectName(backbuf->GetRTV(), "backbuffer render target view");
|
SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BeginFrame()
|
bool BeginFrame()
|
||||||
|
@ -628,9 +503,8 @@ bool BeginFrame()
|
||||||
PanicAlert("BeginFrame called although a frame is already in progress");
|
PanicAlert("BeginFrame called although a frame is already in progress");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bFrameInProgress = true;
|
bFrameInProgress = true;
|
||||||
return (g_device != NULL);
|
return (device != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EndFrame()
|
void EndFrame()
|
||||||
|
@ -646,7 +520,7 @@ void EndFrame()
|
||||||
void Present()
|
void Present()
|
||||||
{
|
{
|
||||||
// TODO: Is 1 the correct value for vsyncing?
|
// TODO: Is 1 the correct value for vsyncing?
|
||||||
g_swapchain->Present((UINT)g_ActiveConfig.bVSync, 0);
|
swapchain->Present((UINT)g_ActiveConfig.bVSync, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace D3D
|
} // namespace D3D
|
||||||
|
|
|
@ -17,35 +17,21 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <D3DX11.h>
|
#include <D3DX11.h>
|
||||||
#include <D3Dcompiler.h>
|
#include <D3Dcompiler.h>
|
||||||
|
|
||||||
#include "D3DUtil.h"
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
#define SAFE_RELEASE(x) { if (x) (x)->Release(); (x) = NULL; }
|
#define SAFE_RELEASE(x) { if (x) (x)->Release(); (x) = NULL; }
|
||||||
|
#define SAFE_DELETE(x) { delete (x); (x) = NULL; }
|
||||||
#define CHECK(cond, Message, ...) if (!(cond)) { \
|
#define SAFE_DELETE_ARRAY(x) { delete[] (x); (x) = NULL; }
|
||||||
PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); }
|
#define CHECK(cond, Message, ...) if (!(cond)) { PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); }
|
||||||
|
|
||||||
class D3DTexture2D;
|
class D3DTexture2D;
|
||||||
|
|
||||||
SharedPtr<ID3D11Texture2D> CreateTexture2DShared(
|
|
||||||
const D3D11_TEXTURE2D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData);
|
|
||||||
|
|
||||||
SharedPtr<ID3D11BlendState> CreateBlendStateShared(const D3D11_BLEND_DESC *pBlendStateDesc);
|
|
||||||
|
|
||||||
SharedPtr<ID3D11InputLayout> CreateInputLayoutShared(const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs,
|
|
||||||
UINT NumElements, const void *pShaderBytecodeWithInputSignature, SIZE_T BytecodeLength);
|
|
||||||
|
|
||||||
SharedPtr<ID3D11Buffer> CreateBufferShared(const D3D11_BUFFER_DESC *pDesc,
|
|
||||||
const D3D11_SUBRESOURCE_DATA *pInitialData);
|
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -64,10 +50,9 @@ DXGI_SAMPLE_DESC GetAAMode(int index);
|
||||||
HRESULT Create(HWND wnd);
|
HRESULT Create(HWND wnd);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
extern SharedPtr<ID3D11Device> g_device;
|
extern ID3D11Device* device;
|
||||||
extern SharedPtr<ID3D11DeviceContext> g_context;
|
extern ID3D11DeviceContext* context;
|
||||||
extern SharedPtr<IDXGISwapChain> g_swapchain;
|
extern IDXGISwapChain* swapchain;
|
||||||
|
|
||||||
extern bool bFrameInProgress;
|
extern bool bFrameInProgress;
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
@ -77,7 +62,7 @@ void Present();
|
||||||
|
|
||||||
unsigned int GetBackBufferWidth();
|
unsigned int GetBackBufferWidth();
|
||||||
unsigned int GetBackBufferHeight();
|
unsigned int GetBackBufferHeight();
|
||||||
D3DTexture2D* GetBackBuffer();
|
D3DTexture2D* &GetBackBuffer();
|
||||||
const char* PixelShaderVersionString();
|
const char* PixelShaderVersionString();
|
||||||
const char* GeometryShaderVersionString();
|
const char* GeometryShaderVersionString();
|
||||||
const char* VertexShaderVersionString();
|
const char* VertexShaderVersionString();
|
||||||
|
@ -93,7 +78,6 @@ void SetDebugObjectName(T resource, const char* name)
|
||||||
{
|
{
|
||||||
static_assert(std::is_convertible<T, ID3D11DeviceChild*>::value,
|
static_assert(std::is_convertible<T, ID3D11DeviceChild*>::value,
|
||||||
"resource must be convertible to ID3D11DeviceChild*");
|
"resource must be convertible to ID3D11DeviceChild*");
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
resource->SetPrivateData(WKPDID_D3DDebugObjectName, (UINT)strlen(name), name);
|
resource->SetPrivateData(WKPDID_D3DDebugObjectName, (UINT)strlen(name), name);
|
||||||
#endif
|
#endif
|
||||||
|
@ -127,8 +111,6 @@ typedef HRESULT (WINAPI* CREATEDXGIFACTORY)(REFIID, void**);
|
||||||
extern CREATEDXGIFACTORY PCreateDXGIFactory;
|
extern CREATEDXGIFACTORY PCreateDXGIFactory;
|
||||||
typedef HRESULT (WINAPI* D3D11CREATEDEVICE)(IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL*, UINT, UINT, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext**);
|
typedef HRESULT (WINAPI* D3D11CREATEDEVICE)(IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL*, UINT, UINT, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext**);
|
||||||
extern D3D11CREATEDEVICE PD3D11CreateDevice;
|
extern D3D11CREATEDEVICE PD3D11CreateDevice;
|
||||||
typedef HRESULT (WINAPI* D3D10CREATEBLOB)(SIZE_T NumBytes, LPD3D10BLOB *ppBuffer);
|
|
||||||
extern D3D10CREATEBLOB PD3D10CreateBlob;
|
|
||||||
|
|
||||||
typedef HRESULT (WINAPI *D3DREFLECT)(LPCVOID, SIZE_T, REFIID, void**);
|
typedef HRESULT (WINAPI *D3DREFLECT)(LPCVOID, SIZE_T, REFIID, void**);
|
||||||
extern D3DREFLECT PD3DReflect;
|
extern D3DREFLECT PD3DReflect;
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#include <d3d11.h>
|
||||||
|
#include "D3DBlob.h"
|
||||||
|
|
||||||
|
namespace DX11
|
||||||
|
{
|
||||||
|
|
||||||
|
D3DBlob::D3DBlob(unsigned int blob_size, const u8* init_data) : ref(1), size(blob_size), blob(NULL)
|
||||||
|
{
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8* D3DBlob::Data()
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace DX11
|
|
@ -0,0 +1,53 @@
|
||||||
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "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 = NULL);
|
||||||
|
|
||||||
|
// d3dblob will be AddRef'd
|
||||||
|
D3DBlob(ID3D10Blob* d3dblob);
|
||||||
|
|
||||||
|
void AddRef();
|
||||||
|
unsigned int Release();
|
||||||
|
|
||||||
|
unsigned int Size();
|
||||||
|
u8* Data();
|
||||||
|
|
||||||
|
private:
|
||||||
|
~D3DBlob();
|
||||||
|
|
||||||
|
unsigned int ref;
|
||||||
|
unsigned int size;
|
||||||
|
|
||||||
|
u8* data;
|
||||||
|
ID3D10Blob* blob;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
|
|
||||||
|
#include "D3DBase.h"
|
||||||
#include "D3DShader.h"
|
#include "D3DShader.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
|
@ -28,149 +29,217 @@ namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
// bytecode->shader
|
// bytecode->shader
|
||||||
SharedPtr<ID3D11VertexShader> CreateVertexShaderFromByteCode(const void* bytecode, unsigned int len)
|
ID3D11VertexShader* CreateVertexShaderFromByteCode(const void* bytecode, unsigned int len)
|
||||||
{
|
{
|
||||||
ID3D11VertexShader* v_shader = nullptr;
|
ID3D11VertexShader* v_shader;
|
||||||
HRESULT hr = D3D::g_device->CreateVertexShader(bytecode, len, NULL, &v_shader);
|
HRESULT hr = D3D::device->CreateVertexShader(bytecode, len, NULL, &v_shader);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
PanicAlert("CreateVertexShaderFromByteCode failed from %p (size %d) at %s %d\n",
|
{
|
||||||
bytecode, len, __FILE__, __LINE__);
|
PanicAlert("CreateVertexShaderFromByteCode failed from %p (size %d) at %s %d\n", bytecode, len, __FILE__, __LINE__);
|
||||||
|
v_shader = NULL;
|
||||||
return SharedPtr<ID3D11VertexShader>::FromPtr(v_shader);
|
}
|
||||||
|
return v_shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bytecode->shader
|
// code->bytecode
|
||||||
SharedPtr<ID3D11GeometryShader> CreateGeometryShaderFromByteCode(const void* bytecode, unsigned int len)
|
bool CompileVertexShader(const char* code, unsigned int len, D3DBlob** blob)
|
||||||
{
|
{
|
||||||
ID3D11GeometryShader* g_shader = nullptr;
|
ID3D10Blob* shaderBuffer = NULL;
|
||||||
HRESULT hr = D3D::g_device->CreateGeometryShader(bytecode, len, NULL, &g_shader);
|
ID3D10Blob* errorBuffer = NULL;
|
||||||
if (FAILED(hr))
|
|
||||||
PanicAlert("CreateGeometryShaderFromByteCode failed from %p (size %d) at %s %d\n",
|
|
||||||
bytecode, len, __FILE__, __LINE__);
|
|
||||||
|
|
||||||
return SharedPtr<ID3D11GeometryShader>::FromPtr(g_shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
// bytecode->shader
|
|
||||||
SharedPtr<ID3D11PixelShader> CreatePixelShaderFromByteCode(const void* bytecode, unsigned int len)
|
|
||||||
{
|
|
||||||
ID3D11PixelShader* p_shader = nullptr;
|
|
||||||
HRESULT hr = D3D::g_device->CreatePixelShader(bytecode, len, NULL, &p_shader);
|
|
||||||
if (FAILED(hr))
|
|
||||||
PanicAlert("CreatePixelShaderFromByteCode failed at %s %d\n", __FILE__, __LINE__);
|
|
||||||
|
|
||||||
return SharedPtr<ID3D11PixelShader>::FromPtr(p_shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
static SharedPtr<ID3D10Blob> CompileShader(const char* code, unsigned int len,
|
|
||||||
const char* ver_str, const D3D_SHADER_MACRO* pDefines = NULL)
|
|
||||||
{
|
|
||||||
static const UINT shader_compilation_flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY
|
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
| D3D10_SHADER_DEBUG | D3D10_SHADER_WARNINGS_ARE_ERRORS;
|
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_DEBUG|D3D10_SHADER_WARNINGS_ARE_ERRORS;
|
||||||
#else
|
#else
|
||||||
| D3D10_SHADER_OPTIMIZATION_LEVEL3 | D3D10_SHADER_SKIP_VALIDATION;
|
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_OPTIMIZATION_LEVEL3|D3D10_SHADER_SKIP_VALIDATION;
|
||||||
#endif
|
#endif
|
||||||
|
HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, NULL, NULL, "main", D3D::VertexShaderVersionString(),
|
||||||
ID3D10Blob* shaderBuffer = nullptr;
|
flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL);
|
||||||
ID3D10Blob* errorBuffer = nullptr;
|
|
||||||
|
|
||||||
HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, pDefines, NULL, "main", ver_str,
|
|
||||||
shader_compilation_flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL);
|
|
||||||
|
|
||||||
if (FAILED(hr) && g_ActiveConfig.bShowShaderErrors)
|
|
||||||
{
|
|
||||||
std::string msg = (const char*)errorBuffer->GetBufferPointer();
|
|
||||||
msg += "\n\n";
|
|
||||||
msg += ver_str;
|
|
||||||
msg += "\n\n";
|
|
||||||
msg += code;
|
|
||||||
MessageBoxA(0, msg.c_str(), "Error compiling shader", MB_ICONERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorBuffer)
|
if (errorBuffer)
|
||||||
{
|
{
|
||||||
INFO_LOG(VIDEO, "Shader %s compiler messages:\n%s\n", ver_str,
|
INFO_LOG(VIDEO, "Vertex shader compiler messages:\n%s\n",
|
||||||
(const char*)errorBuffer->GetBufferPointer());
|
(const char*)errorBuffer->GetBufferPointer());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
if (g_ActiveConfig.bShowShaderErrors)
|
||||||
|
{
|
||||||
|
std::string msg = (char*)errorBuffer->GetBufferPointer();
|
||||||
|
msg += "\n\n";
|
||||||
|
msg += D3D::VertexShaderVersionString();
|
||||||
|
msg += "\n\n";
|
||||||
|
msg += code;
|
||||||
|
MessageBoxA(0, msg.c_str(), "Error compiling vertex shader", MB_ICONERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
*blob = NULL;
|
||||||
errorBuffer->Release();
|
errorBuffer->Release();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
return SharedPtr<ID3D10Blob>::FromPtr(shaderBuffer);
|
{
|
||||||
|
*blob = new D3DBlob(shaderBuffer);
|
||||||
|
shaderBuffer->Release();
|
||||||
|
}
|
||||||
|
return SUCCEEDED(hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// code->bytecode
|
// bytecode->shader
|
||||||
SharedPtr<ID3D10Blob> CompileVertexShader(const char* code, unsigned int len)
|
ID3D11GeometryShader* CreateGeometryShaderFromByteCode(const void* bytecode, unsigned int len)
|
||||||
{
|
{
|
||||||
return CompileShader(code, len, D3D::VertexShaderVersionString());
|
ID3D11GeometryShader* g_shader;
|
||||||
|
HRESULT hr = D3D::device->CreateGeometryShader(bytecode, len, NULL, &g_shader);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
PanicAlert("CreateGeometryShaderFromByteCode failed from %p (size %d) at %s %d\n", bytecode, len, __FILE__, __LINE__);
|
||||||
|
g_shader = NULL;
|
||||||
|
}
|
||||||
|
return g_shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
// code->bytecode
|
// code->bytecode
|
||||||
SharedPtr<ID3D10Blob> CompileGeometryShader(const char* code, unsigned int len,
|
bool CompileGeometryShader(const char* code, unsigned int len, D3DBlob** blob,
|
||||||
const D3D_SHADER_MACRO* pDefines)
|
const D3D_SHADER_MACRO* pDefines)
|
||||||
{
|
{
|
||||||
return CompileShader(code, len, D3D::GeometryShaderVersionString(), pDefines);
|
ID3D10Blob* shaderBuffer = NULL;
|
||||||
|
ID3D10Blob* errorBuffer = NULL;
|
||||||
|
|
||||||
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
|
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_DEBUG|D3D10_SHADER_WARNINGS_ARE_ERRORS;
|
||||||
|
#else
|
||||||
|
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_OPTIMIZATION_LEVEL3|D3D10_SHADER_SKIP_VALIDATION;
|
||||||
|
#endif
|
||||||
|
HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, pDefines, NULL, "main", D3D::GeometryShaderVersionString(),
|
||||||
|
flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL);
|
||||||
|
|
||||||
|
if (errorBuffer)
|
||||||
|
{
|
||||||
|
INFO_LOG(VIDEO, "Geometry shader compiler messages:\n%s\n",
|
||||||
|
(const char*)errorBuffer->GetBufferPointer());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
if (g_ActiveConfig.bShowShaderErrors)
|
||||||
|
{
|
||||||
|
std::string msg = (char*)errorBuffer->GetBufferPointer();
|
||||||
|
msg += "\n\n";
|
||||||
|
msg += D3D::GeometryShaderVersionString();
|
||||||
|
msg += "\n\n";
|
||||||
|
msg += code;
|
||||||
|
MessageBoxA(0, msg.c_str(), "Error compiling geometry shader", MB_ICONERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
*blob = NULL;
|
||||||
|
errorBuffer->Release();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*blob = new D3DBlob(shaderBuffer);
|
||||||
|
shaderBuffer->Release();
|
||||||
|
}
|
||||||
|
return SUCCEEDED(hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bytecode->shader
|
||||||
|
ID3D11PixelShader* CreatePixelShaderFromByteCode(const void* bytecode, unsigned int len)
|
||||||
|
{
|
||||||
|
ID3D11PixelShader* p_shader;
|
||||||
|
HRESULT hr = D3D::device->CreatePixelShader(bytecode, len, NULL, &p_shader);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
PanicAlert("CreatePixelShaderFromByteCode failed at %s %d\n", __FILE__, __LINE__);
|
||||||
|
p_shader = NULL;
|
||||||
|
}
|
||||||
|
return p_shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
// code->bytecode
|
// code->bytecode
|
||||||
SharedPtr<ID3D10Blob> CompilePixelShader(const char* code, unsigned int len,
|
bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob,
|
||||||
const D3D_SHADER_MACRO* pDefines)
|
const D3D_SHADER_MACRO* pDefines)
|
||||||
{
|
{
|
||||||
return CompileShader(code, len, D3D::PixelShaderVersionString(), pDefines);
|
ID3D10Blob* shaderBuffer = NULL;
|
||||||
}
|
ID3D10Blob* errorBuffer = NULL;
|
||||||
|
|
||||||
SharedPtr<ID3D11VertexShader> CompileAndCreateVertexShader(const char* code, unsigned int len,
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
SharedPtr<ID3D10Blob>* bytecode)
|
UINT flags = D3D10_SHADER_DEBUG|D3D10_SHADER_WARNINGS_ARE_ERRORS;
|
||||||
{
|
#else
|
||||||
auto const blob = CompileVertexShader(code, len);
|
UINT flags = D3D10_SHADER_OPTIMIZATION_LEVEL3;
|
||||||
if (blob)
|
#endif
|
||||||
|
HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, pDefines, NULL, "main", D3D::PixelShaderVersionString(),
|
||||||
|
flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL);
|
||||||
|
|
||||||
|
if (errorBuffer)
|
||||||
{
|
{
|
||||||
if (bytecode)
|
INFO_LOG(VIDEO, "Pixel shader compiler messages:\n%s",
|
||||||
*bytecode = blob;
|
(const char*)errorBuffer->GetBufferPointer());
|
||||||
return CreateVertexShaderFromByteCode(blob->GetBufferPointer(), (unsigned int)blob->GetBufferSize());
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
if (g_ActiveConfig.bShowShaderErrors)
|
||||||
|
{
|
||||||
|
std::string msg = (char*)errorBuffer->GetBufferPointer();
|
||||||
|
msg += "\n\n";
|
||||||
|
msg += D3D::PixelShaderVersionString();
|
||||||
|
msg += "\n\n";
|
||||||
|
msg += code;
|
||||||
|
MessageBoxA(0, msg.c_str(), "Error compiling pixel shader", MB_ICONERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
*blob = NULL;
|
||||||
|
errorBuffer->Release();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to compile and create vertex shader from %p (size %d) at %s %d\n",
|
*blob = new D3DBlob(shaderBuffer);
|
||||||
code, len, __FILE__, __LINE__);
|
shaderBuffer->Release();
|
||||||
return SharedPtr<ID3D11VertexShader>::FromPtr(nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return SUCCEEDED(hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<ID3D11GeometryShader> CompileAndCreateGeometryShader(const char* code, unsigned int len,
|
ID3D11VertexShader* CompileAndCreateVertexShader(const char* code,
|
||||||
const D3D_SHADER_MACRO* pDefines, SharedPtr<ID3D10Blob>* bytecode)
|
unsigned int len)
|
||||||
{
|
{
|
||||||
auto const blob = CompileGeometryShader(code, len, pDefines);
|
D3DBlob* blob = NULL;
|
||||||
if (blob)
|
if (CompileVertexShader(code, len, &blob))
|
||||||
{
|
{
|
||||||
if (bytecode)
|
ID3D11VertexShader* v_shader = CreateVertexShaderFromByteCode(blob);
|
||||||
*bytecode = blob;
|
blob->Release();
|
||||||
return CreateGeometryShaderFromByteCode(blob->GetBufferPointer(), (unsigned int)blob->GetBufferSize());
|
return v_shader;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PanicAlert("Failed to compile and create geometry shader from %p (size %d) at %s %d\n",
|
|
||||||
code, len, __FILE__, __LINE__);
|
|
||||||
return SharedPtr<ID3D11GeometryShader>::FromPtr(nullptr);
|
|
||||||
}
|
}
|
||||||
|
PanicAlert("Failed to compile and create vertex shader from %p (size %d) at %s %d\n", code, len, __FILE__, __LINE__);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<ID3D11PixelShader> CompileAndCreatePixelShader(const char* code, unsigned int len,
|
ID3D11GeometryShader* CompileAndCreateGeometryShader(const char* code,
|
||||||
const D3D_SHADER_MACRO* pDefines, SharedPtr<ID3D10Blob>* bytecode)
|
unsigned int len, const D3D_SHADER_MACRO* pDefines)
|
||||||
{
|
{
|
||||||
auto const blob = CompilePixelShader(code, len, pDefines);
|
D3DBlob* blob = NULL;
|
||||||
|
if (CompileGeometryShader(code, len, &blob, pDefines))
|
||||||
|
{
|
||||||
|
ID3D11GeometryShader* g_shader = CreateGeometryShaderFromByteCode(blob);
|
||||||
|
blob->Release();
|
||||||
|
return g_shader;
|
||||||
|
}
|
||||||
|
PanicAlert("Failed to compile and create geometry shader from %p (size %d) at %s %d\n", code, len, __FILE__, __LINE__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D11PixelShader* CompileAndCreatePixelShader(const char* code,
|
||||||
|
unsigned int len)
|
||||||
|
{
|
||||||
|
D3DBlob* blob = NULL;
|
||||||
|
CompilePixelShader(code, len, &blob);
|
||||||
if (blob)
|
if (blob)
|
||||||
{
|
{
|
||||||
if (bytecode)
|
ID3D11PixelShader* p_shader = CreatePixelShaderFromByteCode(blob);
|
||||||
*bytecode = blob;
|
blob->Release();
|
||||||
return CreatePixelShaderFromByteCode(blob->GetBufferPointer(), (unsigned int)blob->GetBufferSize());
|
return p_shader;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PanicAlert("Failed to compile and create pixel shader, %s %d\n", __FILE__, __LINE__);
|
|
||||||
return SharedPtr<ID3D11PixelShader>::FromPtr(nullptr);
|
|
||||||
}
|
}
|
||||||
|
PanicAlert("Failed to compile and create pixel shader, %s %d\n", __FILE__, __LINE__);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -18,47 +18,49 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "D3DBase.h"
|
#include "D3DBase.h"
|
||||||
|
#include "D3DBlob.h"
|
||||||
|
|
||||||
|
struct ID3D11PixelShader;
|
||||||
|
struct ID3D11VertexShader;
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
ID3D11VertexShader* CreateVertexShaderFromByteCode(const void* bytecode, unsigned int len);
|
||||||
|
ID3D11GeometryShader* CreateGeometryShaderFromByteCode(const void* bytecode, unsigned int len);
|
||||||
|
ID3D11PixelShader* CreatePixelShaderFromByteCode(const void* bytecode, unsigned int len);
|
||||||
|
|
||||||
// returns bytecode
|
// The returned bytecode buffers should be Release()d.
|
||||||
SharedPtr<ID3D10Blob> CompileVertexShader(const char* code, unsigned int len);
|
bool CompileVertexShader(const char* code, unsigned int len,
|
||||||
SharedPtr<ID3D10Blob> CompileGeometryShader(const char* code, unsigned int len,
|
D3DBlob** blob);
|
||||||
const D3D_SHADER_MACRO* pDefines = NULL);
|
bool CompileGeometryShader(const char* code, unsigned int len,
|
||||||
SharedPtr<ID3D10Blob> CompilePixelShader(const char* code, unsigned int len,
|
D3DBlob** blob, const D3D_SHADER_MACRO* pDefines = NULL);
|
||||||
const D3D_SHADER_MACRO* pDefines = NULL);
|
bool CompilePixelShader(const char* code, unsigned int len,
|
||||||
|
D3DBlob** blob, const D3D_SHADER_MACRO* pDefines = NULL);
|
||||||
|
|
||||||
SharedPtr<ID3D11VertexShader> CreateVertexShaderFromByteCode(const void* bytecode, unsigned int len);
|
// Utility functions
|
||||||
SharedPtr<ID3D11GeometryShader> CreateGeometryShaderFromByteCode(const void* bytecode, unsigned int len);
|
ID3D11VertexShader* CompileAndCreateVertexShader(const char* code,
|
||||||
SharedPtr<ID3D11PixelShader> CreatePixelShaderFromByteCode(const void* bytecode, unsigned int len);
|
unsigned int len);
|
||||||
|
ID3D11GeometryShader* CompileAndCreateGeometryShader(const char* code,
|
||||||
|
unsigned int len, const D3D_SHADER_MACRO* pDefines = NULL);
|
||||||
|
ID3D11PixelShader* CompileAndCreatePixelShader(const char* code,
|
||||||
|
unsigned int len);
|
||||||
|
|
||||||
inline SharedPtr<ID3D11VertexShader> CreateVertexShaderFromByteCode(SharedPtr<ID3D10Blob> bytecode)
|
inline ID3D11VertexShader* CreateVertexShaderFromByteCode(D3DBlob* bytecode)
|
||||||
{
|
{ return CreateVertexShaderFromByteCode(bytecode->Data(), bytecode->Size()); }
|
||||||
return CreateVertexShaderFromByteCode(bytecode->GetBufferPointer(), (unsigned int)bytecode->GetBufferSize());
|
inline ID3D11GeometryShader* CreateGeometryShaderFromByteCode(D3DBlob* bytecode)
|
||||||
}
|
{ return CreateGeometryShaderFromByteCode(bytecode->Data(), bytecode->Size()); }
|
||||||
|
inline ID3D11PixelShader* CreatePixelShaderFromByteCode(D3DBlob* bytecode)
|
||||||
inline SharedPtr<ID3D11GeometryShader> CreateGeometryShaderFromByteCode(SharedPtr<ID3D10Blob> bytecode)
|
{ return CreatePixelShaderFromByteCode(bytecode->Data(), bytecode->Size()); }
|
||||||
{
|
|
||||||
return CreateGeometryShaderFromByteCode(bytecode->GetBufferPointer(), (unsigned int)bytecode->GetBufferSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline SharedPtr<ID3D11PixelShader> CreatePixelShaderFromByteCode(SharedPtr<ID3D10Blob> bytecode)
|
|
||||||
{
|
|
||||||
return CreatePixelShaderFromByteCode(bytecode->GetBufferPointer(), (unsigned int)bytecode->GetBufferSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utility functions, optionally return the bytecode if "bytecode" is non-null
|
|
||||||
SharedPtr<ID3D11VertexShader> CompileAndCreateVertexShader(const char* code, unsigned int len,
|
|
||||||
SharedPtr<ID3D10Blob>* bytecode = nullptr);
|
|
||||||
SharedPtr<ID3D11GeometryShader> CompileAndCreateGeometryShader(const char* code, unsigned int len,
|
|
||||||
const D3D_SHADER_MACRO* pDefines = nullptr, SharedPtr<ID3D10Blob>* bytecode = nullptr);
|
|
||||||
SharedPtr<ID3D11PixelShader> CompileAndCreatePixelShader(const char* code, unsigned int len,
|
|
||||||
const D3D_SHADER_MACRO* pDefines = nullptr, SharedPtr<ID3D10Blob>* bytecode = nullptr);
|
|
||||||
|
|
||||||
|
inline ID3D11VertexShader* CompileAndCreateVertexShader(D3DBlob* code)
|
||||||
|
{ return CompileAndCreateVertexShader((const char*)code->Data(), code->Size()); }
|
||||||
|
inline ID3D11GeometryShader* CompileAndCreateGeometryShader(D3DBlob* code, const D3D_SHADER_MACRO* pDefines = NULL)
|
||||||
|
{ return CompileAndCreateGeometryShader((const char*)code->Data(), code->Size(), pDefines); }
|
||||||
|
inline ID3D11PixelShader* CompileAndCreatePixelShader(D3DBlob* code)
|
||||||
|
{ return CompileAndCreatePixelShader((const char*)code->Data(), code->Size()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace DX11
|
} // namespace DX11
|
|
@ -29,7 +29,7 @@ void ReplaceRGBATexture2D(ID3D11Texture2D* pTexture, const u8* buffer, unsigned
|
||||||
if (usage == D3D11_USAGE_DYNAMIC || usage == D3D11_USAGE_STAGING)
|
if (usage == D3D11_USAGE_DYNAMIC || usage == D3D11_USAGE_STAGING)
|
||||||
{
|
{
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
D3D::g_context->Map(pTexture, level, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
D3D::context->Map(pTexture, level, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
if (4 * pitch == map.RowPitch)
|
if (4 * pitch == map.RowPitch)
|
||||||
{
|
{
|
||||||
memcpy(map.pData, buffer, map.RowPitch * height);
|
memcpy(map.pData, buffer, map.RowPitch * height);
|
||||||
|
@ -39,43 +39,63 @@ void ReplaceRGBATexture2D(ID3D11Texture2D* pTexture, const u8* buffer, unsigned
|
||||||
for (unsigned int y = 0; y < height; ++y)
|
for (unsigned int y = 0; y < height; ++y)
|
||||||
memcpy((u8*)map.pData + y * map.RowPitch, (u32*)buffer + y * pitch, 4 * pitch);
|
memcpy((u8*)map.pData + y * map.RowPitch, (u32*)buffer + y * pitch, 4 * pitch);
|
||||||
}
|
}
|
||||||
D3D::g_context->Unmap(pTexture, level);
|
D3D::context->Unmap(pTexture, level);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
D3D11_BOX dest_region = CD3D11_BOX(0, 0, 0, width, height, 1);
|
D3D11_BOX dest_region = CD3D11_BOX(0, 0, 0, width, height, 1);
|
||||||
D3D::g_context->UpdateSubresource(pTexture, level, &dest_region, buffer, 4*pitch, 4*pitch*height);
|
D3D::context->UpdateSubresource(pTexture, level, &dest_region, buffer, 4*pitch, 4*pitch*height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::unique_ptr<D3DTexture2D> D3DTexture2D::Create(unsigned int width, unsigned int height, D3D11_BIND_FLAG bind,
|
D3DTexture2D* D3DTexture2D::Create(unsigned int width, unsigned int height, D3D11_BIND_FLAG bind, D3D11_USAGE usage, DXGI_FORMAT fmt, unsigned int levels)
|
||||||
D3D11_USAGE usage, DXGI_FORMAT fmt, unsigned int levels)
|
|
||||||
{
|
{
|
||||||
|
ID3D11Texture2D* pTexture = NULL;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
D3D11_CPU_ACCESS_FLAG cpuflags;
|
D3D11_CPU_ACCESS_FLAG cpuflags;
|
||||||
if (usage == D3D11_USAGE_STAGING)
|
if (usage == D3D11_USAGE_STAGING) cpuflags = (D3D11_CPU_ACCESS_FLAG)((int)D3D11_CPU_ACCESS_WRITE|(int)D3D11_CPU_ACCESS_READ);
|
||||||
cpuflags = (D3D11_CPU_ACCESS_FLAG)(D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ);
|
else if (usage == D3D11_USAGE_DYNAMIC) cpuflags = D3D11_CPU_ACCESS_WRITE;
|
||||||
else if (usage == D3D11_USAGE_DYNAMIC)
|
else cpuflags = (D3D11_CPU_ACCESS_FLAG)0;
|
||||||
cpuflags = D3D11_CPU_ACCESS_WRITE;
|
D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(fmt, width, height, 1, levels, bind, usage, cpuflags);
|
||||||
else
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &pTexture);
|
||||||
cpuflags = (D3D11_CPU_ACCESS_FLAG)0;
|
if (FAILED(hr))
|
||||||
|
|
||||||
const D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(fmt, width, height, 1, levels, bind, usage, cpuflags);
|
|
||||||
|
|
||||||
auto texture = CreateTexture2DShared(&texdesc, NULL);
|
|
||||||
if (!texture)
|
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to create texture at %s, line %d\n", __FILE__, __LINE__);
|
PanicAlert("Failed to create texture at %s, line %d: hr=%#x\n", __FILE__, __LINE__, hr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::unique_ptr<D3DTexture2D>(new D3DTexture2D(texture, bind));
|
D3DTexture2D* ret = new D3DTexture2D(pTexture, bind);
|
||||||
|
SAFE_RELEASE(pTexture);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DTexture2D::D3DTexture2D(SharedPtr<ID3D11Texture2D> texptr, D3D11_BIND_FLAG bind,
|
void D3DTexture2D::AddRef()
|
||||||
DXGI_FORMAT srv_format, DXGI_FORMAT dsv_format, DXGI_FORMAT rtv_format, bool multisampled)
|
{
|
||||||
: ref(1), tex(texptr), srv(NULL), rtv(NULL), dsv(NULL)
|
++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)
|
||||||
|
: ref(1), tex(texptr), srv(NULL), rtv(NULL), dsv(NULL)
|
||||||
{
|
{
|
||||||
D3D11_SRV_DIMENSION srv_dim = multisampled ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D;
|
D3D11_SRV_DIMENSION srv_dim = multisampled ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||||
D3D11_DSV_DIMENSION dsv_dim = multisampled ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;
|
D3D11_DSV_DIMENSION dsv_dim = multisampled ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;
|
||||||
|
@ -83,12 +103,10 @@ D3DTexture2D::D3DTexture2D(SharedPtr<ID3D11Texture2D> texptr, D3D11_BIND_FLAG bi
|
||||||
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = CD3D11_SHADER_RESOURCE_VIEW_DESC(srv_dim, srv_format);
|
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_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);
|
D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = CD3D11_RENDER_TARGET_VIEW_DESC(rtv_dim, rtv_format);
|
||||||
if (bind & D3D11_BIND_SHADER_RESOURCE)
|
if (bind & D3D11_BIND_SHADER_RESOURCE) D3D::device->CreateShaderResourceView(tex, &srv_desc, &srv);
|
||||||
D3D::g_device->CreateShaderResourceView(tex, &srv_desc, &srv);
|
if (bind & D3D11_BIND_RENDER_TARGET) D3D::device->CreateRenderTargetView(tex, &rtv_desc, &rtv);
|
||||||
if (bind & D3D11_BIND_RENDER_TARGET)
|
if (bind & D3D11_BIND_DEPTH_STENCIL) D3D::device->CreateDepthStencilView(tex, &dsv_desc, &dsv);
|
||||||
D3D::g_device->CreateRenderTargetView(tex, &rtv_desc, &rtv);
|
tex->AddRef();
|
||||||
if (bind & D3D11_BIND_DEPTH_STENCIL)
|
|
||||||
D3D::g_device->CreateDepthStencilView(tex, &dsv_desc, &dsv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DTexture2D::~D3DTexture2D()
|
D3DTexture2D::~D3DTexture2D()
|
||||||
|
@ -96,6 +114,7 @@ D3DTexture2D::~D3DTexture2D()
|
||||||
SAFE_RELEASE(srv);
|
SAFE_RELEASE(srv);
|
||||||
SAFE_RELEASE(rtv);
|
SAFE_RELEASE(rtv);
|
||||||
SAFE_RELEASE(dsv);
|
SAFE_RELEASE(dsv);
|
||||||
|
SAFE_RELEASE(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace DX11
|
} // namespace DX11
|
|
@ -34,22 +34,22 @@ public:
|
||||||
// either create an ID3D11Texture2D object, pass it to the constructor and specify what views to create
|
// either create an ID3D11Texture2D object, pass it to the constructor and specify what views to create
|
||||||
// or let the texture automatically be created by D3DTexture2D::Create
|
// or let the texture automatically be created by D3DTexture2D::Create
|
||||||
|
|
||||||
D3DTexture2D(SharedPtr<ID3D11Texture2D> texptr, D3D11_BIND_FLAG bind,
|
D3DTexture2D(ID3D11Texture2D* texptr, D3D11_BIND_FLAG bind, DXGI_FORMAT srv_format = DXGI_FORMAT_UNKNOWN, DXGI_FORMAT dsv_format = DXGI_FORMAT_UNKNOWN, DXGI_FORMAT rtv_format = DXGI_FORMAT_UNKNOWN, bool multisampled = false);
|
||||||
DXGI_FORMAT srv_format = DXGI_FORMAT_UNKNOWN, DXGI_FORMAT dsv_format = DXGI_FORMAT_UNKNOWN,
|
static D3DTexture2D* Create(unsigned int width, unsigned int height, D3D11_BIND_FLAG bind, D3D11_USAGE usage, DXGI_FORMAT, unsigned int levels = 1);
|
||||||
DXGI_FORMAT rtv_format = DXGI_FORMAT_UNKNOWN, bool multisampled = false);
|
|
||||||
|
|
||||||
static std::unique_ptr<D3DTexture2D> Create(unsigned int width, unsigned int height,
|
// reference counting, use AddRef() when creating a new reference and Release() it when you don't need it anymore
|
||||||
D3D11_BIND_FLAG bind, D3D11_USAGE usage, DXGI_FORMAT, unsigned int levels = 1);
|
void AddRef();
|
||||||
|
UINT Release();
|
||||||
|
|
||||||
ID3D11Texture2D* GetTex() { return tex; }
|
ID3D11Texture2D* &GetTex();
|
||||||
ID3D11ShaderResourceView*const& GetSRV() { return srv; }
|
ID3D11ShaderResourceView* &GetSRV();
|
||||||
ID3D11RenderTargetView*const& GetRTV() { return rtv; }
|
ID3D11RenderTargetView* &GetRTV();
|
||||||
ID3D11DepthStencilView*const& GetDSV() { return dsv; }
|
ID3D11DepthStencilView* &GetDSV();
|
||||||
|
|
||||||
~D3DTexture2D();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SharedPtr<ID3D11Texture2D> tex;
|
~D3DTexture2D();
|
||||||
|
|
||||||
|
ID3D11Texture2D* tex;
|
||||||
ID3D11ShaderResourceView* srv;
|
ID3D11ShaderResourceView* srv;
|
||||||
ID3D11RenderTargetView* rtv;
|
ID3D11RenderTargetView* rtv;
|
||||||
ID3D11DepthStencilView* dsv;
|
ID3D11DepthStencilView* dsv;
|
||||||
|
|
|
@ -34,35 +34,36 @@ namespace D3D
|
||||||
class UtilVertexBuffer
|
class UtilVertexBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UtilVertexBuffer(UINT size)
|
UtilVertexBuffer(int size) : buf(NULL), offset(0), max_size(size)
|
||||||
: offset(0), max_size(size)
|
|
||||||
{
|
{
|
||||||
D3D11_BUFFER_DESC desc = CD3D11_BUFFER_DESC(max_size, D3D11_BIND_VERTEX_BUFFER,
|
D3D11_BUFFER_DESC desc = CD3D11_BUFFER_DESC(max_size, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||||
D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
device->CreateBuffer(&desc, NULL, &buf);
|
||||||
m_buf = CreateBufferShared(&desc, NULL);
|
}
|
||||||
|
~UtilVertexBuffer()
|
||||||
|
{
|
||||||
|
buf->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns vertex offset to the new data
|
// returns vertex offset to the new data
|
||||||
int AppendData(void* data, UINT size, UINT vertex_size)
|
int AppendData(void* data, int size, int vertex_size)
|
||||||
{
|
{
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
if (offset + size >= max_size)
|
if(offset + size >= max_size)
|
||||||
{
|
{
|
||||||
// wrap buffer around and notify observers
|
// wrap buffer around and notify observers
|
||||||
offset = 0;
|
offset = 0;
|
||||||
g_context->Map(m_buf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
context->Map(buf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
|
|
||||||
for each (auto obs in observers)
|
for(std::list<bool*>::iterator it = observers.begin(); it != observers.end(); ++it)
|
||||||
*obs = true;
|
**it = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_context->Map(m_buf, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map);
|
context->Map(buf, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map);
|
||||||
}
|
}
|
||||||
|
offset = ((offset+vertex_size-1)/vertex_size)*vertex_size; // align offset to vertex_size bytes
|
||||||
offset = ((offset+vertex_size - 1) / vertex_size) * vertex_size; // align offset to vertex_size bytes
|
|
||||||
memcpy((u8*)map.pData + offset, data, size);
|
memcpy((u8*)map.pData + offset, data, size);
|
||||||
g_context->Unmap(m_buf, 0);
|
context->Unmap(buf, 0);
|
||||||
|
|
||||||
offset += size;
|
offset += size;
|
||||||
return (offset - size) / vertex_size;
|
return (offset - size) / vertex_size;
|
||||||
|
@ -73,18 +74,18 @@ public:
|
||||||
observers.push_back(observer);
|
observers.push_back(observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11Buffer*const& GetBuffer() { return m_buf; }
|
inline ID3D11Buffer* &GetBuffer() { return buf; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SharedPtr<ID3D11Buffer> m_buf;
|
ID3D11Buffer* buf;
|
||||||
UINT offset;
|
int offset;
|
||||||
UINT max_size;
|
int max_size;
|
||||||
|
|
||||||
std::list<bool*> observers;
|
std::list<bool*> observers;
|
||||||
};
|
};
|
||||||
|
|
||||||
CD3DFont font;
|
CD3DFont font;
|
||||||
std::unique_ptr<UtilVertexBuffer> util_vbuf;
|
UtilVertexBuffer* util_vbuf = NULL;
|
||||||
|
|
||||||
#define MAX_NUM_VERTICES 50*6
|
#define MAX_NUM_VERTICES 50*6
|
||||||
struct FONT2DVERTEX {
|
struct FONT2DVERTEX {
|
||||||
|
@ -103,10 +104,13 @@ inline FONT2DVERTEX InitFont2DVertex(float x, float y, u32 color, float tu, floa
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
CD3DFont::CD3DFont()
|
CD3DFont::CD3DFont() : m_dwTexWidth(512), m_dwTexHeight(512)
|
||||||
: m_dwTexWidth(512), m_dwTexHeight(512)
|
|
||||||
{
|
{
|
||||||
m_pTexture = NULL;
|
m_pTexture = NULL;
|
||||||
|
m_pVB = NULL;
|
||||||
|
m_InputLayout = NULL;
|
||||||
|
m_pshader = NULL;
|
||||||
|
m_vshader = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char fontpixshader[] = {
|
const char fontpixshader[] = {
|
||||||
|
@ -220,20 +224,21 @@ int CD3DFont::Init()
|
||||||
// Create a new texture for the font
|
// Create a new texture for the font
|
||||||
// possible optimization: store the converted data in a buffer and fill the texture on creation.
|
// possible optimization: store the converted data in a buffer and fill the texture on creation.
|
||||||
// That way, we can use a static texture
|
// That way, we can use a static texture
|
||||||
|
ID3D11Texture2D* buftex;
|
||||||
D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, m_dwTexWidth, m_dwTexHeight,
|
D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, m_dwTexWidth, m_dwTexHeight,
|
||||||
1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DYNAMIC,
|
||||||
|
D3D11_CPU_ACCESS_WRITE);
|
||||||
auto buftex = CreateTexture2DShared(&texdesc, NULL);
|
hr = device->CreateTexture2D(&texdesc, NULL, &buftex);
|
||||||
if (!buftex)
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to create font texture");
|
PanicAlert("Failed to create font texture");
|
||||||
return S_FALSE;
|
return hr;
|
||||||
}
|
}
|
||||||
D3D::SetDebugObjectName(buftex, "texture of a CD3DFont object");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)buftex, "texture of a CD3DFont object");
|
||||||
|
|
||||||
// Lock the surface and write the alpha values for the set pixels
|
// Lock the surface and write the alpha values for the set pixels
|
||||||
D3D11_MAPPED_SUBRESOURCE texmap;
|
D3D11_MAPPED_SUBRESOURCE texmap;
|
||||||
hr = g_context->Map(buftex, 0, D3D11_MAP_WRITE_DISCARD, 0, &texmap);
|
hr = context->Map(buftex, 0, D3D11_MAP_WRITE_DISCARD, 0, &texmap);
|
||||||
if (FAILED(hr)) PanicAlert("Failed to map a texture at %s %d\n", __FILE__, __LINE__);
|
if (FAILED(hr)) PanicAlert("Failed to map a texture at %s %d\n", __FILE__, __LINE__);
|
||||||
|
|
||||||
for (y = 0; y < m_dwTexHeight; y++)
|
for (y = 0; y < m_dwTexHeight; y++)
|
||||||
|
@ -247,12 +252,10 @@ int CD3DFont::Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done updating texture, so clean up used objects
|
// Done updating texture, so clean up used objects
|
||||||
g_context->Unmap(buftex, 0);
|
context->Unmap(buftex, 0);
|
||||||
hr = D3D::g_device->CreateShaderResourceView(buftex, NULL, &m_pTexture);
|
hr = D3D::device->CreateShaderResourceView(buftex, NULL, &m_pTexture);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr)) PanicAlert("Failed to create shader resource view at %s %d\n", __FILE__, __LINE__);
|
||||||
PanicAlert("Failed to create shader resource view at %s %d\n", __FILE__, __LINE__);
|
SAFE_RELEASE(buftex);
|
||||||
|
|
||||||
buftex.reset();
|
|
||||||
|
|
||||||
SelectObject(hDC, hOldbmBitmap);
|
SelectObject(hDC, hOldbmBitmap);
|
||||||
DeleteObject(hbmBitmap);
|
DeleteObject(hbmBitmap);
|
||||||
|
@ -262,16 +265,15 @@ int CD3DFont::Init()
|
||||||
|
|
||||||
// setup device objects for drawing
|
// setup device objects for drawing
|
||||||
m_pshader = D3D::CompileAndCreatePixelShader(fontpixshader, sizeof(fontpixshader));
|
m_pshader = D3D::CompileAndCreatePixelShader(fontpixshader, sizeof(fontpixshader));
|
||||||
if (!m_pshader)
|
if (m_pshader == NULL) PanicAlert("Failed to create pixel shader, %s %d\n", __FILE__, __LINE__);
|
||||||
PanicAlert("Failed to create pixel shader, %s %d\n", __FILE__, __LINE__);
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_pshader, "pixel shader of a CD3DFont object");
|
||||||
D3D::SetDebugObjectName(m_pshader, "pixel shader of a CD3DFont object");
|
|
||||||
|
|
||||||
SharedPtr<ID3D10Blob> vsbytecode;
|
D3DBlob* vsbytecode;
|
||||||
m_vshader = D3D::CompileAndCreateVertexShader(fontvertshader, sizeof(fontvertshader), std::addressof(vsbytecode));
|
D3D::CompileVertexShader(fontvertshader, sizeof(fontvertshader), &vsbytecode);
|
||||||
|
if (vsbytecode == NULL) PanicAlert("Failed to compile vertex shader, %s %d\n", __FILE__, __LINE__);
|
||||||
if (!m_vshader)
|
m_vshader = D3D::CreateVertexShaderFromByteCode(vsbytecode);
|
||||||
PanicAlert("Failed to compile/create vertex shader, %s %d\n", __FILE__, __LINE__);
|
if (m_vshader == NULL) PanicAlert("Failed to create vertex shader, %s %d\n", __FILE__, __LINE__);
|
||||||
D3D::SetDebugObjectName(m_vshader, "vertex shader of a CD3DFont object");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_vshader, "vertex shader of a CD3DFont object");
|
||||||
|
|
||||||
const D3D11_INPUT_ELEMENT_DESC desc[] =
|
const D3D11_INPUT_ELEMENT_DESC desc[] =
|
||||||
{
|
{
|
||||||
|
@ -279,11 +281,9 @@ int CD3DFont::Init()
|
||||||
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
};
|
};
|
||||||
|
hr = D3D::device->CreateInputLayout(desc, 3, vsbytecode->Data(), vsbytecode->Size(), &m_InputLayout);
|
||||||
m_InputLayout = CreateInputLayoutShared(desc, 3, vsbytecode->GetBufferPointer(),
|
if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__);
|
||||||
vsbytecode->GetBufferSize());
|
SAFE_RELEASE(vsbytecode);
|
||||||
if (!m_InputLayout)
|
|
||||||
PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__);
|
|
||||||
|
|
||||||
D3D11_BLEND_DESC blenddesc;
|
D3D11_BLEND_DESC blenddesc;
|
||||||
blenddesc.AlphaToCoverageEnable = FALSE;
|
blenddesc.AlphaToCoverageEnable = FALSE;
|
||||||
|
@ -296,37 +296,34 @@ int CD3DFont::Init()
|
||||||
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
||||||
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||||
blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||||
m_blendstate = CreateBlendStateShared(&blenddesc);
|
hr = D3D::device->CreateBlendState(&blenddesc, &m_blendstate);
|
||||||
CHECK(m_blendstate, "Create font blend state");
|
CHECK(hr==S_OK, "Create font blend state");
|
||||||
D3D::SetDebugObjectName(m_blendstate, "blend state of a CD3DFont object");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_blendstate, "blend state of a CD3DFont object");
|
||||||
|
|
||||||
D3D11_RASTERIZER_DESC rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE,
|
D3D11_RASTERIZER_DESC rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0.f, false, false, false, false);
|
||||||
false, 0, 0.f, 0.f, false, false, false, false);
|
hr = D3D::device->CreateRasterizerState(&rastdesc, &m_raststate);
|
||||||
hr = D3D::g_device->CreateRasterizerState(&rastdesc, &m_raststate);
|
|
||||||
CHECK(hr==S_OK, "Create font rasterizer state");
|
CHECK(hr==S_OK, "Create font rasterizer state");
|
||||||
D3D::SetDebugObjectName(m_raststate, "rasterizer state of a CD3DFont object");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_raststate, "rasterizer state of a CD3DFont object");
|
||||||
|
|
||||||
D3D11_BUFFER_DESC vbdesc = CD3D11_BUFFER_DESC(MAX_NUM_VERTICES * sizeof(FONT2DVERTEX),
|
D3D11_BUFFER_DESC vbdesc = CD3D11_BUFFER_DESC(MAX_NUM_VERTICES*sizeof(FONT2DVERTEX), D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||||
D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
if (FAILED(hr = device->CreateBuffer(&vbdesc, NULL, &m_pVB)))
|
||||||
m_pVB = CreateBufferShared(&vbdesc, NULL);
|
|
||||||
if (!m_pVB)
|
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to create font vertex buffer at %s, line %d\n", __FILE__, __LINE__);
|
PanicAlert("Failed to create font vertex buffer at %s, line %d\n", __FILE__, __LINE__);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
D3D::SetDebugObjectName(m_pVB, "vertex buffer of a CD3DFont object");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_pVB, "vertex buffer of a CD3DFont object");
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CD3DFont::Shutdown()
|
int CD3DFont::Shutdown()
|
||||||
{
|
{
|
||||||
m_pVB.reset();
|
SAFE_RELEASE(m_pVB);
|
||||||
SAFE_RELEASE(m_pTexture);
|
SAFE_RELEASE(m_pTexture);
|
||||||
m_InputLayout.reset();
|
SAFE_RELEASE(m_InputLayout);
|
||||||
m_pshader.reset();
|
SAFE_RELEASE(m_pshader);
|
||||||
m_vshader.reset();
|
SAFE_RELEASE(m_vshader);
|
||||||
|
|
||||||
m_blendstate.reset();
|
SAFE_RELEASE(m_blendstate);
|
||||||
SAFE_RELEASE(m_raststate);
|
SAFE_RELEASE(m_raststate);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -354,7 +351,7 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
|
||||||
int dwNumTriangles = 0L;
|
int dwNumTriangles = 0L;
|
||||||
|
|
||||||
D3D11_MAPPED_SUBRESOURCE vbmap;
|
D3D11_MAPPED_SUBRESOURCE vbmap;
|
||||||
HRESULT hr = g_context->Map(m_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vbmap);
|
HRESULT hr = context->Map(m_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vbmap);
|
||||||
if (FAILED(hr)) PanicAlert("Mapping vertex buffer failed, %s %d\n", __FILE__, __LINE__);
|
if (FAILED(hr)) PanicAlert("Mapping vertex buffer failed, %s %d\n", __FILE__, __LINE__);
|
||||||
pVertices = (D3D::FONT2DVERTEX*)vbmap.pData;
|
pVertices = (D3D::FONT2DVERTEX*)vbmap.pData;
|
||||||
|
|
||||||
|
@ -363,12 +360,12 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
|
||||||
D3D::stateman->PushRasterizerState(m_raststate);
|
D3D::stateman->PushRasterizerState(m_raststate);
|
||||||
D3D::stateman->Apply();
|
D3D::stateman->Apply();
|
||||||
|
|
||||||
D3D::g_context->PSSetShader(m_pshader, NULL, 0);
|
D3D::context->PSSetShader(m_pshader, NULL, 0);
|
||||||
D3D::g_context->VSSetShader(m_vshader, NULL, 0);
|
D3D::context->VSSetShader(m_vshader, NULL, 0);
|
||||||
|
|
||||||
D3D::g_context->IASetInputLayout(m_InputLayout);
|
D3D::context->IASetInputLayout(m_InputLayout);
|
||||||
D3D::g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
D3D::g_context->PSSetShaderResources(0, 1, &m_pTexture);
|
D3D::context->PSSetShaderResources(0, 1, &m_pTexture);
|
||||||
|
|
||||||
float fStartX = sx;
|
float fStartX = sx;
|
||||||
while (c = *strText++)
|
while (c = *strText++)
|
||||||
|
@ -405,14 +402,14 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
|
||||||
|
|
||||||
if (dwNumTriangles * 3 > (MAX_NUM_VERTICES - 6))
|
if (dwNumTriangles * 3 > (MAX_NUM_VERTICES - 6))
|
||||||
{
|
{
|
||||||
g_context->Unmap(m_pVB, 0);
|
context->Unmap(m_pVB, 0);
|
||||||
|
|
||||||
D3D::g_context->IASetVertexBuffers(0, 1, &m_pVB, &stride, &bufoffset);
|
D3D::context->IASetVertexBuffers(0, 1, &m_pVB, &stride, &bufoffset);
|
||||||
D3D::g_context->Draw(3 * dwNumTriangles, 0);
|
D3D::context->Draw(3 * dwNumTriangles, 0);
|
||||||
|
|
||||||
dwNumTriangles = 0;
|
dwNumTriangles = 0;
|
||||||
D3D11_MAPPED_SUBRESOURCE vbmap;
|
D3D11_MAPPED_SUBRESOURCE vbmap;
|
||||||
hr = g_context->Map(m_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vbmap);
|
hr = context->Map(m_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vbmap);
|
||||||
if (FAILED(hr)) PanicAlert("Mapping vertex buffer failed, %s %d\n", __FILE__, __LINE__);
|
if (FAILED(hr)) PanicAlert("Mapping vertex buffer failed, %s %d\n", __FILE__, __LINE__);
|
||||||
pVertices = (D3D::FONT2DVERTEX*)vbmap.pData;
|
pVertices = (D3D::FONT2DVERTEX*)vbmap.pData;
|
||||||
}
|
}
|
||||||
|
@ -420,11 +417,11 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlock and render the vertex buffer
|
// Unlock and render the vertex buffer
|
||||||
g_context->Unmap(m_pVB, 0);
|
context->Unmap(m_pVB, 0);
|
||||||
if (dwNumTriangles > 0)
|
if (dwNumTriangles > 0)
|
||||||
{
|
{
|
||||||
D3D::g_context->IASetVertexBuffers(0, 1, &m_pVB, &stride, &bufoffset);
|
D3D::context->IASetVertexBuffers(0, 1, &m_pVB, &stride, &bufoffset);
|
||||||
D3D::g_context->Draw(3 * dwNumTriangles, 0);
|
D3D::context->Draw(3 * dwNumTriangles, 0);
|
||||||
}
|
}
|
||||||
D3D::stateman->PopBlendState();
|
D3D::stateman->PopBlendState();
|
||||||
D3D::stateman->PopRasterizerState();
|
D3D::stateman->PopRasterizerState();
|
||||||
|
@ -470,25 +467,18 @@ bool stq_observer, stsq_observer, cq_observer, clearq_observer;
|
||||||
|
|
||||||
void InitUtils()
|
void InitUtils()
|
||||||
{
|
{
|
||||||
util_vbuf.reset(new UtilVertexBuffer(0x4000));
|
util_vbuf = new UtilVertexBuffer(0x4000);
|
||||||
|
|
||||||
const float border[4] = { 0.f, 0.f, 0.f, 0.f };
|
float border[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||||
D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_POINT,
|
D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
|
||||||
D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER,
|
HRESULT hr = D3D::device->CreateSamplerState(&samDesc, &point_copy_sampler);
|
||||||
0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
|
if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
|
||||||
HRESULT hr = D3D::g_device->CreateSamplerState(&samDesc, &point_copy_sampler);
|
else SetDebugObjectName((ID3D11DeviceChild*)point_copy_sampler, "point copy sampler state");
|
||||||
if (FAILED(hr))
|
|
||||||
PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
|
|
||||||
else
|
|
||||||
SetDebugObjectName(point_copy_sampler, "point copy sampler state");
|
|
||||||
|
|
||||||
samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_BORDER,
|
samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
|
||||||
D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
|
hr = D3D::device->CreateSamplerState(&samDesc, &linear_copy_sampler);
|
||||||
hr = D3D::g_device->CreateSamplerState(&samDesc, &linear_copy_sampler);
|
if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
|
||||||
if (FAILED(hr))
|
else SetDebugObjectName((ID3D11DeviceChild*)linear_copy_sampler, "linear copy sampler state");
|
||||||
PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
|
|
||||||
else
|
|
||||||
SetDebugObjectName(linear_copy_sampler, "linear copy sampler state");
|
|
||||||
|
|
||||||
// cached data used to avoid unnecessarily reloading the vertex buffers
|
// cached data used to avoid unnecessarily reloading the vertex buffers
|
||||||
memset(&tex_quad_data, 0, sizeof(tex_quad_data));
|
memset(&tex_quad_data, 0, sizeof(tex_quad_data));
|
||||||
|
@ -511,17 +501,17 @@ void ShutdownUtils()
|
||||||
font.Shutdown();
|
font.Shutdown();
|
||||||
SAFE_RELEASE(point_copy_sampler);
|
SAFE_RELEASE(point_copy_sampler);
|
||||||
SAFE_RELEASE(linear_copy_sampler);
|
SAFE_RELEASE(linear_copy_sampler);
|
||||||
util_vbuf.reset();
|
SAFE_DELETE(util_vbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPointCopySampler()
|
void SetPointCopySampler()
|
||||||
{
|
{
|
||||||
D3D::g_context->PSSetSamplers(0, 1, &point_copy_sampler);
|
D3D::context->PSSetSamplers(0, 1, &point_copy_sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetLinearCopySampler()
|
void SetLinearCopySampler()
|
||||||
{
|
{
|
||||||
D3D::g_context->PSSetSamplers(0, 1, &linear_copy_sampler);
|
D3D::context->PSSetSamplers(0, 1, &linear_copy_sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
|
void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
|
||||||
|
@ -565,17 +555,17 @@ void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
|
||||||
UINT stride = sizeof(STQVertex);
|
UINT stride = sizeof(STQVertex);
|
||||||
UINT offset = 0;
|
UINT offset = 0;
|
||||||
|
|
||||||
D3D::g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||||
D3D::g_context->IASetInputLayout(layout);
|
D3D::context->IASetInputLayout(layout);
|
||||||
D3D::g_context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset);
|
D3D::context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset);
|
||||||
D3D::g_context->PSSetShader(PShader, NULL, 0);
|
D3D::context->PSSetShader(PShader, NULL, 0);
|
||||||
D3D::g_context->PSSetShaderResources(0, 1, &texture);
|
D3D::context->PSSetShaderResources(0, 1, &texture);
|
||||||
D3D::g_context->VSSetShader(Vshader, NULL, 0);
|
D3D::context->VSSetShader(Vshader, NULL, 0);
|
||||||
D3D::stateman->Apply();
|
D3D::stateman->Apply();
|
||||||
D3D::g_context->Draw(4, stq_offset);
|
D3D::context->Draw(4, stq_offset);
|
||||||
|
|
||||||
ID3D11ShaderResourceView* texres = NULL;
|
ID3D11ShaderResourceView* texres = NULL;
|
||||||
g_context->PSSetShaderResources(0, 1, &texres); // immediately unbind the texture
|
context->PSSetShaderResources(0, 1, &texres); // immediately unbind the texture
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
|
void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
|
||||||
|
@ -622,17 +612,17 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
|
||||||
UINT stride = sizeof(STSQVertex);
|
UINT stride = sizeof(STSQVertex);
|
||||||
UINT offset = 0;
|
UINT offset = 0;
|
||||||
|
|
||||||
g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||||
g_context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset);
|
context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset);
|
||||||
g_context->IASetInputLayout(layout);
|
context->IASetInputLayout(layout);
|
||||||
g_context->PSSetShaderResources(0, 1, &texture);
|
context->PSSetShaderResources(0, 1, &texture);
|
||||||
g_context->PSSetShader(PShader, NULL, 0);
|
context->PSSetShader(PShader, NULL, 0);
|
||||||
g_context->VSSetShader(Vshader, NULL, 0);
|
context->VSSetShader(Vshader, NULL, 0);
|
||||||
stateman->Apply();
|
stateman->Apply();
|
||||||
g_context->Draw(4, stsq_offset);
|
context->Draw(4, stsq_offset);
|
||||||
|
|
||||||
ID3D11ShaderResourceView* texres = NULL;
|
ID3D11ShaderResourceView* texres = NULL;
|
||||||
g_context->PSSetShaderResources(0, 1, &texres); // immediately unbind the texture
|
context->PSSetShaderResources(0, 1, &texres); // immediately unbind the texture
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fills a certain area of the current render target with the specified color
|
// Fills a certain area of the current render target with the specified color
|
||||||
|
@ -661,17 +651,17 @@ void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2)
|
||||||
draw_quad_data.col = Color;
|
draw_quad_data.col = Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_context->VSSetShader(VertexShaderCache::GetClearVertexShader(), NULL, 0);
|
context->VSSetShader(VertexShaderCache::GetClearVertexShader(), NULL, 0);
|
||||||
g_context->PSSetShader(PixelShaderCache::GetClearProgram(), NULL, 0);
|
context->PSSetShader(PixelShaderCache::GetClearProgram(), NULL, 0);
|
||||||
g_context->IASetInputLayout(VertexShaderCache::GetClearInputLayout());
|
context->IASetInputLayout(VertexShaderCache::GetClearInputLayout());
|
||||||
|
|
||||||
UINT stride = sizeof(ColVertex);
|
UINT stride = sizeof(ColVertex);
|
||||||
UINT offset = 0;
|
UINT offset = 0;
|
||||||
g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||||
g_context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset);
|
context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset);
|
||||||
|
|
||||||
stateman->Apply();
|
stateman->Apply();
|
||||||
g_context->Draw(4, cq_offset);
|
context->Draw(4, cq_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout)
|
void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout)
|
||||||
|
@ -691,16 +681,16 @@ void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexS
|
||||||
clear_quad_data.col = Color;
|
clear_quad_data.col = Color;
|
||||||
clear_quad_data.z = z;
|
clear_quad_data.z = z;
|
||||||
}
|
}
|
||||||
g_context->VSSetShader(Vshader, NULL, 0);
|
context->VSSetShader(Vshader, NULL, 0);
|
||||||
g_context->PSSetShader(PShader, NULL, 0);
|
context->PSSetShader(PShader, NULL, 0);
|
||||||
g_context->IASetInputLayout(layout);
|
context->IASetInputLayout(layout);
|
||||||
|
|
||||||
UINT stride = sizeof(ClearVertex);
|
UINT stride = sizeof(ClearVertex);
|
||||||
UINT offset = 0;
|
UINT offset = 0;
|
||||||
g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||||
g_context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset);
|
context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset);
|
||||||
stateman->Apply();
|
stateman->Apply();
|
||||||
g_context->Draw(4, clearq_offset);
|
context->Draw(4, clearq_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace D3D
|
} // namespace D3D
|
||||||
|
|
|
@ -23,150 +23,68 @@
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
// simple "smart" pointer which calls AddRef/Release as needed
|
|
||||||
template <typename T>
|
|
||||||
class SharedPtr
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef T* pointer;
|
|
||||||
|
|
||||||
static SharedPtr FromPtr(pointer ptr)
|
|
||||||
{
|
|
||||||
return SharedPtr(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedPtr()
|
|
||||||
: data(nullptr)
|
|
||||||
{}
|
|
||||||
|
|
||||||
SharedPtr(const SharedPtr& other)
|
|
||||||
: data(NULL)
|
|
||||||
{
|
|
||||||
*this = other;
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedPtr& operator=(const SharedPtr& other)
|
|
||||||
{
|
|
||||||
if (other.data)
|
|
||||||
other.data->AddRef();
|
|
||||||
|
|
||||||
reset();
|
|
||||||
data = other.data;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~SharedPtr()
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset()
|
|
||||||
{
|
|
||||||
if (data)
|
|
||||||
data->Release();
|
|
||||||
|
|
||||||
data = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// returning reference for dx functions needing pointer to pointer
|
|
||||||
operator pointer const&() const
|
|
||||||
{
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator*() const
|
|
||||||
{
|
|
||||||
return *data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// overloading operator& for dx functions needing pointer to pointer
|
|
||||||
T*const* operator&() const
|
|
||||||
{
|
|
||||||
return &data;
|
|
||||||
}
|
|
||||||
|
|
||||||
pointer operator->() const
|
|
||||||
{
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const SharedPtr& other) const
|
|
||||||
{
|
|
||||||
return data == other.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const SharedPtr& other) const
|
|
||||||
{
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit SharedPtr(pointer ptr)
|
|
||||||
: data(ptr)
|
|
||||||
{}
|
|
||||||
|
|
||||||
pointer data;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
// Font creation flags
|
||||||
|
#define D3DFONT_BOLD 0x0001
|
||||||
|
#define D3DFONT_ITALIC 0x0002
|
||||||
|
|
||||||
// Font creation flags
|
// Font rendering flags
|
||||||
static const u32 D3DFONT_BOLD = 0x0001;
|
#define D3DFONT_CENTERED 0x0001
|
||||||
static const u32 D3DFONT_ITALIC = 0x0002;
|
|
||||||
|
|
||||||
// Font rendering flags
|
class CD3DFont
|
||||||
static const u32 D3DFONT_CENTERED = 0x0001;
|
{
|
||||||
|
ID3D11ShaderResourceView* m_pTexture;
|
||||||
|
ID3D11Buffer* m_pVB;
|
||||||
|
ID3D11InputLayout* m_InputLayout;
|
||||||
|
ID3D11PixelShader* m_pshader;
|
||||||
|
ID3D11VertexShader* m_vshader;
|
||||||
|
ID3D11BlendState* m_blendstate;
|
||||||
|
ID3D11RasterizerState* m_raststate;
|
||||||
|
const int m_dwTexWidth;
|
||||||
|
const int m_dwTexHeight;
|
||||||
|
unsigned int m_LineHeight;
|
||||||
|
float m_fTexCoords[128-32][4];
|
||||||
|
|
||||||
class CD3DFont
|
public:
|
||||||
{
|
CD3DFont();
|
||||||
ID3D11ShaderResourceView* m_pTexture;
|
// 2D text drawing function
|
||||||
SharedPtr<ID3D11Buffer> m_pVB;
|
// Initializing and destroying device-dependent objects
|
||||||
SharedPtr<ID3D11InputLayout> m_InputLayout;
|
int Init();
|
||||||
SharedPtr<ID3D11PixelShader> m_pshader;
|
int Shutdown();
|
||||||
SharedPtr<ID3D11VertexShader> m_vshader;
|
int DrawTextScaled(float x, float y,
|
||||||
SharedPtr<ID3D11BlendState> m_blendstate;
|
float size,
|
||||||
ID3D11RasterizerState* m_raststate;
|
float spacing, u32 dwColor,
|
||||||
const int m_dwTexWidth;
|
const char* strText);
|
||||||
const int m_dwTexHeight;
|
};
|
||||||
unsigned int m_LineHeight;
|
|
||||||
float m_fTexCoords[128-32][4];
|
|
||||||
|
|
||||||
public:
|
extern CD3DFont font;
|
||||||
CD3DFont();
|
|
||||||
// 2D text drawing function
|
|
||||||
// Initializing and destroying device-dependent objects
|
|
||||||
int Init();
|
|
||||||
int Shutdown();
|
|
||||||
int DrawTextScaled(float x, float y, float size,
|
|
||||||
float spacing, u32 dwColor, const char* strText);
|
|
||||||
};
|
|
||||||
|
|
||||||
extern CD3DFont font;
|
void InitUtils();
|
||||||
|
void ShutdownUtils();
|
||||||
|
|
||||||
void InitUtils();
|
void SetPointCopySampler();
|
||||||
void ShutdownUtils();
|
void SetLinearCopySampler();
|
||||||
|
|
||||||
void SetPointCopySampler();
|
|
||||||
void SetLinearCopySampler();
|
|
||||||
|
|
||||||
void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
|
|
||||||
const D3D11_RECT* rSource,
|
|
||||||
int SourceWidth, int SourceHeight,
|
|
||||||
ID3D11PixelShader* PShader, ID3D11VertexShader* VShader,
|
|
||||||
ID3D11InputLayout* layout, float Gamma = 1.0f);
|
|
||||||
|
|
||||||
void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
|
|
||||||
const MathUtil::Rectangle<float>* rSource,
|
|
||||||
int SourceWidth, int SourceHeight,
|
|
||||||
const MathUtil::Rectangle<float>* rDest,
|
|
||||||
ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader,
|
|
||||||
ID3D11InputLayout* layout, float Gamma = 1.0f);
|
|
||||||
|
|
||||||
void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout);
|
|
||||||
void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2);
|
|
||||||
|
|
||||||
|
void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
|
||||||
|
const D3D11_RECT* rSource,
|
||||||
|
int SourceWidth,
|
||||||
|
int SourceHeight,
|
||||||
|
ID3D11PixelShader* PShader,
|
||||||
|
ID3D11VertexShader* VShader,
|
||||||
|
ID3D11InputLayout* layout,
|
||||||
|
float Gamma = 1.0f);
|
||||||
|
void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
|
||||||
|
const MathUtil::Rectangle<float>* rSource,
|
||||||
|
int SourceWidth,
|
||||||
|
int SourceHeight,
|
||||||
|
const MathUtil::Rectangle<float>* rDest,
|
||||||
|
ID3D11PixelShader* PShader,
|
||||||
|
ID3D11VertexShader* Vshader,
|
||||||
|
ID3D11InputLayout* layout,
|
||||||
|
float Gamma = 1.0f);
|
||||||
|
void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout);
|
||||||
|
void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -23,155 +23,153 @@
|
||||||
#include "PixelShaderCache.h"
|
#include "PixelShaderCache.h"
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
#include "VertexShaderCache.h"
|
#include "VertexShaderCache.h"
|
||||||
|
#include "XFBEncoder.h"
|
||||||
#include "HW/Memmap.h"
|
#include "HW/Memmap.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11 {
|
||||||
{
|
|
||||||
|
static XFBEncoder s_xfbEncoder;
|
||||||
|
|
||||||
FramebufferManager::Efb FramebufferManager::m_efb;
|
FramebufferManager::Efb FramebufferManager::m_efb;
|
||||||
|
|
||||||
D3DTexture2D* FramebufferManager::GetResolvedEFBColorTexture()
|
D3DTexture2D* &FramebufferManager::GetEFBColorTexture() { return m_efb.color_tex; }
|
||||||
|
ID3D11Texture2D* &FramebufferManager::GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; }
|
||||||
|
|
||||||
|
D3DTexture2D* &FramebufferManager::GetEFBDepthTexture() { return m_efb.depth_tex; }
|
||||||
|
D3DTexture2D* &FramebufferManager::GetEFBDepthReadTexture() { return m_efb.depth_read_texture; }
|
||||||
|
ID3D11Texture2D* &FramebufferManager::GetEFBDepthStagingBuffer() { return m_efb.depth_staging_buf; }
|
||||||
|
|
||||||
|
D3DTexture2D* &FramebufferManager::GetResolvedEFBColorTexture()
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.iMultisampleMode)
|
if (g_ActiveConfig.iMultisampleMode)
|
||||||
{
|
{
|
||||||
D3D::g_context->ResolveSubresource(m_efb.resolved_color_tex->GetTex(), 0, m_efb.color_tex->GetTex(), 0, DXGI_FORMAT_R8G8B8A8_UNORM);
|
D3D::context->ResolveSubresource(m_efb.resolved_color_tex->GetTex(), 0, m_efb.color_tex->GetTex(), 0, DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||||
return m_efb.resolved_color_tex.get();
|
return m_efb.resolved_color_tex;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return m_efb.color_tex.get();
|
return m_efb.color_tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DTexture2D* FramebufferManager::GetResolvedEFBDepthTexture()
|
D3DTexture2D* &FramebufferManager::GetResolvedEFBDepthTexture()
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.iMultisampleMode)
|
if (g_ActiveConfig.iMultisampleMode)
|
||||||
{
|
{
|
||||||
D3D::g_context->ResolveSubresource(m_efb.resolved_color_tex->GetTex(), 0, m_efb.color_tex->GetTex(), 0, DXGI_FORMAT_R8G8B8A8_UNORM);
|
D3D::context->ResolveSubresource(m_efb.resolved_color_tex->GetTex(), 0, m_efb.color_tex->GetTex(), 0, DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||||
return m_efb.resolved_color_tex.get();
|
return m_efb.resolved_color_tex;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return m_efb.depth_tex.get();
|
return m_efb.depth_tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferManager::FramebufferManager()
|
FramebufferManager::FramebufferManager()
|
||||||
{
|
{
|
||||||
const unsigned int target_width = Renderer::GetTargetWidth();
|
unsigned int target_width = Renderer::GetTargetWidth();
|
||||||
const unsigned int target_height = Renderer::GetTargetHeight();
|
unsigned int target_height = Renderer::GetTargetHeight();
|
||||||
DXGI_SAMPLE_DESC sample_desc = D3D::GetAAMode(g_ActiveConfig.iMultisampleMode);
|
DXGI_SAMPLE_DESC sample_desc = D3D::GetAAMode(g_ActiveConfig.iMultisampleMode);
|
||||||
|
|
||||||
|
ID3D11Texture2D* buf;
|
||||||
|
D3D11_TEXTURE2D_DESC texdesc;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
// EFB color texture - primary render target
|
// EFB color texture - primary render target
|
||||||
{
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, target_width, target_height, 1, 1, D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT, 0, sample_desc.Count, sample_desc.Quality);
|
||||||
auto texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, target_width, target_height,
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
||||||
1, 1, D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT, 0, sample_desc.Count, sample_desc.Quality);
|
CHECK(hr==S_OK, "create EFB color texture (size: %dx%d; hr=%#x)", target_width, target_height, hr);
|
||||||
auto const buf = CreateTexture2DShared(&texdesc, NULL);
|
m_efb.color_tex = new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET), DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM, (sample_desc.Count > 1));
|
||||||
CHECK(buf, "create EFB color texture (size: %dx%d)", target_width, target_height);
|
|
||||||
m_efb.color_tex.reset(new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET),
|
|
||||||
DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM, (sample_desc.Count > 1)));
|
|
||||||
CHECK(m_efb.color_tex!=NULL, "create EFB color texture (size: %dx%d)", target_width, target_height);
|
CHECK(m_efb.color_tex!=NULL, "create EFB color texture (size: %dx%d)", target_width, target_height);
|
||||||
D3D::SetDebugObjectName(m_efb.color_tex->GetTex(), "EFB color texture");
|
SAFE_RELEASE(buf);
|
||||||
D3D::SetDebugObjectName(m_efb.color_tex->GetSRV(), "EFB color texture shader resource view");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetTex(), "EFB color texture");
|
||||||
D3D::SetDebugObjectName(m_efb.color_tex->GetRTV(), "EFB color texture render target view");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetSRV(), "EFB color texture shader resource view");
|
||||||
}
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetRTV(), "EFB color texture render target view");
|
||||||
|
|
||||||
// Temporary EFB color texture - used in ReinterpretPixelData
|
// Temporary EFB color texture - used in ReinterpretPixelData
|
||||||
{
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, target_width, target_height, 1, 1, D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT, 0, 1, 0);
|
||||||
auto texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, target_width, target_height,
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
||||||
1, 1, D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT, 0, 1, 0);
|
CHECK(hr==S_OK, "create EFB color temp texture (size: %dx%d; hr=%#x)", target_width, target_height, hr);
|
||||||
auto const buf = CreateTexture2DShared(&texdesc, NULL);
|
m_efb.color_temp_tex = new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET), DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||||
CHECK(buf, "create EFB color temp texture (size: %dx%d)", target_width, target_height);
|
|
||||||
m_efb.color_temp_tex.reset(new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET),
|
|
||||||
DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM));
|
|
||||||
CHECK(m_efb.color_temp_tex!=NULL, "create EFB color temp texture (size: %dx%d)", target_width, target_height);
|
CHECK(m_efb.color_temp_tex!=NULL, "create EFB color temp texture (size: %dx%d)", target_width, target_height);
|
||||||
D3D::SetDebugObjectName(m_efb.color_temp_tex->GetTex(), "EFB color temp texture");
|
SAFE_RELEASE(buf);
|
||||||
D3D::SetDebugObjectName(m_efb.color_temp_tex->GetSRV(), "EFB color temp texture shader resource view");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_temp_tex->GetTex(), "EFB color temp texture");
|
||||||
D3D::SetDebugObjectName(m_efb.color_temp_tex->GetRTV(), "EFB color temp texture render target view");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_temp_tex->GetSRV(), "EFB color temp texture shader resource view");
|
||||||
}
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_temp_tex->GetRTV(), "EFB color temp texture render target view");
|
||||||
|
|
||||||
// AccessEFB - Sysmem buffer used to retrieve the pixel data from color_tex
|
// AccessEFB - Sysmem buffer used to retrieve the pixel data from color_tex
|
||||||
{
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ);
|
||||||
auto texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ);
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &m_efb.color_staging_buf);
|
||||||
m_efb.color_staging_buf = CreateTexture2DShared(&texdesc, NULL);
|
CHECK(hr==S_OK, "create EFB color staging buffer (hr=%#x)", hr);
|
||||||
CHECK(m_efb.color_staging_buf, "create EFB color staging buffer");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_staging_buf, "EFB color staging texture (used for Renderer::AccessEFB)");
|
||||||
D3D::SetDebugObjectName(m_efb.color_staging_buf, "EFB color staging texture (used for Renderer::AccessEFB)");
|
|
||||||
}
|
|
||||||
|
|
||||||
// EFB depth buffer - primary depth buffer
|
// EFB depth buffer - primary depth buffer
|
||||||
{
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, target_width, target_height, 1, 1, D3D11_BIND_DEPTH_STENCIL|D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, sample_desc.Count, sample_desc.Quality);
|
||||||
auto texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, target_width, target_height, 1, 1, D3D11_BIND_DEPTH_STENCIL|D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, sample_desc.Count, sample_desc.Quality);
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
||||||
auto const buf = CreateTexture2DShared(&texdesc, NULL);
|
CHECK(hr==S_OK, "create EFB depth texture (size: %dx%d; hr=%#x)", target_width, target_height, hr);
|
||||||
CHECK(buf, "create EFB depth texture (size: %dx%d)", target_width, target_height);
|
m_efb.depth_tex = new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_DEPTH_STENCIL|D3D11_BIND_SHADER_RESOURCE), DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, (sample_desc.Count > 1));
|
||||||
m_efb.depth_tex.reset(new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE),
|
SAFE_RELEASE(buf);
|
||||||
DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, (sample_desc.Count > 1)));
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetTex(), "EFB depth texture");
|
||||||
D3D::SetDebugObjectName(m_efb.depth_tex->GetTex(), "EFB depth texture");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetDSV(), "EFB depth texture depth stencil view");
|
||||||
D3D::SetDebugObjectName(m_efb.depth_tex->GetDSV(), "EFB depth texture depth stencil view");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetSRV(), "EFB depth texture shader resource view");
|
||||||
D3D::SetDebugObjectName(m_efb.depth_tex->GetSRV(), "EFB depth texture shader resource view");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render buffer for AccessEFB (depth data)
|
// Render buffer for AccessEFB (depth data)
|
||||||
{
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, 1, 1, 1, 1, D3D11_BIND_RENDER_TARGET);
|
||||||
auto texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, 1, 1, 1, 1, D3D11_BIND_RENDER_TARGET);
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
||||||
auto const buf = CreateTexture2DShared(&texdesc, NULL);
|
CHECK(hr==S_OK, "create EFB depth read texture (hr=%#x)", hr);
|
||||||
CHECK(buf, "create EFB depth read texture");
|
m_efb.depth_read_texture = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
|
||||||
m_efb.depth_read_texture.reset(new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET));
|
SAFE_RELEASE(buf);
|
||||||
D3D::SetDebugObjectName(m_efb.depth_read_texture->GetTex(), "EFB depth read texture (used in Renderer::AccessEFB)");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_read_texture->GetTex(), "EFB depth read texture (used in Renderer::AccessEFB)");
|
||||||
D3D::SetDebugObjectName(m_efb.depth_read_texture->GetRTV(), "EFB depth read texture render target view (used in Renderer::AccessEFB)");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_read_texture->GetRTV(), "EFB depth read texture render target view (used in Renderer::AccessEFB)");
|
||||||
}
|
|
||||||
|
|
||||||
// AccessEFB - Sysmem buffer used to retrieve the pixel data from depth_read_texture
|
// AccessEFB - Sysmem buffer used to retrieve the pixel data from depth_read_texture
|
||||||
{
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, 1, 1, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ);
|
||||||
auto texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, 1, 1, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ);
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &m_efb.depth_staging_buf);
|
||||||
m_efb.depth_staging_buf = CreateTexture2DShared(&texdesc, NULL);
|
CHECK(hr==S_OK, "create EFB depth staging buffer (hr=%#x)", hr);
|
||||||
CHECK(m_efb.depth_staging_buf, "create EFB depth staging buffer");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_staging_buf, "EFB depth staging texture (used for Renderer::AccessEFB)");
|
||||||
D3D::SetDebugObjectName(m_efb.depth_staging_buf, "EFB depth staging texture (used for Renderer::AccessEFB)");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_ActiveConfig.iMultisampleMode)
|
if (g_ActiveConfig.iMultisampleMode)
|
||||||
{
|
{
|
||||||
// Framebuffer resolve textures (color+depth)
|
// Framebuffer resolve textures (color+depth)
|
||||||
{
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, target_width, target_height, 1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, 1);
|
||||||
auto texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, target_width, target_height,
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
||||||
1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, 1);
|
m_efb.resolved_color_tex = new D3DTexture2D(buf, D3D11_BIND_SHADER_RESOURCE, DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||||
auto const buf = CreateTexture2DShared(&texdesc, NULL);
|
|
||||||
m_efb.resolved_color_tex.reset(new D3DTexture2D(buf, D3D11_BIND_SHADER_RESOURCE, DXGI_FORMAT_R8G8B8A8_UNORM));
|
|
||||||
CHECK(m_efb.resolved_color_tex!=NULL, "create EFB color resolve texture (size: %dx%d)", target_width, target_height);
|
CHECK(m_efb.resolved_color_tex!=NULL, "create EFB color resolve texture (size: %dx%d)", target_width, target_height);
|
||||||
D3D::SetDebugObjectName(m_efb.resolved_color_tex->GetTex(), "EFB color resolve texture");
|
SAFE_RELEASE(buf);
|
||||||
D3D::SetDebugObjectName(m_efb.resolved_color_tex->GetSRV(), "EFB color resolve texture shader resource view");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_color_tex->GetTex(), "EFB color resolve texture");
|
||||||
}
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_color_tex->GetSRV(), "EFB color resolve texture shader resource view");
|
||||||
|
|
||||||
{
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, target_width, target_height, 1, 1, D3D11_BIND_SHADER_RESOURCE);
|
||||||
auto texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, target_width, target_height, 1, 1, D3D11_BIND_SHADER_RESOURCE);
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
||||||
auto const buf = CreateTexture2DShared(&texdesc, NULL);
|
CHECK(hr==S_OK, "create EFB depth resolve texture (size: %dx%d; hr=%#x)", target_width, target_height, hr);
|
||||||
CHECK(buf, "create EFB depth resolve texture (size: %dx%d)", target_width, target_height);
|
m_efb.resolved_depth_tex = new D3DTexture2D(buf, D3D11_BIND_SHADER_RESOURCE, DXGI_FORMAT_R24_UNORM_X8_TYPELESS);
|
||||||
m_efb.resolved_depth_tex.reset(new D3DTexture2D(buf, D3D11_BIND_SHADER_RESOURCE, DXGI_FORMAT_R24_UNORM_X8_TYPELESS));
|
SAFE_RELEASE(buf);
|
||||||
D3D::SetDebugObjectName(m_efb.resolved_depth_tex->GetTex(), "EFB depth resolve texture");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_depth_tex->GetTex(), "EFB depth resolve texture");
|
||||||
D3D::SetDebugObjectName(m_efb.resolved_depth_tex->GetSRV(), "EFB depth resolve texture shader resource view");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_depth_tex->GetSRV(), "EFB depth resolve texture shader resource view");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_efb.resolved_color_tex = NULL;
|
m_efb.resolved_color_tex = NULL;
|
||||||
m_efb.resolved_depth_tex = NULL;
|
m_efb.resolved_depth_tex = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s_xfbEncoder.Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferManager::~FramebufferManager()
|
FramebufferManager::~FramebufferManager()
|
||||||
{
|
{
|
||||||
m_efb.color_tex.reset();
|
s_xfbEncoder.Shutdown();
|
||||||
m_efb.color_staging_buf.reset();
|
|
||||||
|
|
||||||
m_efb.depth_tex.reset();
|
SAFE_RELEASE(m_efb.color_tex);
|
||||||
m_efb.depth_staging_buf.reset();
|
SAFE_RELEASE(m_efb.color_temp_tex);
|
||||||
m_efb.depth_read_texture.reset();
|
SAFE_RELEASE(m_efb.color_staging_buf);
|
||||||
|
SAFE_RELEASE(m_efb.resolved_color_tex);
|
||||||
m_efb.color_temp_tex.reset();
|
SAFE_RELEASE(m_efb.depth_tex);
|
||||||
|
SAFE_RELEASE(m_efb.depth_staging_buf);
|
||||||
m_efb.resolved_color_tex.reset();
|
SAFE_RELEASE(m_efb.depth_read_texture);
|
||||||
m_efb.resolved_depth_tex.reset();
|
SAFE_RELEASE(m_efb.resolved_depth_tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
|
void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
|
||||||
{
|
{
|
||||||
u8* dst = Memory::GetPointer(xfbAddr);
|
u8* dst = Memory::GetPointer(xfbAddr);
|
||||||
m_xfbEncoder.Encode(dst, fbWidth, fbHeight, sourceRc, Gamma);
|
s_xfbEncoder.Encode(dst, fbWidth, fbHeight, sourceRc, Gamma);
|
||||||
}
|
}
|
||||||
|
|
||||||
XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height)
|
XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height)
|
||||||
|
@ -216,8 +214,8 @@ void XFBSource::CopyEFB(float Gamma)
|
||||||
// Copy EFB data to XFB and restore render target again
|
// Copy EFB data to XFB and restore render target again
|
||||||
const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)texWidth, (float)texHeight);
|
const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)texWidth, (float)texHeight);
|
||||||
|
|
||||||
D3D::g_context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
D3D::g_context->OMSetRenderTargets(1, &tex->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &tex->GetRTV(), NULL);
|
||||||
D3D::SetLinearCopySampler();
|
D3D::SetLinearCopySampler();
|
||||||
|
|
||||||
D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), sourceRc.AsRECT(),
|
D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), sourceRc.AsRECT(),
|
||||||
|
@ -225,7 +223,7 @@ void XFBSource::CopyEFB(float Gamma)
|
||||||
PixelShaderCache::GetColorCopyProgram(true), VertexShaderCache::GetSimpleVertexShader(),
|
PixelShaderCache::GetColorCopyProgram(true), VertexShaderCache::GetSimpleVertexShader(),
|
||||||
VertexShaderCache::GetSimpleInputLayout(),Gamma);
|
VertexShaderCache::GetSimpleInputLayout(),Gamma);
|
||||||
|
|
||||||
D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(),
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(),
|
||||||
FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include "FramebufferManagerBase.h"
|
#include "FramebufferManagerBase.h"
|
||||||
|
|
||||||
#include "D3DTexture.h"
|
#include "D3DTexture.h"
|
||||||
#include "XFBEncoder.h"
|
|
||||||
|
|
||||||
namespace DX11 {
|
namespace DX11 {
|
||||||
|
|
||||||
|
@ -61,16 +60,15 @@ namespace DX11 {
|
||||||
|
|
||||||
struct XFBSource : public XFBSourceBase
|
struct XFBSource : public XFBSourceBase
|
||||||
{
|
{
|
||||||
XFBSource(std::unique_ptr<D3DTexture2D>&& _tex)
|
XFBSource(D3DTexture2D *_tex) : tex(_tex) {}
|
||||||
: tex(std::move(_tex))
|
~XFBSource() { tex->Release(); }
|
||||||
{}
|
|
||||||
|
|
||||||
void Draw(const MathUtil::Rectangle<float> &sourcerc,
|
void Draw(const MathUtil::Rectangle<float> &sourcerc,
|
||||||
const MathUtil::Rectangle<float> &drawrc, int width, int height) const;
|
const MathUtil::Rectangle<float> &drawrc, int width, int height) const;
|
||||||
void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
|
void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
|
||||||
void CopyEFB(float Gamma);
|
void CopyEFB(float Gamma);
|
||||||
|
|
||||||
std::unique_ptr<D3DTexture2D> const tex;
|
D3DTexture2D* const tex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FramebufferManager : public FramebufferManagerBase
|
class FramebufferManager : public FramebufferManagerBase
|
||||||
|
@ -79,21 +77,22 @@ public:
|
||||||
FramebufferManager();
|
FramebufferManager();
|
||||||
~FramebufferManager();
|
~FramebufferManager();
|
||||||
|
|
||||||
static D3DTexture2D* GetEFBColorTexture() { return m_efb.color_tex.get(); }
|
static D3DTexture2D* &GetEFBColorTexture();
|
||||||
static ID3D11Texture2D* GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; }
|
static ID3D11Texture2D* &GetEFBColorStagingBuffer();
|
||||||
|
|
||||||
static D3DTexture2D* GetEFBDepthTexture() { return m_efb.depth_tex.get(); }
|
static D3DTexture2D* &GetEFBDepthTexture();
|
||||||
static D3DTexture2D* GetEFBDepthReadTexture() { return m_efb.depth_read_texture.get(); }
|
static D3DTexture2D* &GetEFBDepthReadTexture();
|
||||||
static ID3D11Texture2D* GetEFBDepthStagingBuffer() { return m_efb.depth_staging_buf; }
|
static ID3D11Texture2D* &GetEFBDepthStagingBuffer();
|
||||||
|
|
||||||
static D3DTexture2D* GetResolvedEFBColorTexture();
|
static D3DTexture2D* &GetResolvedEFBColorTexture();
|
||||||
static D3DTexture2D* GetResolvedEFBDepthTexture();
|
static D3DTexture2D* &GetResolvedEFBDepthTexture();
|
||||||
|
|
||||||
static D3DTexture2D* GetEFBColorTempTexture() { return m_efb.color_temp_tex.get(); }
|
static D3DTexture2D* &GetEFBColorTempTexture() { return m_efb.color_temp_tex; }
|
||||||
|
|
||||||
static void SwapReinterpretTexture()
|
static void SwapReinterpretTexture()
|
||||||
{
|
{
|
||||||
std::swap(m_efb.color_temp_tex, m_efb.color_tex);
|
D3DTexture2D* swaptex = GetEFBColorTempTexture();
|
||||||
|
m_efb.color_temp_tex = GetEFBColorTexture();
|
||||||
|
m_efb.color_tex = swaptex;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -104,20 +103,18 @@ private:
|
||||||
|
|
||||||
static struct Efb
|
static struct Efb
|
||||||
{
|
{
|
||||||
std::unique_ptr<D3DTexture2D> color_tex;
|
D3DTexture2D* color_tex;
|
||||||
SharedPtr<ID3D11Texture2D> color_staging_buf;
|
ID3D11Texture2D* color_staging_buf;
|
||||||
|
|
||||||
std::unique_ptr<D3DTexture2D> depth_tex;
|
D3DTexture2D* depth_tex;
|
||||||
SharedPtr<ID3D11Texture2D> depth_staging_buf;
|
ID3D11Texture2D* depth_staging_buf;
|
||||||
std::unique_ptr<D3DTexture2D> depth_read_texture;
|
D3DTexture2D* depth_read_texture;
|
||||||
|
|
||||||
std::unique_ptr<D3DTexture2D> color_temp_tex;
|
D3DTexture2D* color_temp_tex;
|
||||||
|
|
||||||
std::unique_ptr<D3DTexture2D> resolved_color_tex;
|
D3DTexture2D* resolved_color_tex;
|
||||||
std::unique_ptr<D3DTexture2D> resolved_depth_tex;
|
D3DTexture2D* resolved_depth_tex;
|
||||||
} m_efb;
|
} m_efb;
|
||||||
|
|
||||||
XFBEncoder m_xfbEncoder;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace DX11
|
} // namespace DX11
|
||||||
|
|
|
@ -26,19 +26,66 @@ namespace DX11
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
std::unique_ptr<StateManager> stateman;
|
StateManager* stateman;
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T> AutoState<T>::AutoState(const T* object) : state(object)
|
||||||
|
{
|
||||||
|
((IUnknown*)state)->AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> AutoState<T>::AutoState(const AutoState<T> &source)
|
||||||
|
{
|
||||||
|
state = source.GetPtr();
|
||||||
|
((T*)state)->AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> AutoState<T>::~AutoState()
|
||||||
|
{
|
||||||
|
if(state) ((T*)state)->Release();
|
||||||
|
state = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
StateManager::StateManager() : cur_blendstate(NULL), cur_depthstate(NULL), cur_raststate(NULL) {}
|
||||||
|
|
||||||
|
void StateManager::PushBlendState(const ID3D11BlendState* state) { blendstates.push(AutoBlendState(state)); }
|
||||||
|
void StateManager::PushDepthState(const ID3D11DepthStencilState* state) { depthstates.push(AutoDepthStencilState(state)); }
|
||||||
|
void StateManager::PushRasterizerState(const ID3D11RasterizerState* state) { raststates.push(AutoRasterizerState(state)); }
|
||||||
|
void StateManager::PopBlendState() { blendstates.pop(); }
|
||||||
|
void StateManager::PopDepthState() { depthstates.pop(); }
|
||||||
|
void StateManager::PopRasterizerState() { raststates.pop(); }
|
||||||
|
|
||||||
void StateManager::Apply()
|
void StateManager::Apply()
|
||||||
{
|
{
|
||||||
if (blendstates.empty() || depthstates.empty() || raststates.empty())
|
if (!blendstates.empty())
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "Tried to apply without complete state!");
|
if (cur_blendstate != blendstates.top().GetPtr())
|
||||||
return;
|
{
|
||||||
|
cur_blendstate = (ID3D11BlendState*)blendstates.top().GetPtr();
|
||||||
|
D3D::context->OMSetBlendState(cur_blendstate, NULL, 0xFFFFFFFF);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else ERROR_LOG(VIDEO, "Tried to apply without blend state!");
|
||||||
|
|
||||||
D3D::g_context->OMSetBlendState(blendstates.top(), NULL, 0xFFFFFFFF);
|
if (!depthstates.empty())
|
||||||
D3D::g_context->OMSetDepthStencilState(depthstates.top(), 0);
|
{
|
||||||
D3D::g_context->RSSetState(raststates.top());
|
if (cur_depthstate != depthstates.top().GetPtr())
|
||||||
|
{
|
||||||
|
cur_depthstate = (ID3D11DepthStencilState*)depthstates.top().GetPtr();
|
||||||
|
D3D::context->OMSetDepthStencilState(cur_depthstate, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else ERROR_LOG(VIDEO, "Tried to apply without depth state!");
|
||||||
|
|
||||||
|
if (!raststates.empty())
|
||||||
|
{
|
||||||
|
if (cur_raststate != raststates.top().GetPtr())
|
||||||
|
{
|
||||||
|
cur_raststate = (ID3D11RasterizerState*)raststates.top().GetPtr();
|
||||||
|
D3D::context->RSSetState(cur_raststate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else ERROR_LOG(VIDEO, "Tried to apply without rasterizer state!");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -19,7 +19,9 @@
|
||||||
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
#include "D3DUtil.h"
|
struct ID3D11BlendState;
|
||||||
|
struct ID3D11DepthStencilState;
|
||||||
|
struct ID3D11RasterizerState;
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
@ -27,35 +29,37 @@ namespace DX11
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef SharedPtr<ID3D11BlendState> AutoBlendState;
|
template<typename T> class AutoState
|
||||||
typedef SharedPtr<ID3D11DepthStencilState> AutoDepthStencilState;
|
{
|
||||||
typedef SharedPtr<ID3D11RasterizerState> AutoRasterizerState;
|
public:
|
||||||
|
AutoState(const T* object);
|
||||||
|
AutoState(const AutoState<T> &source);
|
||||||
|
~AutoState();
|
||||||
|
|
||||||
|
const inline T* GetPtr() const { return state; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const T* state;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef AutoState<ID3D11BlendState> AutoBlendState;
|
||||||
|
typedef AutoState<ID3D11DepthStencilState> AutoDepthStencilState;
|
||||||
|
typedef AutoState<ID3D11RasterizerState> AutoRasterizerState;
|
||||||
|
|
||||||
class StateManager
|
class StateManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
StateManager();
|
||||||
|
|
||||||
// call any of these to change the affected states
|
// call any of these to change the affected states
|
||||||
void PushBlendState(const AutoBlendState& state)
|
void PushBlendState(const ID3D11BlendState* state);
|
||||||
{
|
void PushDepthState(const ID3D11DepthStencilState* state);
|
||||||
blendstates.push(state);
|
void PushRasterizerState(const ID3D11RasterizerState* state);
|
||||||
}
|
|
||||||
|
|
||||||
void PushDepthState(ID3D11DepthStencilState* state)
|
|
||||||
{
|
|
||||||
state->AddRef();
|
|
||||||
depthstates.push(AutoDepthStencilState::FromPtr(state));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PushRasterizerState(ID3D11RasterizerState* state)
|
|
||||||
{
|
|
||||||
state->AddRef();
|
|
||||||
raststates.push(AutoRasterizerState::FromPtr(state));
|
|
||||||
}
|
|
||||||
|
|
||||||
// call these after drawing
|
// call these after drawing
|
||||||
void PopBlendState() { blendstates.pop(); }
|
void PopBlendState();
|
||||||
void PopDepthState() { depthstates.pop(); }
|
void PopDepthState();
|
||||||
void PopRasterizerState() { raststates.pop(); }
|
void PopRasterizerState();
|
||||||
|
|
||||||
// call this before any drawing operation if states could have changed meanwhile
|
// call this before any drawing operation if states could have changed meanwhile
|
||||||
void Apply();
|
void Apply();
|
||||||
|
@ -64,9 +68,12 @@ private:
|
||||||
std::stack<AutoBlendState> blendstates;
|
std::stack<AutoBlendState> blendstates;
|
||||||
std::stack<AutoDepthStencilState> depthstates;
|
std::stack<AutoDepthStencilState> depthstates;
|
||||||
std::stack<AutoRasterizerState> raststates;
|
std::stack<AutoRasterizerState> raststates;
|
||||||
|
ID3D11BlendState* cur_blendstate;
|
||||||
|
ID3D11DepthStencilState* cur_depthstate;
|
||||||
|
ID3D11RasterizerState* cur_raststate;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::unique_ptr<StateManager> stateman;
|
extern StateManager* stateman;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
|
@ -138,19 +138,39 @@ static const char LINE_GS_COMMON[] =
|
||||||
;
|
;
|
||||||
|
|
||||||
LineGeometryShader::LineGeometryShader()
|
LineGeometryShader::LineGeometryShader()
|
||||||
: m_ready(false)
|
: m_ready(false), m_paramsBuffer(NULL)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void LineGeometryShader::Init()
|
||||||
{
|
{
|
||||||
|
m_ready = false;
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
// Create constant buffer for uploading data to geometry shader
|
// Create constant buffer for uploading data to geometry shader
|
||||||
|
|
||||||
D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(LineGSParams_Padded),
|
D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(LineGSParams_Padded),
|
||||||
D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||||
m_paramsBuffer = CreateBufferShared(&bd, NULL);
|
hr = D3D::device->CreateBuffer(&bd, NULL, &m_paramsBuffer);
|
||||||
CHECK(m_paramsBuffer, "create line geometry shader params buffer");
|
CHECK(SUCCEEDED(hr), "create line geometry shader params buffer");
|
||||||
D3D::SetDebugObjectName(m_paramsBuffer, "line geometry shader params buffer");
|
D3D::SetDebugObjectName(m_paramsBuffer, "line geometry shader params buffer");
|
||||||
|
|
||||||
m_ready = true;
|
m_ready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LineGeometryShader::Shutdown()
|
||||||
|
{
|
||||||
|
m_ready = false;
|
||||||
|
|
||||||
|
for (ComboMap::iterator it = m_shaders.begin(); it != m_shaders.end(); ++it)
|
||||||
|
{
|
||||||
|
SAFE_RELEASE(it->second);
|
||||||
|
}
|
||||||
|
m_shaders.clear();
|
||||||
|
|
||||||
|
SAFE_RELEASE(m_paramsBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
bool LineGeometryShader::SetShader(u32 components, float lineWidth,
|
bool LineGeometryShader::SetShader(u32 components, float lineWidth,
|
||||||
float texOffset, float vpWidth, float vpHeight, const bool* texOffsetEnable)
|
float texOffset, float vpWidth, float vpHeight, const bool* texOffsetEnable)
|
||||||
{
|
{
|
||||||
|
@ -177,13 +197,12 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth,
|
||||||
{ "NUM_TEXCOORDS", numTexCoordsStr.str().c_str() },
|
{ "NUM_TEXCOORDS", numTexCoordsStr.str().c_str() },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
ID3D11GeometryShader* newShader = D3D::CompileAndCreateGeometryShader(code, unsigned int(strlen(code)), macros);
|
||||||
auto const newShader = D3D::CompileAndCreateGeometryShader(code, unsigned int(strlen(code)), macros);
|
|
||||||
if (!newShader)
|
if (!newShader)
|
||||||
{
|
{
|
||||||
WARN_LOG(VIDEO, "Line geometry shader for components 0x%.08X failed to compile", components);
|
WARN_LOG(VIDEO, "Line geometry shader for components 0x%.08X failed to compile", components);
|
||||||
// Add dummy shader to prevent trying to compile again
|
// Add dummy shader to prevent trying to compile again
|
||||||
m_shaders[components].reset();
|
m_shaders[components] = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,18 +214,19 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth,
|
||||||
if (shaderIt->second)
|
if (shaderIt->second)
|
||||||
{
|
{
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
HRESULT hr = D3D::g_context->Map(m_paramsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
HRESULT hr = D3D::context->Map(m_paramsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
LineGSParams* params = (LineGSParams*)map.pData;
|
LineGSParams* params = (LineGSParams*)map.pData;
|
||||||
params->LineWidth = lineWidth;
|
params->LineWidth = lineWidth;
|
||||||
|
|
||||||
params->TexOffset = texOffset;
|
params->TexOffset = texOffset;
|
||||||
params->VpWidth = vpWidth;
|
params->VpWidth = vpWidth;
|
||||||
params->VpHeight = vpHeight;
|
params->VpHeight = vpHeight;
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
params->TexOffsetEnable[i] = texOffsetEnable[i] ? 1.f : 0.f;
|
params->TexOffsetEnable[i] = texOffsetEnable[i] ? 1.f : 0.f;
|
||||||
|
|
||||||
D3D::g_context->Unmap(m_paramsBuffer, 0);
|
D3D::context->Unmap(m_paramsBuffer, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ERROR_LOG(VIDEO, "Failed to map line gs params buffer");
|
ERROR_LOG(VIDEO, "Failed to map line gs params buffer");
|
||||||
|
@ -214,8 +234,8 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth,
|
||||||
DEBUG_LOG(VIDEO, "Line params: width %f, texOffset %f, vpWidth %f, vpHeight %f",
|
DEBUG_LOG(VIDEO, "Line params: width %f, texOffset %f, vpWidth %f, vpHeight %f",
|
||||||
lineWidth, texOffset, vpWidth, vpHeight);
|
lineWidth, texOffset, vpWidth, vpHeight);
|
||||||
|
|
||||||
D3D::g_context->GSSetShader(shaderIt->second, NULL, 0);
|
D3D::context->GSSetShader(shaderIt->second, NULL, 0);
|
||||||
D3D::g_context->GSSetConstantBuffers(0, 1, &m_paramsBuffer);
|
D3D::context->GSSetConstantBuffers(0, 1, &m_paramsBuffer);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,9 @@
|
||||||
#define _LINEGEOMETRYSHADER_H
|
#define _LINEGEOMETRYSHADER_H
|
||||||
|
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
#include "D3DUtil.h"
|
|
||||||
|
struct ID3D11Buffer;
|
||||||
|
struct ID3D11GeometryShader;
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
@ -28,21 +30,27 @@ namespace DX11
|
||||||
// vertex format.
|
// vertex format.
|
||||||
class LineGeometryShader
|
class LineGeometryShader
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LineGeometryShader();
|
LineGeometryShader();
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void Shutdown();
|
||||||
// Returns true on success, false on failure
|
// Returns true on success, false on failure
|
||||||
bool SetShader(u32 components, float lineWidth, float texOffset,
|
bool SetShader(u32 components, float lineWidth, float texOffset,
|
||||||
float vpWidth, float vpHeight, const bool* texOffsetEnable);
|
float vpWidth, float vpHeight, const bool* texOffsetEnable);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool m_ready;
|
bool m_ready;
|
||||||
|
|
||||||
SharedPtr<ID3D11Buffer> m_paramsBuffer;
|
ID3D11Buffer* m_paramsBuffer;
|
||||||
|
|
||||||
typedef std::map<u32, SharedPtr<ID3D11GeometryShader>> ComboMap;
|
typedef std::map<u32, ID3D11GeometryShader*> ComboMap;
|
||||||
|
|
||||||
ComboMap m_shaders;
|
ComboMap m_shaders;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "D3DBase.h"
|
#include "D3DBase.h"
|
||||||
|
#include "D3DBlob.h"
|
||||||
#include "NativeVertexFormat.h"
|
#include "NativeVertexFormat.h"
|
||||||
#include "VertexManager.h"
|
#include "VertexManager.h"
|
||||||
#include "VertexShaderCache.h"
|
#include "VertexShaderCache.h"
|
||||||
|
@ -29,11 +30,12 @@ class D3DVertexFormat : public NativeVertexFormat
|
||||||
D3D11_INPUT_ELEMENT_DESC m_elems[32];
|
D3D11_INPUT_ELEMENT_DESC m_elems[32];
|
||||||
UINT m_num_elems;
|
UINT m_num_elems;
|
||||||
|
|
||||||
SharedPtr<ID3D10Blob> m_vs_bytecode;
|
DX11::D3DBlob* m_vs_bytecode;
|
||||||
SharedPtr<ID3D11InputLayout> m_layout;
|
ID3D11InputLayout* m_layout;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
D3DVertexFormat() : m_num_elems(0) {}
|
D3DVertexFormat() : m_num_elems(0), m_vs_bytecode(NULL), m_layout(NULL) {}
|
||||||
|
~D3DVertexFormat() { SAFE_RELEASE(m_vs_bytecode); SAFE_RELEASE(m_layout); }
|
||||||
|
|
||||||
void Initialize(const PortableVertexDeclaration &_vtx_decl);
|
void Initialize(const PortableVertexDeclaration &_vtx_decl);
|
||||||
void SetupVertexPointers();
|
void SetupVertexPointers();
|
||||||
|
@ -139,15 +141,17 @@ void D3DVertexFormat::SetupVertexPointers()
|
||||||
{
|
{
|
||||||
if (m_vs_bytecode != DX11::VertexShaderCache::GetActiveShaderBytecode())
|
if (m_vs_bytecode != DX11::VertexShaderCache::GetActiveShaderBytecode())
|
||||||
{
|
{
|
||||||
m_vs_bytecode = DX11::VertexShaderCache::GetActiveShaderBytecode();
|
SAFE_RELEASE(m_vs_bytecode);
|
||||||
|
SAFE_RELEASE(m_layout);
|
||||||
|
|
||||||
m_layout = CreateInputLayoutShared(m_elems, m_num_elems,
|
m_vs_bytecode = DX11::VertexShaderCache::GetActiveShaderBytecode();
|
||||||
m_vs_bytecode->GetBufferPointer(), m_vs_bytecode->GetBufferSize());
|
m_vs_bytecode->AddRef();
|
||||||
if (!m_layout)
|
|
||||||
PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__);
|
HRESULT hr = DX11::D3D::device->CreateInputLayout(m_elems, m_num_elems, m_vs_bytecode->Data(), m_vs_bytecode->Size(), &m_layout);
|
||||||
DX11::D3D::SetDebugObjectName(m_layout, "input layout used to emulate the GX pipeline");
|
if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__);
|
||||||
|
DX11::D3D::SetDebugObjectName((ID3D11DeviceChild*)m_layout, "input layout used to emulate the GX pipeline");
|
||||||
}
|
}
|
||||||
DX11::D3D::g_context->IASetInputLayout(m_layout);
|
DX11::D3D::context->IASetInputLayout(m_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace DX11
|
} // namespace DX11
|
||||||
|
|
|
@ -846,6 +846,24 @@ static const char EFB_ENCODE_PS[] =
|
||||||
"}\n"
|
"}\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
|
PSTextureEncoder::PSTextureEncoder()
|
||||||
|
: m_ready(false), m_out(NULL), m_outRTV(NULL), m_outStage(NULL),
|
||||||
|
m_encodeParams(NULL),
|
||||||
|
m_quad(NULL), m_vShader(NULL), m_quadLayout(NULL),
|
||||||
|
m_efbEncodeBlendState(NULL), m_efbEncodeDepthState(NULL),
|
||||||
|
m_efbEncodeRastState(NULL), m_efbSampler(NULL),
|
||||||
|
m_dynamicShader(NULL), m_classLinkage(NULL)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < 4; ++i)
|
||||||
|
m_fetchClass[i] = NULL;
|
||||||
|
for (size_t i = 0; i < 2; ++i)
|
||||||
|
m_scaledFetchClass[i] = NULL;
|
||||||
|
for (size_t i = 0; i < 2; ++i)
|
||||||
|
m_intensityClass[i] = NULL;
|
||||||
|
for (size_t i = 0; i < 16; ++i)
|
||||||
|
m_generatorClass[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static const D3D11_INPUT_ELEMENT_DESC QUAD_LAYOUT_DESC[] = {
|
static const D3D11_INPUT_ELEMENT_DESC QUAD_LAYOUT_DESC[] = {
|
||||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }
|
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }
|
||||||
};
|
};
|
||||||
|
@ -856,22 +874,11 @@ static const struct QuadVertex
|
||||||
float posY;
|
float posY;
|
||||||
} QUAD_VERTS[4] = { { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } };
|
} QUAD_VERTS[4] = { { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } };
|
||||||
|
|
||||||
PSTextureEncoder::PSTextureEncoder()
|
void PSTextureEncoder::Init()
|
||||||
: m_ready(false), m_outRTV(NULL),
|
|
||||||
m_efbEncodeDepthState(NULL),
|
|
||||||
m_efbEncodeRastState(NULL), m_efbSampler(NULL),
|
|
||||||
m_classLinkage(NULL)
|
|
||||||
{
|
{
|
||||||
m_ready = false;
|
m_ready = false;
|
||||||
|
|
||||||
for (size_t i = 0; i < 4; ++i)
|
HRESULT hr;
|
||||||
m_fetchClass[i] = NULL;
|
|
||||||
for (size_t i = 0; i < 2; ++i)
|
|
||||||
m_scaledFetchClass[i] = NULL;
|
|
||||||
for (size_t i = 0; i < 2; ++i)
|
|
||||||
m_intensityClass[i] = NULL;
|
|
||||||
for (size_t i = 0; i < 16; ++i)
|
|
||||||
m_generatorClass[i] = NULL;
|
|
||||||
|
|
||||||
// Create output texture RGBA format
|
// Create output texture RGBA format
|
||||||
|
|
||||||
|
@ -879,15 +886,15 @@ PSTextureEncoder::PSTextureEncoder()
|
||||||
D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC(
|
D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC(
|
||||||
DXGI_FORMAT_R32G32B32A32_UINT,
|
DXGI_FORMAT_R32G32B32A32_UINT,
|
||||||
EFB_WIDTH, EFB_HEIGHT/4, 1, 1, D3D11_BIND_RENDER_TARGET);
|
EFB_WIDTH, EFB_HEIGHT/4, 1, 1, D3D11_BIND_RENDER_TARGET);
|
||||||
m_out = CreateTexture2DShared(&t2dd, NULL);
|
hr = D3D::device->CreateTexture2D(&t2dd, NULL, &m_out);
|
||||||
CHECK(m_out, "create efb encode output texture");
|
CHECK(SUCCEEDED(hr), "create efb encode output texture");
|
||||||
D3D::SetDebugObjectName(m_out, "efb encoder output texture");
|
D3D::SetDebugObjectName(m_out, "efb encoder output texture");
|
||||||
|
|
||||||
// Create output render target view
|
// Create output render target view
|
||||||
|
|
||||||
D3D11_RENDER_TARGET_VIEW_DESC rtvd = CD3D11_RENDER_TARGET_VIEW_DESC(m_out,
|
D3D11_RENDER_TARGET_VIEW_DESC rtvd = CD3D11_RENDER_TARGET_VIEW_DESC(m_out,
|
||||||
D3D11_RTV_DIMENSION_TEXTURE2D, DXGI_FORMAT_R32G32B32A32_UINT);
|
D3D11_RTV_DIMENSION_TEXTURE2D, DXGI_FORMAT_R32G32B32A32_UINT);
|
||||||
HRESULT hr = D3D::g_device->CreateRenderTargetView(m_out, &rtvd, &m_outRTV);
|
hr = D3D::device->CreateRenderTargetView(m_out, &rtvd, &m_outRTV);
|
||||||
CHECK(SUCCEEDED(hr), "create efb encode output render target view");
|
CHECK(SUCCEEDED(hr), "create efb encode output render target view");
|
||||||
D3D::SetDebugObjectName(m_outRTV, "efb encoder output rtv");
|
D3D::SetDebugObjectName(m_outRTV, "efb encoder output rtv");
|
||||||
|
|
||||||
|
@ -896,16 +903,16 @@ PSTextureEncoder::PSTextureEncoder()
|
||||||
t2dd.Usage = D3D11_USAGE_STAGING;
|
t2dd.Usage = D3D11_USAGE_STAGING;
|
||||||
t2dd.BindFlags = 0;
|
t2dd.BindFlags = 0;
|
||||||
t2dd.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
t2dd.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||||
m_outStage = CreateTexture2DShared(&t2dd, NULL);
|
hr = D3D::device->CreateTexture2D(&t2dd, NULL, &m_outStage);
|
||||||
CHECK(m_outStage, "create efb encode output staging buffer");
|
CHECK(SUCCEEDED(hr), "create efb encode output staging buffer");
|
||||||
D3D::SetDebugObjectName(m_outStage, "efb encoder output staging buffer");
|
D3D::SetDebugObjectName(m_outStage, "efb encoder output staging buffer");
|
||||||
|
|
||||||
// Create constant buffer for uploading data to shaders
|
// Create constant buffer for uploading data to shaders
|
||||||
|
|
||||||
D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(EFBEncodeParams),
|
D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(EFBEncodeParams),
|
||||||
D3D11_BIND_CONSTANT_BUFFER);
|
D3D11_BIND_CONSTANT_BUFFER);
|
||||||
m_encodeParams = CreateBufferShared(&bd, NULL);
|
hr = D3D::device->CreateBuffer(&bd, NULL, &m_encodeParams);
|
||||||
CHECK(m_encodeParams, "create efb encode params buffer");
|
CHECK(SUCCEEDED(hr), "create efb encode params buffer");
|
||||||
D3D::SetDebugObjectName(m_encodeParams, "efb encoder params buffer");
|
D3D::SetDebugObjectName(m_encodeParams, "efb encoder params buffer");
|
||||||
|
|
||||||
// Create vertex quad
|
// Create vertex quad
|
||||||
|
@ -914,23 +921,33 @@ PSTextureEncoder::PSTextureEncoder()
|
||||||
D3D11_USAGE_IMMUTABLE);
|
D3D11_USAGE_IMMUTABLE);
|
||||||
D3D11_SUBRESOURCE_DATA srd = { QUAD_VERTS, 0, 0 };
|
D3D11_SUBRESOURCE_DATA srd = { QUAD_VERTS, 0, 0 };
|
||||||
|
|
||||||
m_quad = CreateBufferShared(&bd, &srd);
|
hr = D3D::device->CreateBuffer(&bd, &srd, &m_quad);
|
||||||
CHECK(m_quad, "create efb encode quad vertex buffer");
|
CHECK(SUCCEEDED(hr), "create efb encode quad vertex buffer");
|
||||||
D3D::SetDebugObjectName(m_quad, "efb encoder quad vertex buffer");
|
D3D::SetDebugObjectName(m_quad, "efb encoder quad vertex buffer");
|
||||||
|
|
||||||
// Create vertex shader
|
// Create vertex shader
|
||||||
SharedPtr<ID3D10Blob> bytecode;
|
|
||||||
m_vShader = D3D::CompileAndCreateVertexShader(EFB_ENCODE_VS, sizeof(EFB_ENCODE_VS), std::addressof(bytecode));
|
D3DBlob* bytecode = NULL;
|
||||||
CHECK(m_vShader, "compile/create efb encode vertex shader");
|
if (!D3D::CompileVertexShader(EFB_ENCODE_VS, sizeof(EFB_ENCODE_VS), &bytecode))
|
||||||
|
{
|
||||||
|
ERROR_LOG(VIDEO, "EFB encode vertex shader failed to compile");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = D3D::device->CreateVertexShader(bytecode->Data(), bytecode->Size(), NULL, &m_vShader);
|
||||||
|
CHECK(SUCCEEDED(hr), "create efb encode vertex shader");
|
||||||
D3D::SetDebugObjectName(m_vShader, "efb encoder vertex shader");
|
D3D::SetDebugObjectName(m_vShader, "efb encoder vertex shader");
|
||||||
|
|
||||||
// Create input layout for vertex quad using bytecode from vertex shader
|
// Create input layout for vertex quad using bytecode from vertex shader
|
||||||
m_quadLayout = CreateInputLayoutShared(QUAD_LAYOUT_DESC,
|
|
||||||
sizeof(QUAD_LAYOUT_DESC) / sizeof(D3D11_INPUT_ELEMENT_DESC),
|
hr = D3D::device->CreateInputLayout(QUAD_LAYOUT_DESC,
|
||||||
bytecode->GetBufferPointer(), bytecode->GetBufferSize());
|
sizeof(QUAD_LAYOUT_DESC)/sizeof(D3D11_INPUT_ELEMENT_DESC),
|
||||||
CHECK(m_quadLayout, "create efb encode quad vertex layout");
|
bytecode->Data(), bytecode->Size(), &m_quadLayout);
|
||||||
|
CHECK(SUCCEEDED(hr), "create efb encode quad vertex layout");
|
||||||
D3D::SetDebugObjectName(m_quadLayout, "efb encoder quad layout");
|
D3D::SetDebugObjectName(m_quadLayout, "efb encoder quad layout");
|
||||||
|
|
||||||
|
bytecode->Release();
|
||||||
|
|
||||||
// Create pixel shader
|
// Create pixel shader
|
||||||
|
|
||||||
#ifdef USE_DYNAMIC_MODE
|
#ifdef USE_DYNAMIC_MODE
|
||||||
|
@ -941,46 +958,44 @@ PSTextureEncoder::PSTextureEncoder()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Create blend state
|
// Create blend state
|
||||||
{
|
|
||||||
auto const bld = CD3D11_BLEND_DESC(CD3D11_DEFAULT());
|
D3D11_BLEND_DESC bld = CD3D11_BLEND_DESC(CD3D11_DEFAULT());
|
||||||
m_efbEncodeBlendState = CreateBlendStateShared(&bld);
|
hr = D3D::device->CreateBlendState(&bld, &m_efbEncodeBlendState);
|
||||||
CHECK(SUCCEEDED(hr), "create efb encode blend state");
|
CHECK(SUCCEEDED(hr), "create efb encode blend state");
|
||||||
D3D::SetDebugObjectName(m_efbEncodeBlendState, "efb encoder blend state");
|
D3D::SetDebugObjectName(m_efbEncodeBlendState, "efb encoder blend state");
|
||||||
}
|
|
||||||
|
|
||||||
// Create depth state
|
// Create depth state
|
||||||
{
|
|
||||||
auto dsd = CD3D11_DEPTH_STENCIL_DESC(CD3D11_DEFAULT());
|
D3D11_DEPTH_STENCIL_DESC dsd = CD3D11_DEPTH_STENCIL_DESC(CD3D11_DEFAULT());
|
||||||
dsd.DepthEnable = FALSE;
|
dsd.DepthEnable = FALSE;
|
||||||
hr = D3D::g_device->CreateDepthStencilState(&dsd, &m_efbEncodeDepthState);
|
hr = D3D::device->CreateDepthStencilState(&dsd, &m_efbEncodeDepthState);
|
||||||
CHECK(SUCCEEDED(hr), "create efb encode depth state");
|
CHECK(SUCCEEDED(hr), "create efb encode depth state");
|
||||||
D3D::SetDebugObjectName(m_efbEncodeDepthState, "efb encoder depth state");
|
D3D::SetDebugObjectName(m_efbEncodeDepthState, "efb encoder depth state");
|
||||||
}
|
|
||||||
|
|
||||||
// Create rasterizer state
|
// Create rasterizer state
|
||||||
{
|
|
||||||
auto rd = CD3D11_RASTERIZER_DESC(CD3D11_DEFAULT());
|
D3D11_RASTERIZER_DESC rd = CD3D11_RASTERIZER_DESC(CD3D11_DEFAULT());
|
||||||
rd.CullMode = D3D11_CULL_NONE;
|
rd.CullMode = D3D11_CULL_NONE;
|
||||||
rd.DepthClipEnable = FALSE;
|
rd.DepthClipEnable = FALSE;
|
||||||
hr = D3D::g_device->CreateRasterizerState(&rd, &m_efbEncodeRastState);
|
hr = D3D::device->CreateRasterizerState(&rd, &m_efbEncodeRastState);
|
||||||
CHECK(SUCCEEDED(hr), "create efb encode rast state");
|
CHECK(SUCCEEDED(hr), "create efb encode rast state");
|
||||||
D3D::SetDebugObjectName(m_efbEncodeRastState, "efb encoder rast state");
|
D3D::SetDebugObjectName(m_efbEncodeRastState, "efb encoder rast state");
|
||||||
}
|
|
||||||
|
|
||||||
// Create efb texture sampler
|
// Create efb texture sampler
|
||||||
{
|
|
||||||
auto sd = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT());
|
D3D11_SAMPLER_DESC sd = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT());
|
||||||
sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||||
hr = D3D::g_device->CreateSamplerState(&sd, &m_efbSampler);
|
hr = D3D::device->CreateSamplerState(&sd, &m_efbSampler);
|
||||||
CHECK(SUCCEEDED(hr), "create efb encode texture sampler");
|
CHECK(SUCCEEDED(hr), "create efb encode texture sampler");
|
||||||
D3D::SetDebugObjectName(m_efbSampler, "efb encoder texture sampler");
|
D3D::SetDebugObjectName(m_efbSampler, "efb encoder texture sampler");
|
||||||
}
|
|
||||||
|
|
||||||
m_ready = true;
|
m_ready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
PSTextureEncoder::~PSTextureEncoder()
|
void PSTextureEncoder::Shutdown()
|
||||||
{
|
{
|
||||||
|
m_ready = false;
|
||||||
|
|
||||||
for (size_t i = 0; i < 4; ++i)
|
for (size_t i = 0; i < 4; ++i)
|
||||||
SAFE_RELEASE(m_fetchClass[i]);
|
SAFE_RELEASE(m_fetchClass[i]);
|
||||||
for (size_t i = 0; i < 2; ++i)
|
for (size_t i = 0; i < 2; ++i)
|
||||||
|
@ -989,13 +1004,29 @@ PSTextureEncoder::~PSTextureEncoder()
|
||||||
SAFE_RELEASE(m_intensityClass[i]);
|
SAFE_RELEASE(m_intensityClass[i]);
|
||||||
for (size_t i = 0; i < 16; ++i)
|
for (size_t i = 0; i < 16; ++i)
|
||||||
SAFE_RELEASE(m_generatorClass[i]);
|
SAFE_RELEASE(m_generatorClass[i]);
|
||||||
|
m_linkageArray.clear();
|
||||||
|
|
||||||
SAFE_RELEASE(m_classLinkage);
|
SAFE_RELEASE(m_classLinkage);
|
||||||
|
SAFE_RELEASE(m_dynamicShader);
|
||||||
|
|
||||||
|
for (ComboMap::iterator it = m_staticShaders.begin();
|
||||||
|
it != m_staticShaders.end(); ++it)
|
||||||
|
{
|
||||||
|
SAFE_RELEASE(it->second);
|
||||||
|
}
|
||||||
|
m_staticShaders.clear();
|
||||||
|
|
||||||
SAFE_RELEASE(m_efbSampler);
|
SAFE_RELEASE(m_efbSampler);
|
||||||
SAFE_RELEASE(m_efbEncodeRastState);
|
SAFE_RELEASE(m_efbEncodeRastState);
|
||||||
SAFE_RELEASE(m_efbEncodeDepthState);
|
SAFE_RELEASE(m_efbEncodeDepthState);
|
||||||
|
SAFE_RELEASE(m_efbEncodeBlendState);
|
||||||
|
SAFE_RELEASE(m_quadLayout);
|
||||||
|
SAFE_RELEASE(m_vShader);
|
||||||
|
SAFE_RELEASE(m_quad);
|
||||||
|
SAFE_RELEASE(m_encodeParams);
|
||||||
|
SAFE_RELEASE(m_outStage);
|
||||||
SAFE_RELEASE(m_outRTV);
|
SAFE_RELEASE(m_outRTV);
|
||||||
|
SAFE_RELEASE(m_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat,
|
size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat,
|
||||||
|
@ -1052,7 +1083,7 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat,
|
||||||
if (SetStaticShader(dstFormat, srcFormat, isIntensity, scaleByHalf))
|
if (SetStaticShader(dstFormat, srcFormat, isIntensity, scaleByHalf))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
D3D::g_context->VSSetShader(m_vShader, NULL, 0);
|
D3D::context->VSSetShader(m_vShader, NULL, 0);
|
||||||
|
|
||||||
D3D::stateman->PushBlendState(m_efbEncodeBlendState);
|
D3D::stateman->PushBlendState(m_efbEncodeBlendState);
|
||||||
D3D::stateman->PushDepthState(m_efbEncodeDepthState);
|
D3D::stateman->PushDepthState(m_efbEncodeDepthState);
|
||||||
|
@ -1060,13 +1091,13 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat,
|
||||||
D3D::stateman->Apply();
|
D3D::stateman->Apply();
|
||||||
|
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, FLOAT(cacheLinesPerRow*2), FLOAT(numBlocksY));
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, FLOAT(cacheLinesPerRow*2), FLOAT(numBlocksY));
|
||||||
D3D::g_context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
D3D::g_context->IASetInputLayout(m_quadLayout);
|
D3D::context->IASetInputLayout(m_quadLayout);
|
||||||
D3D::g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||||
UINT stride = sizeof(QuadVertex);
|
UINT stride = sizeof(QuadVertex);
|
||||||
UINT offset = 0;
|
UINT offset = 0;
|
||||||
D3D::g_context->IASetVertexBuffers(0, 1, &m_quad, &stride, &offset);
|
D3D::context->IASetVertexBuffers(0, 1, &m_quad, &stride, &offset);
|
||||||
|
|
||||||
EFBRectangle fullSrcRect;
|
EFBRectangle fullSrcRect;
|
||||||
fullSrcRect.left = 0;
|
fullSrcRect.left = 0;
|
||||||
|
@ -1084,55 +1115,55 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat,
|
||||||
params.TexTop = float(targetRect.top) / g_renderer->GetTargetHeight();
|
params.TexTop = float(targetRect.top) / g_renderer->GetTargetHeight();
|
||||||
params.TexRight = float(targetRect.right) / g_renderer->GetTargetWidth();
|
params.TexRight = float(targetRect.right) / g_renderer->GetTargetWidth();
|
||||||
params.TexBottom = float(targetRect.bottom) / g_renderer->GetTargetHeight();
|
params.TexBottom = float(targetRect.bottom) / g_renderer->GetTargetHeight();
|
||||||
D3D::g_context->UpdateSubresource(m_encodeParams, 0, NULL, ¶ms, 0, 0);
|
D3D::context->UpdateSubresource(m_encodeParams, 0, NULL, ¶ms, 0, 0);
|
||||||
|
|
||||||
D3D::g_context->VSSetConstantBuffers(0, 1, &m_encodeParams);
|
D3D::context->VSSetConstantBuffers(0, 1, &m_encodeParams);
|
||||||
|
|
||||||
D3D::g_context->OMSetRenderTargets(1, &m_outRTV, NULL);
|
D3D::context->OMSetRenderTargets(1, &m_outRTV, NULL);
|
||||||
|
|
||||||
ID3D11ShaderResourceView* pEFB = (srcFormat == PIXELFMT_Z24) ?
|
ID3D11ShaderResourceView* pEFB = (srcFormat == PIXELFMT_Z24) ?
|
||||||
FramebufferManager::GetEFBDepthTexture()->GetSRV() :
|
FramebufferManager::GetEFBDepthTexture()->GetSRV() :
|
||||||
// FIXME: Instead of resolving EFB, it would be better to pick out a
|
// FIXME: Instead of resolving EFB, it would be better to pick out a
|
||||||
// single sample from each pixel. The game may break if it isn't
|
// single sample from each pixel. The game may break if it isn't
|
||||||
// expecting the blurred edges around multisampled shapes.
|
// expecting the blurred edges around multisampled shapes.
|
||||||
FramebufferManager::GetResolvedEFBColorTexture()->GetSRV();
|
FramebufferManager::GetResolvedEFBColorTexture()->GetSRV();
|
||||||
|
|
||||||
D3D::g_context->PSSetConstantBuffers(0, 1, &m_encodeParams);
|
D3D::context->PSSetConstantBuffers(0, 1, &m_encodeParams);
|
||||||
D3D::g_context->PSSetShaderResources(0, 1, &pEFB);
|
D3D::context->PSSetShaderResources(0, 1, &pEFB);
|
||||||
D3D::g_context->PSSetSamplers(0, 1, &m_efbSampler);
|
D3D::context->PSSetSamplers(0, 1, &m_efbSampler);
|
||||||
|
|
||||||
// Encode!
|
// Encode!
|
||||||
|
|
||||||
D3D::g_context->Draw(4, 0);
|
D3D::context->Draw(4, 0);
|
||||||
|
|
||||||
// Copy to staging buffer
|
// Copy to staging buffer
|
||||||
|
|
||||||
D3D11_BOX srcBox = CD3D11_BOX(0, 0, 0, cacheLinesPerRow*2, numBlocksY, 1);
|
D3D11_BOX srcBox = CD3D11_BOX(0, 0, 0, cacheLinesPerRow*2, numBlocksY, 1);
|
||||||
D3D::g_context->CopySubresourceRegion(m_outStage, 0, 0, 0, 0, m_out, 0, &srcBox);
|
D3D::context->CopySubresourceRegion(m_outStage, 0, 0, 0, 0, m_out, 0, &srcBox);
|
||||||
|
|
||||||
// Clean up state
|
// Clean up state
|
||||||
|
|
||||||
IUnknown* nullDummy = NULL;
|
IUnknown* nullDummy = NULL;
|
||||||
|
|
||||||
D3D::g_context->PSSetSamplers(0, 1, (ID3D11SamplerState**)&nullDummy);
|
D3D::context->PSSetSamplers(0, 1, (ID3D11SamplerState**)&nullDummy);
|
||||||
D3D::g_context->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&nullDummy);
|
D3D::context->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&nullDummy);
|
||||||
D3D::g_context->PSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy);
|
D3D::context->PSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy);
|
||||||
|
|
||||||
D3D::g_context->OMSetRenderTargets(0, NULL, NULL);
|
D3D::context->OMSetRenderTargets(0, NULL, NULL);
|
||||||
|
|
||||||
D3D::g_context->VSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy);
|
D3D::context->VSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy);
|
||||||
|
|
||||||
D3D::stateman->PopRasterizerState();
|
D3D::stateman->PopRasterizerState();
|
||||||
D3D::stateman->PopDepthState();
|
D3D::stateman->PopDepthState();
|
||||||
D3D::stateman->PopBlendState();
|
D3D::stateman->PopBlendState();
|
||||||
|
|
||||||
D3D::g_context->PSSetShader(NULL, NULL, 0);
|
D3D::context->PSSetShader(NULL, NULL, 0);
|
||||||
D3D::g_context->VSSetShader(NULL, NULL, 0);
|
D3D::context->VSSetShader(NULL, NULL, 0);
|
||||||
|
|
||||||
// Transfer staging buffer to GameCube/Wii RAM
|
// Transfer staging buffer to GameCube/Wii RAM
|
||||||
|
|
||||||
D3D11_MAPPED_SUBRESOURCE map = { 0 };
|
D3D11_MAPPED_SUBRESOURCE map = { 0 };
|
||||||
hr = D3D::g_context->Map(m_outStage, 0, D3D11_MAP_READ, 0, &map);
|
hr = D3D::context->Map(m_outStage, 0, D3D11_MAP_READ, 0, &map);
|
||||||
CHECK(SUCCEEDED(hr), "map staging buffer");
|
CHECK(SUCCEEDED(hr), "map staging buffer");
|
||||||
|
|
||||||
u8* src = (u8*)map.pData;
|
u8* src = (u8*)map.pData;
|
||||||
|
@ -1143,7 +1174,7 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat,
|
||||||
src += map.RowPitch;
|
src += map.RowPitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D::g_context->Unmap(m_outStage, 0);
|
D3D::context->Unmap(m_outStage, 0);
|
||||||
|
|
||||||
encodeSize = bpmem.copyMipMapStrideChannels*32 * numBlocksY;
|
encodeSize = bpmem.copyMipMapStrideChannels*32 * numBlocksY;
|
||||||
}
|
}
|
||||||
|
@ -1151,7 +1182,8 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat,
|
||||||
// Restore API
|
// Restore API
|
||||||
|
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(),
|
D3D::context->OMSetRenderTargets(1,
|
||||||
|
&FramebufferManager::GetEFBColorTexture()->GetRTV(),
|
||||||
FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
|
|
||||||
return encodeSize;
|
return encodeSize;
|
||||||
|
@ -1206,15 +1238,15 @@ bool PSTextureEncoder::SetStaticShader(unsigned int dstFormat, unsigned int srcF
|
||||||
case 0xC: generatorFuncName = "Generate_C"; break;
|
case 0xC: generatorFuncName = "Generate_C"; break;
|
||||||
default:
|
default:
|
||||||
WARN_LOG(VIDEO, "No generator available for dst format 0x%X; aborting", generatorNum);
|
WARN_LOG(VIDEO, "No generator available for dst format 0x%X; aborting", generatorNum);
|
||||||
m_staticShaders[key].reset();
|
m_staticShaders[key] = NULL;
|
||||||
return false;
|
return false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INFO_LOG(VIDEO, "Compiling efb encoding shader for dstFormat 0x%X, srcFormat %d, isIntensity %d, scaleByHalf %d",
|
INFO_LOG(VIDEO, "Compiling efb encoding shader for dstFormat 0x%X, srcFormat %d, isIntensity %d, scaleByHalf %d",
|
||||||
dstFormat, srcFormat, isIntensity ? 1 : 0, scaleByHalf ? 1 : 0);
|
dstFormat, srcFormat, isIntensity ? 1 : 0, scaleByHalf ? 1 : 0);
|
||||||
|
|
||||||
// Shader permutation not found, so compile it
|
// Shader permutation not found, so compile it
|
||||||
|
D3DBlob* bytecode = NULL;
|
||||||
D3D_SHADER_MACRO macros[] = {
|
D3D_SHADER_MACRO macros[] = {
|
||||||
{ "IMP_FETCH", FETCH_FUNC_NAMES[fetchNum] },
|
{ "IMP_FETCH", FETCH_FUNC_NAMES[fetchNum] },
|
||||||
{ "IMP_SCALEDFETCH", SCALEDFETCH_FUNC_NAMES[scaledFetchNum] },
|
{ "IMP_SCALEDFETCH", SCALEDFETCH_FUNC_NAMES[scaledFetchNum] },
|
||||||
|
@ -1222,30 +1254,29 @@ bool PSTextureEncoder::SetStaticShader(unsigned int dstFormat, unsigned int srcF
|
||||||
{ "IMP_GENERATOR", generatorFuncName },
|
{ "IMP_GENERATOR", generatorFuncName },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
if (!D3D::CompilePixelShader(EFB_ENCODE_PS, sizeof(EFB_ENCODE_PS), &bytecode, macros))
|
||||||
auto const bytecode = D3D::CompilePixelShader(EFB_ENCODE_PS, sizeof(EFB_ENCODE_PS), macros);
|
|
||||||
if (!bytecode)
|
|
||||||
{
|
{
|
||||||
WARN_LOG(VIDEO, "EFB encoder shader for dstFormat 0x%X, srcFormat %d, isIntensity %d, scaleByHalf %d failed to compile",
|
WARN_LOG(VIDEO, "EFB encoder shader for dstFormat 0x%X, srcFormat %d, isIntensity %d, scaleByHalf %d failed to compile",
|
||||||
dstFormat, srcFormat, isIntensity ? 1 : 0, scaleByHalf ? 1 : 0);
|
dstFormat, srcFormat, isIntensity ? 1 : 0, scaleByHalf ? 1 : 0);
|
||||||
// Add dummy shader to map to prevent trying to compile over and
|
// Add dummy shader to map to prevent trying to compile over and
|
||||||
// over again
|
// over again
|
||||||
m_staticShaders[key].reset();
|
m_staticShaders[key] = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11PixelShader* newShader = nullptr;
|
ID3D11PixelShader* newShader;
|
||||||
HRESULT hr = D3D::g_device->CreatePixelShader(bytecode->GetBufferPointer(), bytecode->GetBufferSize(), NULL, &newShader);
|
HRESULT hr = D3D::device->CreatePixelShader(bytecode->Data(), bytecode->Size(), NULL, &newShader);
|
||||||
CHECK(SUCCEEDED(hr), "create efb encoder pixel shader");
|
CHECK(SUCCEEDED(hr), "create efb encoder pixel shader");
|
||||||
|
|
||||||
it = m_staticShaders.insert(std::make_pair(key, SharedPtr<ID3D11PixelShader>::FromPtr(newShader))).first;
|
it = m_staticShaders.insert(std::make_pair(key, newShader)).first;
|
||||||
|
bytecode->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it != m_staticShaders.end())
|
if (it != m_staticShaders.end())
|
||||||
{
|
{
|
||||||
if (it->second)
|
if (it->second)
|
||||||
{
|
{
|
||||||
D3D::g_context->PSSetShader(it->second, NULL, 0);
|
D3D::context->PSSetShader(it->second, NULL, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1257,24 +1288,32 @@ bool PSTextureEncoder::SetStaticShader(unsigned int dstFormat, unsigned int srcF
|
||||||
|
|
||||||
bool PSTextureEncoder::InitDynamicMode()
|
bool PSTextureEncoder::InitDynamicMode()
|
||||||
{
|
{
|
||||||
const D3D_SHADER_MACRO macros[] = {
|
HRESULT hr;
|
||||||
|
|
||||||
|
D3D_SHADER_MACRO macros[] = {
|
||||||
{ "DYNAMIC_MODE", NULL },
|
{ "DYNAMIC_MODE", NULL },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT hr = D3D::g_device->CreateClassLinkage(&m_classLinkage);
|
D3DBlob* bytecode = NULL;
|
||||||
|
if (!D3D::CompilePixelShader(EFB_ENCODE_PS, sizeof(EFB_ENCODE_PS), &bytecode, macros))
|
||||||
|
{
|
||||||
|
ERROR_LOG(VIDEO, "EFB encode pixel shader failed to compile");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = D3D::device->CreateClassLinkage(&m_classLinkage);
|
||||||
CHECK(SUCCEEDED(hr), "create efb encode class linkage");
|
CHECK(SUCCEEDED(hr), "create efb encode class linkage");
|
||||||
D3D::SetDebugObjectName(m_classLinkage, "efb encoder class linkage");
|
D3D::SetDebugObjectName(m_classLinkage, "efb encoder class linkage");
|
||||||
|
|
||||||
SharedPtr<ID3D10Blob> bytecode;
|
hr = D3D::device->CreatePixelShader(bytecode->Data(), bytecode->Size(), m_classLinkage, &m_dynamicShader);
|
||||||
m_dynamicShader = D3D::CompileAndCreatePixelShader(EFB_ENCODE_PS, sizeof(EFB_ENCODE_PS), macros, std::addressof(bytecode));
|
CHECK(SUCCEEDED(hr), "create efb encode pixel shader");
|
||||||
CHECK(m_dynamicShader, "compile/create efb encode pixel shader");
|
|
||||||
D3D::SetDebugObjectName(m_dynamicShader, "efb encoder pixel shader");
|
D3D::SetDebugObjectName(m_dynamicShader, "efb encoder pixel shader");
|
||||||
|
|
||||||
// Use D3DReflect
|
// Use D3DReflect
|
||||||
|
|
||||||
ID3D11ShaderReflection* reflect = NULL;
|
ID3D11ShaderReflection* reflect = NULL;
|
||||||
hr = PD3DReflect(bytecode->GetBufferPointer(), bytecode->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&reflect);
|
hr = PD3DReflect(bytecode->Data(), bytecode->Size(), IID_ID3D11ShaderReflection, (void**)&reflect);
|
||||||
CHECK(SUCCEEDED(hr), "reflect on efb encoder shader");
|
CHECK(SUCCEEDED(hr), "reflect on efb encoder shader");
|
||||||
|
|
||||||
// Get number of slots and create dynamic linkage array
|
// Get number of slots and create dynamic linkage array
|
||||||
|
@ -1311,6 +1350,7 @@ bool PSTextureEncoder::InitDynamicMode()
|
||||||
m_generatorClass[i] = NULL;
|
m_generatorClass[i] = NULL;
|
||||||
|
|
||||||
reflect->Release();
|
reflect->Release();
|
||||||
|
bytecode->Release();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1348,7 +1388,6 @@ bool PSTextureEncoder::SetDynamicShader(unsigned int dstFormat,
|
||||||
default:
|
default:
|
||||||
WARN_LOG(VIDEO, "No generator available for dst format 0x%X; aborting", generatorNum);
|
WARN_LOG(VIDEO, "No generator available for dst format 0x%X; aborting", generatorNum);
|
||||||
return false;
|
return false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure class instances are available
|
// Make sure class instances are available
|
||||||
|
@ -1397,7 +1436,7 @@ bool PSTextureEncoder::SetDynamicShader(unsigned int dstFormat,
|
||||||
if (m_generatorSlot != UINT(-1))
|
if (m_generatorSlot != UINT(-1))
|
||||||
m_linkageArray[m_generatorSlot] = m_generatorClass[generatorNum];
|
m_linkageArray[m_generatorSlot] = m_generatorClass[generatorNum];
|
||||||
|
|
||||||
D3D::g_context->PSSetShader(m_dynamicShader,
|
D3D::context->PSSetShader(m_dynamicShader,
|
||||||
m_linkageArray.empty() ? NULL : &m_linkageArray[0],
|
m_linkageArray.empty() ? NULL : &m_linkageArray[0],
|
||||||
(UINT)m_linkageArray.size());
|
(UINT)m_linkageArray.size());
|
||||||
|
|
||||||
|
|
|
@ -19,32 +19,48 @@
|
||||||
#define _PSTEXTUREENCODER_H
|
#define _PSTEXTUREENCODER_H
|
||||||
|
|
||||||
#include "TextureEncoder.h"
|
#include "TextureEncoder.h"
|
||||||
#include "D3DUtil.h"
|
|
||||||
|
struct ID3D11Texture2D;
|
||||||
|
struct ID3D11RenderTargetView;
|
||||||
|
struct ID3D11Buffer;
|
||||||
|
struct ID3D11InputLayout;
|
||||||
|
struct ID3D11VertexShader;
|
||||||
|
struct ID3D11PixelShader;
|
||||||
|
struct ID3D11ClassLinkage;
|
||||||
|
struct ID3D11ClassInstance;
|
||||||
|
struct ID3D11BlendState;
|
||||||
|
struct ID3D11DepthStencilState;
|
||||||
|
struct ID3D11RasterizerState;
|
||||||
|
struct ID3D11SamplerState;
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
class PSTextureEncoder : public TextureEncoder
|
class PSTextureEncoder : public TextureEncoder
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
PSTextureEncoder();
|
|
||||||
~PSTextureEncoder();
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
PSTextureEncoder();
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void Shutdown();
|
||||||
size_t Encode(u8* dst, unsigned int dstFormat,
|
size_t Encode(u8* dst, unsigned int dstFormat,
|
||||||
unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity,
|
unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity,
|
||||||
bool scaleByHalf);
|
bool scaleByHalf);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool m_ready;
|
bool m_ready;
|
||||||
|
|
||||||
SharedPtr<ID3D11Texture2D> m_out;
|
ID3D11Texture2D* m_out;
|
||||||
ID3D11RenderTargetView* m_outRTV;
|
ID3D11RenderTargetView* m_outRTV;
|
||||||
SharedPtr<ID3D11Texture2D> m_outStage;
|
ID3D11Texture2D* m_outStage;
|
||||||
SharedPtr<ID3D11Buffer> m_encodeParams;
|
ID3D11Buffer* m_encodeParams;
|
||||||
SharedPtr<ID3D11Buffer> m_quad;
|
ID3D11Buffer* m_quad;
|
||||||
SharedPtr<ID3D11VertexShader> m_vShader;
|
ID3D11VertexShader* m_vShader;
|
||||||
SharedPtr<ID3D11InputLayout> m_quadLayout;
|
ID3D11InputLayout* m_quadLayout;
|
||||||
SharedPtr<ID3D11BlendState> m_efbEncodeBlendState;
|
ID3D11BlendState* m_efbEncodeBlendState;
|
||||||
ID3D11DepthStencilState* m_efbEncodeDepthState;
|
ID3D11DepthStencilState* m_efbEncodeDepthState;
|
||||||
ID3D11RasterizerState* m_efbEncodeRastState;
|
ID3D11RasterizerState* m_efbEncodeRastState;
|
||||||
ID3D11SamplerState* m_efbSampler;
|
ID3D11SamplerState* m_efbSampler;
|
||||||
|
@ -64,7 +80,7 @@ private:
|
||||||
| (scaleByHalf ? (1<<0) : 0);
|
| (scaleByHalf ? (1<<0) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::map<ComboKey, SharedPtr<ID3D11PixelShader>> ComboMap;
|
typedef std::map<ComboKey, ID3D11PixelShader*> ComboMap;
|
||||||
|
|
||||||
ComboMap m_staticShaders;
|
ComboMap m_staticShaders;
|
||||||
|
|
||||||
|
@ -75,7 +91,7 @@ private:
|
||||||
bool SetDynamicShader(unsigned int dstFormat, unsigned int srcFormat,
|
bool SetDynamicShader(unsigned int dstFormat, unsigned int srcFormat,
|
||||||
bool isIntensity, bool scaleByHalf);
|
bool isIntensity, bool scaleByHalf);
|
||||||
|
|
||||||
SharedPtr<ID3D11PixelShader> m_dynamicShader;
|
ID3D11PixelShader* m_dynamicShader;
|
||||||
ID3D11ClassLinkage* m_classLinkage;
|
ID3D11ClassLinkage* m_classLinkage;
|
||||||
|
|
||||||
// Interface slots
|
// Interface slots
|
||||||
|
@ -95,6 +111,7 @@ private:
|
||||||
ID3D11ClassInstance* m_generatorClass[16];
|
ID3D11ClassInstance* m_generatorClass[16];
|
||||||
|
|
||||||
std::vector<ID3D11ClassInstance*> m_linkageArray;
|
std::vector<ID3D11ClassInstance*> m_linkageArray;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,14 +44,13 @@ const PixelShaderCache::PSCacheEntry* PixelShaderCache::last_entry;
|
||||||
|
|
||||||
LinearDiskCache<PIXELSHADERUID, u8> g_ps_disk_cache;
|
LinearDiskCache<PIXELSHADERUID, u8> g_ps_disk_cache;
|
||||||
|
|
||||||
SharedPtr<ID3D11PixelShader> s_ColorMatrixProgram[2];
|
ID3D11PixelShader* s_ColorMatrixProgram[2] = {NULL};
|
||||||
SharedPtr<ID3D11PixelShader> s_ColorCopyProgram[2];
|
ID3D11PixelShader* s_ColorCopyProgram[2] = {NULL};
|
||||||
SharedPtr<ID3D11PixelShader> s_DepthMatrixProgram[2];
|
ID3D11PixelShader* s_DepthMatrixProgram[2] = {NULL};
|
||||||
SharedPtr<ID3D11PixelShader> s_ClearProgram;
|
ID3D11PixelShader* s_ClearProgram = NULL;
|
||||||
SharedPtr<ID3D11PixelShader> s_rgba6_to_rgb8[2];
|
ID3D11PixelShader* s_rgba6_to_rgb8[2] = {NULL};
|
||||||
SharedPtr<ID3D11PixelShader> s_rgb8_to_rgba6[2];
|
ID3D11PixelShader* s_rgb8_to_rgba6[2] = {NULL};
|
||||||
|
ID3D11Buffer* pscbuf = NULL;
|
||||||
SharedPtr<ID3D11Buffer> pscbuf;
|
|
||||||
|
|
||||||
const char clear_program_code[] = {
|
const char clear_program_code[] = {
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
|
@ -243,7 +242,6 @@ const char reint_rgb8_to_rgba6_msaa[] = {
|
||||||
"}\n"
|
"}\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
ID3D11PixelShader* PixelShaderCache::ReinterpRGBA6ToRGB8(bool multisampled)
|
ID3D11PixelShader* PixelShaderCache::ReinterpRGBA6ToRGB8(bool multisampled)
|
||||||
{
|
{
|
||||||
if (!multisampled || D3D::GetAAMode(g_ActiveConfig.iMultisampleMode).Count == 1)
|
if (!multisampled || D3D::GetAAMode(g_ActiveConfig.iMultisampleMode).Count == 1)
|
||||||
|
@ -298,65 +296,50 @@ ID3D11PixelShader* PixelShaderCache::ReinterpRGB8ToRGBA6(bool multisampled)
|
||||||
|
|
||||||
ID3D11PixelShader* PixelShaderCache::GetColorCopyProgram(bool multisampled)
|
ID3D11PixelShader* PixelShaderCache::GetColorCopyProgram(bool multisampled)
|
||||||
{
|
{
|
||||||
if (!multisampled || D3D::GetAAMode(g_ActiveConfig.iMultisampleMode).Count == 1)
|
if (!multisampled || D3D::GetAAMode(g_ActiveConfig.iMultisampleMode).Count == 1) return s_ColorCopyProgram[0];
|
||||||
{
|
else if (s_ColorCopyProgram[1]) return s_ColorCopyProgram[1];
|
||||||
return s_ColorCopyProgram[0];
|
else
|
||||||
}
|
|
||||||
else if (!s_ColorCopyProgram[1])
|
|
||||||
{
|
{
|
||||||
// create MSAA shader for current AA mode
|
// create MSAA shader for current AA mode
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
const int l = sprintf_s(buf, 1024, color_copy_program_code_msaa, D3D::GetAAMode(g_ActiveConfig.iMultisampleMode));
|
int l = sprintf_s(buf, 1024, color_copy_program_code_msaa, D3D::GetAAMode(g_ActiveConfig.iMultisampleMode));
|
||||||
|
|
||||||
s_ColorCopyProgram[1] = D3D::CompileAndCreatePixelShader(buf, l);
|
s_ColorCopyProgram[1] = D3D::CompileAndCreatePixelShader(buf, l);
|
||||||
|
CHECK(s_ColorCopyProgram[1]!=NULL, "Create color copy MSAA pixel shader");
|
||||||
CHECK(s_ColorCopyProgram[1], "Create color copy MSAA pixel shader");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorCopyProgram[1], "color copy MSAA pixel shader");
|
||||||
D3D::SetDebugObjectName(s_ColorCopyProgram[1], "color copy MSAA pixel shader");
|
return s_ColorCopyProgram[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return s_ColorCopyProgram[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11PixelShader* PixelShaderCache::GetColorMatrixProgram(bool multisampled)
|
ID3D11PixelShader* PixelShaderCache::GetColorMatrixProgram(bool multisampled)
|
||||||
{
|
{
|
||||||
if (!multisampled || D3D::GetAAMode(g_ActiveConfig.iMultisampleMode).Count == 1)
|
if (!multisampled || D3D::GetAAMode(g_ActiveConfig.iMultisampleMode).Count == 1) return s_ColorMatrixProgram[0];
|
||||||
{
|
else if (s_ColorMatrixProgram[1]) return s_ColorMatrixProgram[1];
|
||||||
return s_ColorMatrixProgram[0];
|
else
|
||||||
}
|
|
||||||
else if (!s_ColorMatrixProgram[1])
|
|
||||||
{
|
{
|
||||||
// create MSAA shader for current AA mode
|
// create MSAA shader for current AA mode
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
const int l = sprintf_s(buf, 1024, color_matrix_program_code_msaa, D3D::GetAAMode(g_ActiveConfig.iMultisampleMode));
|
int l = sprintf_s(buf, 1024, color_matrix_program_code_msaa, D3D::GetAAMode(g_ActiveConfig.iMultisampleMode));
|
||||||
|
|
||||||
s_ColorMatrixProgram[1] = D3D::CompileAndCreatePixelShader(buf, l);
|
s_ColorMatrixProgram[1] = D3D::CompileAndCreatePixelShader(buf, l);
|
||||||
|
CHECK(s_ColorMatrixProgram[1]!=NULL, "Create color matrix MSAA pixel shader");
|
||||||
CHECK(s_ColorMatrixProgram[1], "Create color matrix MSAA pixel shader");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorMatrixProgram[1], "color matrix MSAA pixel shader");
|
||||||
D3D::SetDebugObjectName(s_ColorMatrixProgram[1], "color matrix MSAA pixel shader");
|
return s_ColorMatrixProgram[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return s_ColorMatrixProgram[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11PixelShader* PixelShaderCache::GetDepthMatrixProgram(bool multisampled)
|
ID3D11PixelShader* PixelShaderCache::GetDepthMatrixProgram(bool multisampled)
|
||||||
{
|
{
|
||||||
if (!multisampled || D3D::GetAAMode(g_ActiveConfig.iMultisampleMode).Count == 1)
|
if (!multisampled || D3D::GetAAMode(g_ActiveConfig.iMultisampleMode).Count == 1) return s_DepthMatrixProgram[0];
|
||||||
{
|
else if (s_DepthMatrixProgram[1]) return s_DepthMatrixProgram[1];
|
||||||
return s_DepthMatrixProgram[0];
|
else
|
||||||
}
|
|
||||||
else if (!s_DepthMatrixProgram[1])
|
|
||||||
{
|
{
|
||||||
// create MSAA shader for current AA mode
|
// create MSAA shader for current AA mode
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
const int l = sprintf_s(buf, 1024, depth_matrix_program_msaa, D3D::GetAAMode(g_ActiveConfig.iMultisampleMode));
|
int l = sprintf_s(buf, 1024, depth_matrix_program_msaa, D3D::GetAAMode(g_ActiveConfig.iMultisampleMode));
|
||||||
|
|
||||||
s_DepthMatrixProgram[1] = D3D::CompileAndCreatePixelShader(buf, l);
|
s_DepthMatrixProgram[1] = D3D::CompileAndCreatePixelShader(buf, l);
|
||||||
|
CHECK(s_DepthMatrixProgram[1]!=NULL, "Create depth matrix MSAA pixel shader");
|
||||||
CHECK(s_DepthMatrixProgram[1], "Create depth matrix MSAA pixel shader");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_DepthMatrixProgram[1], "depth matrix MSAA pixel shader");
|
||||||
D3D::SetDebugObjectName(s_DepthMatrixProgram[1], "depth matrix MSAA pixel shader");
|
return s_DepthMatrixProgram[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return s_DepthMatrixProgram[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11PixelShader* PixelShaderCache::GetClearProgram()
|
ID3D11PixelShader* PixelShaderCache::GetClearProgram()
|
||||||
|
@ -364,31 +347,27 @@ ID3D11PixelShader* PixelShaderCache::GetClearProgram()
|
||||||
return s_ClearProgram;
|
return s_ClearProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11Buffer*const& PixelShaderCache::GetConstantBuffer()
|
ID3D11Buffer* &PixelShaderCache::GetConstantBuffer()
|
||||||
{
|
{
|
||||||
// TODO: divide the global variables of the generated shaders into about 5 constant buffers to speed this up
|
// TODO: divide the global variables of the generated shaders into about 5 constant buffers to speed this up
|
||||||
if (pscbufchanged)
|
if (pscbufchanged)
|
||||||
{
|
{
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
D3D::g_context->Map(pscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
D3D::context->Map(pscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
memcpy(map.pData, psconstants, sizeof(psconstants));
|
memcpy(map.pData, psconstants, sizeof(psconstants));
|
||||||
D3D::g_context->Unmap(pscbuf, 0);
|
D3D::context->Unmap(pscbuf, 0);
|
||||||
pscbufchanged = false;
|
pscbufchanged = false;
|
||||||
}
|
}
|
||||||
return pscbuf;
|
return pscbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this class will load the precompiled shaders into our cache
|
// this class will load the precompiled shaders into our cache
|
||||||
class PixelShaderCacheInserter
|
class PixelShaderCacheInserter : public LinearDiskCacheReader<PIXELSHADERUID, u8>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <typename F>
|
void Read(const PIXELSHADERUID &key, const u8 *value, u32 value_size)
|
||||||
void operator()(const PIXELSHADERUID& key, u32 value_size, F get_data) const
|
|
||||||
{
|
{
|
||||||
std::unique_ptr<u8[]> value(new u8[value_size]);
|
PixelShaderCache::InsertByteCode(key, value, value_size);
|
||||||
get_data(value.get());
|
|
||||||
|
|
||||||
PixelShaderCache::InsertByteCode(key, value.get(), value_size);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -396,29 +375,29 @@ void PixelShaderCache::Init()
|
||||||
{
|
{
|
||||||
unsigned int cbsize = ((sizeof(psconstants))&(~0xf))+0x10; // must be a multiple of 16
|
unsigned int cbsize = ((sizeof(psconstants))&(~0xf))+0x10; // must be a multiple of 16
|
||||||
D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||||
pscbuf = CreateBufferShared(&cbdesc, NULL);
|
D3D::device->CreateBuffer(&cbdesc, NULL, &pscbuf);
|
||||||
CHECK(pscbuf, "Create pixel shader constant buffer");
|
CHECK(pscbuf!=NULL, "Create pixel shader constant buffer");
|
||||||
D3D::SetDebugObjectName(pscbuf, "pixel shader constant buffer used to emulate the GX pipeline");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)pscbuf, "pixel shader constant buffer used to emulate the GX pipeline");
|
||||||
|
|
||||||
// used when drawing clear quads
|
// used when drawing clear quads
|
||||||
s_ClearProgram = D3D::CompileAndCreatePixelShader(clear_program_code, sizeof(clear_program_code));
|
s_ClearProgram = D3D::CompileAndCreatePixelShader(clear_program_code, sizeof(clear_program_code));
|
||||||
CHECK(s_ClearProgram, "Create clear pixel shader");
|
CHECK(s_ClearProgram!=NULL, "Create clear pixel shader");
|
||||||
D3D::SetDebugObjectName(s_ClearProgram, "clear pixel shader");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "clear pixel shader");
|
||||||
|
|
||||||
// used when copying/resolving the color buffer
|
// used when copying/resolving the color buffer
|
||||||
s_ColorCopyProgram[0] = D3D::CompileAndCreatePixelShader(color_copy_program_code, sizeof(color_copy_program_code));
|
s_ColorCopyProgram[0] = D3D::CompileAndCreatePixelShader(color_copy_program_code, sizeof(color_copy_program_code));
|
||||||
CHECK(s_ColorCopyProgram[0], "Create color copy pixel shader");
|
CHECK(s_ColorCopyProgram[0]!=NULL, "Create color copy pixel shader");
|
||||||
D3D::SetDebugObjectName(s_ColorCopyProgram[0], "color copy pixel shader");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorCopyProgram[0], "color copy pixel shader");
|
||||||
|
|
||||||
// used for color conversion
|
// used for color conversion
|
||||||
s_ColorMatrixProgram[0] = D3D::CompileAndCreatePixelShader(color_matrix_program_code, sizeof(color_matrix_program_code));
|
s_ColorMatrixProgram[0] = D3D::CompileAndCreatePixelShader(color_matrix_program_code, sizeof(color_matrix_program_code));
|
||||||
CHECK(s_ColorMatrixProgram[0], "Create color matrix pixel shader");
|
CHECK(s_ColorMatrixProgram[0]!=NULL, "Create color matrix pixel shader");
|
||||||
D3D::SetDebugObjectName(s_ColorMatrixProgram[0], "color matrix pixel shader");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorMatrixProgram[0], "color matrix pixel shader");
|
||||||
|
|
||||||
// used for depth copy
|
// used for depth copy
|
||||||
s_DepthMatrixProgram[0] = D3D::CompileAndCreatePixelShader(depth_matrix_program, sizeof(depth_matrix_program));
|
s_DepthMatrixProgram[0] = D3D::CompileAndCreatePixelShader(depth_matrix_program, sizeof(depth_matrix_program));
|
||||||
CHECK(s_DepthMatrixProgram[0], "Create depth matrix pixel shader");
|
CHECK(s_DepthMatrixProgram[0]!=NULL, "Create depth matrix pixel shader");
|
||||||
D3D::SetDebugObjectName(s_DepthMatrixProgram[0], "depth matrix pixel shader");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_DepthMatrixProgram[0], "depth matrix pixel shader");
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
|
@ -430,39 +409,41 @@ void PixelShaderCache::Init()
|
||||||
|
|
||||||
char cache_filename[MAX_PATH];
|
char cache_filename[MAX_PATH];
|
||||||
sprintf(cache_filename, "%sdx11-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
|
sprintf(cache_filename, "%sdx11-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
|
||||||
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
||||||
|
PixelShaderCacheInserter inserter;
|
||||||
g_ps_disk_cache.OpenAndRead(cache_filename, PixelShaderCacheInserter());
|
g_ps_disk_cache.OpenAndRead(cache_filename, inserter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ONLY to be used during shutdown.
|
// ONLY to be used during shutdown.
|
||||||
void PixelShaderCache::Clear()
|
void PixelShaderCache::Clear()
|
||||||
{
|
{
|
||||||
|
for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++)
|
||||||
|
iter->second.Destroy();
|
||||||
PixelShaders.clear();
|
PixelShaders.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used in Swap() when AA mode has changed
|
// Used in Swap() when AA mode has changed
|
||||||
void PixelShaderCache::InvalidateMSAAShaders()
|
void PixelShaderCache::InvalidateMSAAShaders()
|
||||||
{
|
{
|
||||||
s_ColorCopyProgram[1].reset();
|
SAFE_RELEASE(s_ColorCopyProgram[1]);
|
||||||
s_ColorMatrixProgram[1].reset();
|
SAFE_RELEASE(s_ColorMatrixProgram[1]);
|
||||||
s_DepthMatrixProgram[1].reset();
|
SAFE_RELEASE(s_DepthMatrixProgram[1]);
|
||||||
s_rgb8_to_rgba6[1].reset();
|
SAFE_RELEASE(s_rgb8_to_rgba6[1]);
|
||||||
s_rgba6_to_rgb8[1].reset();
|
SAFE_RELEASE(s_rgba6_to_rgb8[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderCache::Shutdown()
|
void PixelShaderCache::Shutdown()
|
||||||
{
|
{
|
||||||
pscbuf.reset();
|
SAFE_RELEASE(pscbuf);
|
||||||
|
|
||||||
s_ClearProgram.reset();
|
SAFE_RELEASE(s_ClearProgram);
|
||||||
for (int i = 0; i < 2; ++i)
|
for (int i = 0; i < 2; ++i)
|
||||||
{
|
{
|
||||||
s_ColorCopyProgram[i].reset();
|
SAFE_RELEASE(s_ColorCopyProgram[i]);
|
||||||
s_ColorMatrixProgram[i].reset();
|
SAFE_RELEASE(s_ColorMatrixProgram[i]);
|
||||||
s_DepthMatrixProgram[i].reset();
|
SAFE_RELEASE(s_DepthMatrixProgram[i]);
|
||||||
s_rgba6_to_rgb8[i].reset();
|
SAFE_RELEASE(s_rgba6_to_rgb8[i]);
|
||||||
s_rgb8_to_rgba6[i].reset();
|
SAFE_RELEASE(s_rgb8_to_rgba6[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
|
@ -470,7 +451,7 @@ void PixelShaderCache::Shutdown()
|
||||||
g_ps_disk_cache.Close();
|
g_ps_disk_cache.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PixelShaderCache::LoadShader(DSTALPHA_MODE dstAlphaMode, u32 components)
|
bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
|
||||||
{
|
{
|
||||||
PIXELSHADERUID uid;
|
PIXELSHADERUID uid;
|
||||||
GetPixelShaderId(&uid, dstAlphaMode);
|
GetPixelShaderId(&uid, dstAlphaMode);
|
||||||
|
@ -495,14 +476,14 @@ bool PixelShaderCache::LoadShader(DSTALPHA_MODE dstAlphaMode, u32 components)
|
||||||
last_entry = &entry;
|
last_entry = &entry;
|
||||||
|
|
||||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true);
|
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true);
|
||||||
return (!!entry.shader);
|
return (entry.shader != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need to compile a new shader
|
// Need to compile a new shader
|
||||||
const char* code = GeneratePixelShaderCode(dstAlphaMode, API_D3D11, components);
|
const char* code = GeneratePixelShaderCode(dstAlphaMode, API_D3D11, components);
|
||||||
|
|
||||||
auto const pbytecode = D3D::CompilePixelShader(code, (unsigned int)strlen(code));
|
D3DBlob* pbytecode;
|
||||||
if (!pbytecode)
|
if (!D3D::CompilePixelShader(code, (unsigned int)strlen(code), &pbytecode))
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to compile Pixel Shader:\n\n%s", code);
|
PanicAlert("Failed to compile Pixel Shader:\n\n%s", code);
|
||||||
GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
|
GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
|
||||||
|
@ -510,25 +491,25 @@ bool PixelShaderCache::LoadShader(DSTALPHA_MODE dstAlphaMode, u32 components)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert the bytecode into the caches
|
// Insert the bytecode into the caches
|
||||||
g_ps_disk_cache.Append(uid, (u8*)pbytecode->GetBufferPointer(), (u32)pbytecode->GetBufferSize());
|
g_ps_disk_cache.Append(uid, pbytecode->Data(), pbytecode->Size());
|
||||||
g_ps_disk_cache.Sync();
|
g_ps_disk_cache.Sync();
|
||||||
|
|
||||||
bool result = InsertByteCode(uid, pbytecode->GetBufferPointer(), (u32)pbytecode->GetBufferSize());
|
bool result = InsertByteCode(uid, pbytecode->Data(), pbytecode->Size());
|
||||||
|
pbytecode->Release();
|
||||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
|
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const void* bytecode, unsigned int bytecodelen)
|
bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const void* bytecode, unsigned int bytecodelen)
|
||||||
{
|
{
|
||||||
auto const shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen);
|
ID3D11PixelShader* shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen);
|
||||||
if (!shader)
|
if (shader == NULL)
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to create pixel shader at %s %d\n", __FILE__, __LINE__);
|
PanicAlert("Failed to create pixel shader at %s %d\n", __FILE__, __LINE__);
|
||||||
// INCSTAT(stats.numPixelShadersFailed);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// TODO: Somehow make the debug name a bit more specific
|
// TODO: Somehow make the debug name a bit more specific
|
||||||
D3D::SetDebugObjectName(shader, "a pixel shader of PixelShaderCache");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a pixel shader of PixelShaderCache");
|
||||||
|
|
||||||
// Make an entry in the table
|
// Make an entry in the table
|
||||||
PSCacheEntry newentry;
|
PSCacheEntry newentry;
|
||||||
|
@ -537,6 +518,11 @@ bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const void* byt
|
||||||
PixelShaders[uid] = newentry;
|
PixelShaders[uid] = newentry;
|
||||||
last_entry = &PixelShaders[uid];
|
last_entry = &PixelShaders[uid];
|
||||||
|
|
||||||
|
if (!shader) {
|
||||||
|
// INCSTAT(stats.numPixelShadersFailed);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
INCSTAT(stats.numPixelShadersCreated);
|
INCSTAT(stats.numPixelShadersCreated);
|
||||||
SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
|
SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -33,12 +33,11 @@ public:
|
||||||
static void Init();
|
static void Init();
|
||||||
static void Clear();
|
static void Clear();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
static bool SetShader(DSTALPHA_MODE dstAlphaMode, u32 components); // TODO: Should be renamed to LoadShader
|
||||||
static bool LoadShader(DSTALPHA_MODE dstAlphaMode, u32 components);
|
|
||||||
static bool InsertByteCode(const PIXELSHADERUID &uid, const void* bytecode, unsigned int bytecodelen);
|
static bool InsertByteCode(const PIXELSHADERUID &uid, const void* bytecode, unsigned int bytecodelen);
|
||||||
|
|
||||||
static SharedPtr<ID3D11PixelShader> GetActiveShader() { return last_entry->shader; }
|
static ID3D11PixelShader* GetActiveShader() { return last_entry->shader; }
|
||||||
static ID3D11Buffer*const& GetConstantBuffer();
|
static ID3D11Buffer* &GetConstantBuffer();
|
||||||
|
|
||||||
static ID3D11PixelShader* GetColorMatrixProgram(bool multisampled);
|
static ID3D11PixelShader* GetColorMatrixProgram(bool multisampled);
|
||||||
static ID3D11PixelShader* GetColorCopyProgram(bool multisampled);
|
static ID3D11PixelShader* GetColorCopyProgram(bool multisampled);
|
||||||
|
@ -52,10 +51,11 @@ public:
|
||||||
private:
|
private:
|
||||||
struct PSCacheEntry
|
struct PSCacheEntry
|
||||||
{
|
{
|
||||||
SharedPtr<ID3D11PixelShader> shader;
|
ID3D11PixelShader* shader;
|
||||||
int frameCount;
|
int frameCount;
|
||||||
|
|
||||||
PSCacheEntry() : frameCount(0) {}
|
PSCacheEntry() : shader(NULL), frameCount(0) {}
|
||||||
|
void Destroy() { SAFE_RELEASE(shader); }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
|
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
|
||||||
|
|
|
@ -132,19 +132,39 @@ static const char POINT_GS_COMMON[] =
|
||||||
;
|
;
|
||||||
|
|
||||||
PointGeometryShader::PointGeometryShader()
|
PointGeometryShader::PointGeometryShader()
|
||||||
: m_ready(false)
|
: m_ready(false), m_paramsBuffer(NULL)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void PointGeometryShader::Init()
|
||||||
{
|
{
|
||||||
|
m_ready = false;
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
// Create constant buffer for uploading data to geometry shader
|
// Create constant buffer for uploading data to geometry shader
|
||||||
|
|
||||||
D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(PointGSParams_Padded),
|
D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(PointGSParams_Padded),
|
||||||
D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||||
m_paramsBuffer = CreateBufferShared(&bd, NULL);
|
hr = D3D::device->CreateBuffer(&bd, NULL, &m_paramsBuffer);
|
||||||
CHECK(m_paramsBuffer, "create point geometry shader params buffer");
|
CHECK(SUCCEEDED(hr), "create point geometry shader params buffer");
|
||||||
D3D::SetDebugObjectName(m_paramsBuffer, "point geometry shader params buffer");
|
D3D::SetDebugObjectName(m_paramsBuffer, "point geometry shader params buffer");
|
||||||
|
|
||||||
m_ready = true;
|
m_ready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PointGeometryShader::Shutdown()
|
||||||
|
{
|
||||||
|
m_ready = false;
|
||||||
|
|
||||||
|
for (ComboMap::iterator it = m_shaders.begin(); it != m_shaders.end(); ++it)
|
||||||
|
{
|
||||||
|
SAFE_RELEASE(it->second);
|
||||||
|
}
|
||||||
|
m_shaders.clear();
|
||||||
|
|
||||||
|
SAFE_RELEASE(m_paramsBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
bool PointGeometryShader::SetShader(u32 components, float pointSize,
|
bool PointGeometryShader::SetShader(u32 components, float pointSize,
|
||||||
float texOffset, float vpWidth, float vpHeight, const bool* texOffsetEnable)
|
float texOffset, float vpWidth, float vpHeight, const bool* texOffsetEnable)
|
||||||
{
|
{
|
||||||
|
@ -171,13 +191,12 @@ bool PointGeometryShader::SetShader(u32 components, float pointSize,
|
||||||
{ "NUM_TEXCOORDS", numTexCoordsStr.str().c_str() },
|
{ "NUM_TEXCOORDS", numTexCoordsStr.str().c_str() },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
ID3D11GeometryShader* newShader = D3D::CompileAndCreateGeometryShader(code, unsigned int(strlen(code)), macros);
|
||||||
auto const newShader = D3D::CompileAndCreateGeometryShader(code, unsigned int(strlen(code)), macros);
|
|
||||||
if (!newShader)
|
if (!newShader)
|
||||||
{
|
{
|
||||||
WARN_LOG(VIDEO, "Point geometry shader for components 0x%.08X failed to compile", components);
|
WARN_LOG(VIDEO, "Point geometry shader for components 0x%.08X failed to compile", components);
|
||||||
// Add dummy shader to prevent trying to compile again
|
// Add dummy shader to prevent trying to compile again
|
||||||
m_shaders[components].reset();
|
m_shaders[components] = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,27 +208,28 @@ bool PointGeometryShader::SetShader(u32 components, float pointSize,
|
||||||
if (shaderIt->second)
|
if (shaderIt->second)
|
||||||
{
|
{
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
HRESULT hr = D3D::g_context->Map(m_paramsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
HRESULT hr = D3D::context->Map(m_paramsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
PointGSParams* params = (PointGSParams*)map.pData;
|
PointGSParams* params = (PointGSParams*)map.pData;
|
||||||
params->PointSize = pointSize;
|
params->PointSize = pointSize;
|
||||||
|
|
||||||
params->TexOffset = texOffset;
|
params->TexOffset = texOffset;
|
||||||
params->VpWidth = vpWidth;
|
params->VpWidth = vpWidth;
|
||||||
params->VpHeight = vpHeight;
|
params->VpHeight = vpHeight;
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
params->TexOffsetEnable[i] = texOffsetEnable[i] ? 1.f : 0.f;
|
params->TexOffsetEnable[i] = texOffsetEnable[i] ? 1.f : 0.f;
|
||||||
|
|
||||||
D3D::g_context->Unmap(m_paramsBuffer, 0);
|
D3D::context->Unmap(m_paramsBuffer, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ERROR_LOG(VIDEO, "Failed to map point gs params buffer");
|
ERROR_LOG(VIDEO, "Failed to map point gs params buffer");
|
||||||
|
|
||||||
DEBUG_LOG(VIDEO, "Point params: size %f, texOffset %f, vpWidth %f, vpHeight %f",
|
DEBUG_LOG(VIDEO, "Point params: size %f, texOffset %f, vpWidth %f, vpHeight %f",
|
||||||
pointSize, texOffset, vpWidth, vpHeight);
|
pointSize, texOffset, vpWidth, vpHeight);
|
||||||
|
|
||||||
D3D::g_context->GSSetShader(shaderIt->second, NULL, 0);
|
D3D::context->GSSetShader(shaderIt->second, NULL, 0);
|
||||||
D3D::g_context->GSSetConstantBuffers(0, 1, &m_paramsBuffer);
|
D3D::context->GSSetConstantBuffers(0, 1, &m_paramsBuffer);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,9 @@
|
||||||
#define _POINTGEOMETRYSHADER_H
|
#define _POINTGEOMETRYSHADER_H
|
||||||
|
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
#include "D3DUtil.h"
|
|
||||||
|
struct ID3D11Buffer;
|
||||||
|
struct ID3D11GeometryShader;
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
@ -28,21 +30,27 @@ namespace DX11
|
||||||
// vertex format.
|
// vertex format.
|
||||||
class PointGeometryShader
|
class PointGeometryShader
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PointGeometryShader();
|
PointGeometryShader();
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void Shutdown();
|
||||||
// Returns true on success, false on failure
|
// Returns true on success, false on failure
|
||||||
bool SetShader(u32 components, float pointSize, float texOffset,
|
bool SetShader(u32 components, float pointSize, float texOffset,
|
||||||
float vpWidth, float vpHeight, const bool* texOffsetEnable);
|
float vpWidth, float vpHeight, const bool* texOffsetEnable);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool m_ready;
|
bool m_ready;
|
||||||
|
|
||||||
SharedPtr<ID3D11Buffer> m_paramsBuffer;
|
ID3D11Buffer* m_paramsBuffer;
|
||||||
|
|
||||||
typedef std::map<u32, SharedPtr<ID3D11GeometryShader>> ComboMap;
|
typedef std::map<u32, ID3D11GeometryShader*> ComboMap;
|
||||||
|
|
||||||
ComboMap m_shaders;
|
ComboMap m_shaders;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "VertexShaderCache.h"
|
#include "VertexShaderCache.h"
|
||||||
#include "Core.h"
|
#include "Core.h"
|
||||||
#include "OnFrame.h"
|
#include "OnFrame.h"
|
||||||
|
#include "Television.h"
|
||||||
#include "Host.h"
|
#include "Host.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
|
@ -51,10 +52,12 @@ static u32 s_LastAA = 0;
|
||||||
|
|
||||||
static u32 s_blendMode;
|
static u32 s_blendMode;
|
||||||
|
|
||||||
SharedPtr<ID3D11Buffer> access_efb_cbuf;
|
static Television s_television;
|
||||||
SharedPtr<ID3D11BlendState> clearblendstates[4];
|
|
||||||
|
ID3D11Buffer* access_efb_cbuf = NULL;
|
||||||
|
ID3D11BlendState* clearblendstates[4] = {NULL};
|
||||||
ID3D11DepthStencilState* cleardepthstates[3] = {NULL};
|
ID3D11DepthStencilState* cleardepthstates[3] = {NULL};
|
||||||
SharedPtr<ID3D11BlendState> resetblendstate;
|
ID3D11BlendState* resetblendstate = NULL;
|
||||||
ID3D11DepthStencilState* resetdepthstate = NULL;
|
ID3D11DepthStencilState* resetdepthstate = NULL;
|
||||||
ID3D11RasterizerState* resetraststate = NULL;
|
ID3D11RasterizerState* resetraststate = NULL;
|
||||||
|
|
||||||
|
@ -214,6 +217,8 @@ static const D3D11_TEXTURE_ADDRESS_MODE d3dClamps[4] =
|
||||||
|
|
||||||
void SetupDeviceObjects()
|
void SetupDeviceObjects()
|
||||||
{
|
{
|
||||||
|
s_television.Init();
|
||||||
|
|
||||||
g_framebuffer_manager = new FramebufferManager;
|
g_framebuffer_manager = new FramebufferManager;
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -222,9 +227,9 @@ void SetupDeviceObjects()
|
||||||
D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(20*sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT);
|
D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(20*sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT);
|
||||||
D3D11_SUBRESOURCE_DATA data;
|
D3D11_SUBRESOURCE_DATA data;
|
||||||
data.pSysMem = colmat;
|
data.pSysMem = colmat;
|
||||||
access_efb_cbuf = CreateBufferShared(&cbdesc, &data);
|
hr = D3D::device->CreateBuffer(&cbdesc, &data, &access_efb_cbuf);
|
||||||
CHECK(access_efb_cbuf, "Create constant buffer for Renderer::AccessEFB");
|
CHECK(hr==S_OK, "Create constant buffer for Renderer::AccessEFB");
|
||||||
D3D::SetDebugObjectName(access_efb_cbuf, "constant buffer for Renderer::AccessEFB");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)access_efb_cbuf, "constant buffer for Renderer::AccessEFB");
|
||||||
|
|
||||||
D3D11_DEPTH_STENCIL_DESC ddesc;
|
D3D11_DEPTH_STENCIL_DESC ddesc;
|
||||||
ddesc.DepthEnable = FALSE;
|
ddesc.DepthEnable = FALSE;
|
||||||
|
@ -233,18 +238,18 @@ void SetupDeviceObjects()
|
||||||
ddesc.StencilEnable = FALSE;
|
ddesc.StencilEnable = FALSE;
|
||||||
ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
||||||
ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
||||||
hr = D3D::g_device->CreateDepthStencilState(&ddesc, &cleardepthstates[0]);
|
hr = D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[0]);
|
||||||
CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen");
|
CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen");
|
||||||
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
||||||
ddesc.DepthEnable = TRUE;
|
ddesc.DepthEnable = TRUE;
|
||||||
hr = D3D::g_device->CreateDepthStencilState(&ddesc, &cleardepthstates[1]);
|
hr = D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[1]);
|
||||||
CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen");
|
CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen");
|
||||||
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
|
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
|
||||||
hr = D3D::g_device->CreateDepthStencilState(&ddesc, &cleardepthstates[2]);
|
hr = D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[2]);
|
||||||
CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen");
|
CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen");
|
||||||
D3D::SetDebugObjectName(cleardepthstates[0], "depth state for Renderer::ClearScreen (depth buffer disabled)");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)cleardepthstates[0], "depth state for Renderer::ClearScreen (depth buffer disabled)");
|
||||||
D3D::SetDebugObjectName(cleardepthstates[1], "depth state for Renderer::ClearScreen (depth buffer enabled, writing enabled)");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)cleardepthstates[1], "depth state for Renderer::ClearScreen (depth buffer enabled, writing enabled)");
|
||||||
D3D::SetDebugObjectName(cleardepthstates[2], "depth state for Renderer::ClearScreen (depth buffer enabled, writing disabled)");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)cleardepthstates[2], "depth state for Renderer::ClearScreen (depth buffer enabled, writing disabled)");
|
||||||
|
|
||||||
D3D11_BLEND_DESC blenddesc;
|
D3D11_BLEND_DESC blenddesc;
|
||||||
blenddesc.AlphaToCoverageEnable = FALSE;
|
blenddesc.AlphaToCoverageEnable = FALSE;
|
||||||
|
@ -257,23 +262,24 @@ void SetupDeviceObjects()
|
||||||
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
||||||
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
||||||
blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||||
resetblendstate = CreateBlendStateShared(&blenddesc);
|
hr = D3D::device->CreateBlendState(&blenddesc, &resetblendstate);
|
||||||
CHECK(resetblendstate, "Create blend state for Renderer::ResetAPIState");
|
CHECK(hr==S_OK, "Create blend state for Renderer::ResetAPIState");
|
||||||
D3D::SetDebugObjectName(resetblendstate, "blend state for Renderer::ResetAPIState");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)resetblendstate, "blend state for Renderer::ResetAPIState");
|
||||||
|
|
||||||
clearblendstates[0] = resetblendstate;
|
clearblendstates[0] = resetblendstate;
|
||||||
|
resetblendstate->AddRef();
|
||||||
|
|
||||||
blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_RED
|
blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_RED|D3D11_COLOR_WRITE_ENABLE_GREEN|D3D11_COLOR_WRITE_ENABLE_BLUE;
|
||||||
| D3D11_COLOR_WRITE_ENABLE_GREEN | D3D11_COLOR_WRITE_ENABLE_BLUE;
|
hr = D3D::device->CreateBlendState(&blenddesc, &clearblendstates[1]);
|
||||||
clearblendstates[1] = CreateBlendStateShared(&blenddesc);
|
CHECK(hr==S_OK, "Create blend state for Renderer::ClearScreen");
|
||||||
|
|
||||||
blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALPHA;
|
blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALPHA;
|
||||||
clearblendstates[2] = CreateBlendStateShared(&blenddesc);
|
hr = D3D::device->CreateBlendState(&blenddesc, &clearblendstates[2]);
|
||||||
|
CHECK(hr==S_OK, "Create blend state for Renderer::ClearScreen");
|
||||||
|
|
||||||
blenddesc.RenderTarget[0].RenderTargetWriteMask = 0;
|
blenddesc.RenderTarget[0].RenderTargetWriteMask = 0;
|
||||||
clearblendstates[3] = CreateBlendStateShared(&blenddesc);
|
hr = D3D::device->CreateBlendState(&blenddesc, &clearblendstates[3]);
|
||||||
|
CHECK(hr==S_OK, "Create blend state for Renderer::ClearScreen");
|
||||||
CHECK(clearblendstates[1] && clearblendstates[2] && clearblendstates[3], "Create blend state for Renderer::ClearScreen");
|
|
||||||
|
|
||||||
ddesc.DepthEnable = FALSE;
|
ddesc.DepthEnable = FALSE;
|
||||||
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
|
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
|
||||||
|
@ -281,14 +287,14 @@ void SetupDeviceObjects()
|
||||||
ddesc.StencilEnable = FALSE;
|
ddesc.StencilEnable = FALSE;
|
||||||
ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
||||||
ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
||||||
hr = D3D::g_device->CreateDepthStencilState(&ddesc, &resetdepthstate);
|
hr = D3D::device->CreateDepthStencilState(&ddesc, &resetdepthstate);
|
||||||
CHECK(hr==S_OK, "Create depth state for Renderer::ResetAPIState");
|
CHECK(hr==S_OK, "Create depth state for Renderer::ResetAPIState");
|
||||||
D3D::SetDebugObjectName(resetdepthstate, "depth stencil state for Renderer::ResetAPIState");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)resetdepthstate, "depth stencil state for Renderer::ResetAPIState");
|
||||||
|
|
||||||
D3D11_RASTERIZER_DESC rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0.f, false, false, false, false);
|
D3D11_RASTERIZER_DESC rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0.f, false, false, false, false);
|
||||||
hr = D3D::g_device->CreateRasterizerState(&rastdesc, &resetraststate);
|
hr = D3D::device->CreateRasterizerState(&rastdesc, &resetraststate);
|
||||||
CHECK(hr==S_OK, "Create rasterizer state for Renderer::ResetAPIState");
|
CHECK(hr==S_OK, "Create rasterizer state for Renderer::ResetAPIState");
|
||||||
D3D::SetDebugObjectName(resetraststate, "rasterizer state for Renderer::ResetAPIState");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)resetraststate, "rasterizer state for Renderer::ResetAPIState");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill off all POOL_DEFAULT device objects.
|
// Kill off all POOL_DEFAULT device objects.
|
||||||
|
@ -296,17 +302,19 @@ void TeardownDeviceObjects()
|
||||||
{
|
{
|
||||||
delete g_framebuffer_manager;
|
delete g_framebuffer_manager;
|
||||||
|
|
||||||
access_efb_cbuf.reset();
|
SAFE_RELEASE(access_efb_cbuf);
|
||||||
|
SAFE_RELEASE(clearblendstates[0]);
|
||||||
for (int i = 0; i != 4; ++i)
|
SAFE_RELEASE(clearblendstates[1]);
|
||||||
clearblendstates[i].reset();
|
SAFE_RELEASE(clearblendstates[2]);
|
||||||
|
SAFE_RELEASE(clearblendstates[3]);
|
||||||
SAFE_RELEASE(cleardepthstates[0]);
|
SAFE_RELEASE(cleardepthstates[0]);
|
||||||
SAFE_RELEASE(cleardepthstates[1]);
|
SAFE_RELEASE(cleardepthstates[1]);
|
||||||
SAFE_RELEASE(cleardepthstates[2]);
|
SAFE_RELEASE(cleardepthstates[2]);
|
||||||
resetblendstate.reset();
|
SAFE_RELEASE(resetblendstate);
|
||||||
SAFE_RELEASE(resetdepthstate);
|
SAFE_RELEASE(resetdepthstate);
|
||||||
SAFE_RELEASE(resetraststate);
|
SAFE_RELEASE(resetraststate);
|
||||||
|
|
||||||
|
s_television.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer::Renderer()
|
Renderer::Renderer()
|
||||||
|
@ -318,8 +326,6 @@ Renderer::Renderer()
|
||||||
|
|
||||||
D3D::Create(EmuWindow::GetWnd());
|
D3D::Create(EmuWindow::GetWnd());
|
||||||
|
|
||||||
m_television.reset(new Television);
|
|
||||||
|
|
||||||
s_backbuffer_width = D3D::GetBackBufferWidth();
|
s_backbuffer_width = D3D::GetBackBufferWidth();
|
||||||
s_backbuffer_height = D3D::GetBackBufferHeight();
|
s_backbuffer_height = D3D::GetBackBufferHeight();
|
||||||
|
|
||||||
|
@ -373,20 +379,17 @@ Renderer::Renderer()
|
||||||
|
|
||||||
// Clear EFB textures
|
// Clear EFB textures
|
||||||
float ClearColor[4] = { 0.f, 0.f, 0.f, 1.f };
|
float ClearColor[4] = { 0.f, 0.f, 0.f, 1.f };
|
||||||
D3D::g_context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(), ClearColor);
|
D3D::context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(), ClearColor);
|
||||||
D3D::g_context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0);
|
D3D::context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0);
|
||||||
|
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f,
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)s_target_width, (float)s_target_height);
|
||||||
(float)s_target_width, (float)s_target_height);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
D3D::g_context->RSSetViewports(1, &vp);
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
|
||||||
D3D::BeginFrame();
|
D3D::BeginFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer::~Renderer()
|
Renderer::~Renderer()
|
||||||
{
|
{
|
||||||
m_television.reset();
|
|
||||||
|
|
||||||
TeardownDeviceObjects();
|
TeardownDeviceObjects();
|
||||||
D3D::EndFrame();
|
D3D::EndFrame();
|
||||||
D3D::Present();
|
D3D::Present();
|
||||||
|
@ -476,15 +479,14 @@ bool Renderer::SetScissorRect()
|
||||||
|
|
||||||
if (rc.right >= rc.left && rc.bottom >= rc.top)
|
if (rc.right >= rc.left && rc.bottom >= rc.top)
|
||||||
{
|
{
|
||||||
D3D::g_context->RSSetScissorRects(1, rc.AsRECT());
|
D3D::context->RSSetScissorRects(1, rc.AsRECT());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom);
|
//WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom);
|
||||||
*rc.AsRECT() = CD3D11_RECT(0, 0,
|
*rc.AsRECT() = CD3D11_RECT(0.f, 0.f, s_target_width, s_target_height);
|
||||||
s_target_width, s_target_height);
|
D3D::context->RSSetScissorRects(1, rc.AsRECT());
|
||||||
D3D::g_context->RSSetScissorRects(1, rc.AsRECT());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -563,9 +565,9 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
|
|
||||||
// depth buffers can only be completely CopySubresourceRegion'ed, so we're using drawShadedTexQuad instead
|
// depth buffers can only be completely CopySubresourceRegion'ed, so we're using drawShadedTexQuad instead
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, 1.f, 1.f);
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, 1.f, 1.f);
|
||||||
D3D::g_context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
D3D::g_context->PSSetConstantBuffers(0, 1, &access_efb_cbuf);
|
D3D::context->PSSetConstantBuffers(0, 1, &access_efb_cbuf);
|
||||||
D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBDepthReadTexture()->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBDepthReadTexture()->GetRTV(), NULL);
|
||||||
D3D::SetPointCopySampler();
|
D3D::SetPointCopySampler();
|
||||||
D3D::drawShadedTexQuad(FramebufferManager::GetEFBDepthTexture()->GetSRV(),
|
D3D::drawShadedTexQuad(FramebufferManager::GetEFBDepthTexture()->GetSRV(),
|
||||||
&RectToLock,
|
&RectToLock,
|
||||||
|
@ -575,17 +577,17 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
VertexShaderCache::GetSimpleVertexShader(),
|
VertexShaderCache::GetSimpleVertexShader(),
|
||||||
VertexShaderCache::GetSimpleInputLayout());
|
VertexShaderCache::GetSimpleInputLayout());
|
||||||
|
|
||||||
D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
|
|
||||||
// copy to system memory
|
// copy to system memory
|
||||||
D3D11_BOX box = CD3D11_BOX(0, 0, 0, 1, 1, 1);
|
D3D11_BOX box = CD3D11_BOX(0, 0, 0, 1, 1, 1);
|
||||||
read_tex = FramebufferManager::GetEFBDepthStagingBuffer();
|
read_tex = FramebufferManager::GetEFBDepthStagingBuffer();
|
||||||
D3D::g_context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, FramebufferManager::GetEFBDepthReadTexture()->GetTex(), 0, &box);
|
D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, FramebufferManager::GetEFBDepthReadTexture()->GetTex(), 0, &box);
|
||||||
|
|
||||||
RestoreAPIState(); // restore game state
|
RestoreAPIState(); // restore game state
|
||||||
|
|
||||||
// read the data from system memory
|
// read the data from system memory
|
||||||
D3D::g_context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map);
|
D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map);
|
||||||
|
|
||||||
float val = *(float*)map.pData;
|
float val = *(float*)map.pData;
|
||||||
u32 ret = 0;
|
u32 ret = 0;
|
||||||
|
@ -598,7 +600,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
{
|
{
|
||||||
ret = ((u32)(val * 0xffffff));
|
ret = ((u32)(val * 0xffffff));
|
||||||
}
|
}
|
||||||
D3D::g_context->Unmap(read_tex, 0);
|
D3D::context->Unmap(read_tex, 0);
|
||||||
|
|
||||||
// TODO: in RE0 this value is often off by one in Video_DX9 (where this code is derived from), which causes lighting to disappear
|
// TODO: in RE0 this value is often off by one in Video_DX9 (where this code is derived from), which causes lighting to disappear
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -608,14 +610,14 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
// we can directly copy to system memory here
|
// we can directly copy to system memory here
|
||||||
read_tex = FramebufferManager::GetEFBColorStagingBuffer();
|
read_tex = FramebufferManager::GetEFBColorStagingBuffer();
|
||||||
D3D11_BOX box = CD3D11_BOX(RectToLock.left, RectToLock.top, 0, RectToLock.right, RectToLock.bottom, 1);
|
D3D11_BOX box = CD3D11_BOX(RectToLock.left, RectToLock.top, 0, RectToLock.right, RectToLock.bottom, 1);
|
||||||
D3D::g_context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, FramebufferManager::GetEFBColorTexture()->GetTex(), 0, &box);
|
D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, FramebufferManager::GetEFBColorTexture()->GetTex(), 0, &box);
|
||||||
|
|
||||||
// read the data from system memory
|
// read the data from system memory
|
||||||
D3D::g_context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map);
|
D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map);
|
||||||
u32 ret = 0;
|
u32 ret = 0;
|
||||||
if(map.pData)
|
if(map.pData)
|
||||||
ret = *(u32*)map.pData;
|
ret = *(u32*)map.pData;
|
||||||
D3D::g_context->Unmap(read_tex, 0);
|
D3D::context->Unmap(read_tex, 0);
|
||||||
|
|
||||||
// check what to do with the alpha channel (GX_PokeAlphaRead)
|
// check what to do with the alpha channel (GX_PokeAlphaRead)
|
||||||
PixelEngine::UPEAlphaReadReg alpha_read_mode;
|
PixelEngine::UPEAlphaReadReg alpha_read_mode;
|
||||||
|
@ -645,7 +647,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
// TODO: The first five PE registers may change behavior of EFB pokes, this isn't implemented, yet.
|
// TODO: The first five PE registers may change behavior of EFB pokes, this isn't implemented, yet.
|
||||||
ResetAPIState();
|
ResetAPIState();
|
||||||
|
|
||||||
D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), NULL);
|
||||||
D3D::drawColorQuad(rgbaColor, (float)RectToLock.left * 2.f / (float)Renderer::GetTargetWidth() - 1.f,
|
D3D::drawColorQuad(rgbaColor, (float)RectToLock.left * 2.f / (float)Renderer::GetTargetWidth() - 1.f,
|
||||||
- (float)RectToLock.top * 2.f / (float)Renderer::GetTargetHeight() + 1.f,
|
- (float)RectToLock.top * 2.f / (float)Renderer::GetTargetHeight() + 1.f,
|
||||||
(float)RectToLock.right * 2.f / (float)Renderer::GetTargetWidth() - 1.f,
|
(float)RectToLock.right * 2.f / (float)Renderer::GetTargetWidth() - 1.f,
|
||||||
|
@ -713,9 +715,11 @@ void Renderer::UpdateViewport(Matrix44& vpCorrection)
|
||||||
int X = intendedX;
|
int X = intendedX;
|
||||||
if (X < 0)
|
if (X < 0)
|
||||||
X = 0;
|
X = 0;
|
||||||
|
|
||||||
int Y = intendedY;
|
int Y = intendedY;
|
||||||
if (Y < 0)
|
if (Y < 0)
|
||||||
Y = 0;
|
Y = 0;
|
||||||
|
|
||||||
int Wd = intendedWd;
|
int Wd = intendedWd;
|
||||||
if (X + Wd > GetTargetWidth())
|
if (X + Wd > GetTargetWidth())
|
||||||
Wd = GetTargetWidth() - X;
|
Wd = GetTargetWidth() - X;
|
||||||
|
@ -733,7 +737,7 @@ void Renderer::UpdateViewport(Matrix44& vpCorrection)
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(X, Y, Wd, Ht,
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(X, Y, Wd, Ht,
|
||||||
0.f, // (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f;
|
0.f, // (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f;
|
||||||
1.f); // xfregs.viewport.farZ / 16777216.0f;
|
1.f); // xfregs.viewport.farZ / 16777216.0f;
|
||||||
D3D::g_context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z)
|
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z)
|
||||||
|
@ -753,7 +757,7 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE
|
||||||
// Update the view port for clearing the picture
|
// Update the view port for clearing the picture
|
||||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)targetRc.left, (float)targetRc.top, (float)targetRc.GetWidth(), (float)targetRc.GetHeight(), 0.f, 1.f);
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)targetRc.left, (float)targetRc.top, (float)targetRc.GetWidth(), (float)targetRc.GetHeight(), 0.f, 1.f);
|
||||||
D3D::g_context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
// Color is passed in bgra mode so we need to convert it to rgba
|
// Color is passed in bgra mode so we need to convert it to rgba
|
||||||
u32 rgbaColor = (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000);
|
u32 rgbaColor = (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000);
|
||||||
|
@ -783,18 +787,16 @@ void Renderer::ReinterpretPixelData(unsigned int convtype)
|
||||||
g_renderer->ResetAPIState();
|
g_renderer->ResetAPIState();
|
||||||
|
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)g_renderer->GetTargetWidth(), (float)g_renderer->GetTargetHeight());
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)g_renderer->GetTargetWidth(), (float)g_renderer->GetTargetHeight());
|
||||||
D3D::g_context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTempTexture()->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTempTexture()->GetRTV(), NULL);
|
||||||
D3D::SetPointCopySampler();
|
D3D::SetPointCopySampler();
|
||||||
D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), &source,
|
D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), &source, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), pixel_shader, VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
||||||
g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(),
|
|
||||||
pixel_shader, VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
|
||||||
|
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
|
|
||||||
FramebufferManager::SwapReinterpretTexture();
|
FramebufferManager::SwapReinterpretTexture();
|
||||||
D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSrcBlend(D3D11_BLEND val)
|
void SetSrcBlend(D3D11_BLEND val)
|
||||||
|
@ -874,15 +876,15 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
||||||
bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle &rc)
|
bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle &rc)
|
||||||
{
|
{
|
||||||
// copy back buffer to system memory
|
// copy back buffer to system memory
|
||||||
|
ID3D11Texture2D* buftex;
|
||||||
D3D11_TEXTURE2D_DESC tex_desc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, D3D::GetBackBufferWidth(), D3D::GetBackBufferHeight(), 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE);
|
D3D11_TEXTURE2D_DESC tex_desc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, D3D::GetBackBufferWidth(), D3D::GetBackBufferHeight(), 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE);
|
||||||
auto const buftex = CreateTexture2DShared(&tex_desc, NULL);
|
HRESULT hr = D3D::device->CreateTexture2D(&tex_desc, NULL, &buftex);
|
||||||
if (!buftex)
|
if (FAILED(hr)) PanicAlert("Failed to create screenshot buffer texture");
|
||||||
PanicAlert("Failed to create screenshot buffer texture");
|
D3D::context->CopyResource(buftex, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex());
|
||||||
D3D::g_context->CopyResource(buftex, D3D::GetBackBuffer()->GetTex());
|
|
||||||
|
|
||||||
// D3DX11SaveTextureToFileA doesn't allow us to ignore the alpha channel, so we need to strip it out ourselves
|
// D3DX11SaveTextureToFileA doesn't allow us to ignore the alpha channel, so we need to strip it out ourselves
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
D3D::g_context->Map(buftex, 0, D3D11_MAP_READ_WRITE, 0, &map);
|
D3D::context->Map(buftex, 0, D3D11_MAP_READ_WRITE, 0, &map);
|
||||||
for (unsigned int y = 0; y < D3D::GetBackBufferHeight(); ++y)
|
for (unsigned int y = 0; y < D3D::GetBackBufferHeight(); ++y)
|
||||||
{
|
{
|
||||||
u8* ptr = (u8*)map.pData + y * map.RowPitch + 3;
|
u8* ptr = (u8*)map.pData + y * map.RowPitch + 3;
|
||||||
|
@ -892,10 +894,12 @@ bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
D3D::g_context->Unmap(buftex, 0);
|
D3D::context->Unmap(buftex, 0);
|
||||||
|
|
||||||
// ready to be saved
|
// ready to be saved
|
||||||
HRESULT hr = PD3DX11SaveTextureToFileA(D3D::g_context, buftex, D3DX11_IFF_PNG, filename.c_str());
|
hr = PD3DX11SaveTextureToFileA(D3D::context, buftex, D3DX11_IFF_PNG, filename.c_str());
|
||||||
|
buftex->Release();
|
||||||
|
|
||||||
return SUCCEEDED(hr);
|
return SUCCEEDED(hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -926,9 +930,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
TargetRectangle dst_rect;
|
TargetRectangle dst_rect;
|
||||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)s_backbuffer_width, (float)s_backbuffer_height);
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)s_backbuffer_width, (float)s_backbuffer_height);
|
||||||
D3D::g_context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
float ClearColor[4] = { 0.f, 0.f, 0.f, 1.f };
|
float ClearColor[4] = { 0.f, 0.f, 0.f, 1.f };
|
||||||
D3D::g_context->ClearRenderTargetView(D3D::GetBackBuffer()->GetRTV(), ClearColor);
|
D3D::context->ClearRenderTargetView(D3D::GetBackBuffer()->GetRTV(), ClearColor);
|
||||||
|
|
||||||
int X = dst_rect.left;
|
int X = dst_rect.left;
|
||||||
int Y = dst_rect.top;
|
int Y = dst_rect.top;
|
||||||
|
@ -944,8 +948,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
if (Width > (s_backbuffer_width - X)) Width = s_backbuffer_width - X;
|
if (Width > (s_backbuffer_width - X)) Width = s_backbuffer_width - X;
|
||||||
if (Height > (s_backbuffer_height - Y)) Height = s_backbuffer_height - Y;
|
if (Height > (s_backbuffer_height - Y)) Height = s_backbuffer_height - Y;
|
||||||
vp = CD3D11_VIEWPORT((float)X, (float)Y, (float)Width, (float)Height);
|
vp = CD3D11_VIEWPORT((float)X, (float)Y, (float)Width, (float)Height);
|
||||||
D3D::g_context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
D3D::g_context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL);
|
||||||
|
|
||||||
// activate linear filtering for the buffer copies
|
// activate linear filtering for the buffer copies
|
||||||
D3D::SetLinearCopySampler();
|
D3D::SetLinearCopySampler();
|
||||||
|
@ -953,10 +957,10 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
if (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB)
|
if (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB)
|
||||||
{
|
{
|
||||||
// TODO: Television should be used to render Virtual XFB mode as well.
|
// TODO: Television should be used to render Virtual XFB mode as well.
|
||||||
m_television->Submit(xfbAddr, fbWidth, fbHeight);
|
s_television.Submit(xfbAddr, fbWidth, fbHeight);
|
||||||
m_television->Render();
|
s_television.Render();
|
||||||
}
|
}
|
||||||
else if (g_ActiveConfig.bUseXFB)
|
else if(g_ActiveConfig.bUseXFB)
|
||||||
{
|
{
|
||||||
const XFBSourceBase* xfbSource;
|
const XFBSourceBase* xfbSource;
|
||||||
|
|
||||||
|
@ -1011,11 +1015,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
// TODO: Improve sampling algorithm for the pixel shader so that we can use the multisampled EFB texture as source
|
// TODO: Improve sampling algorithm for the pixel shader so that we can use the multisampled EFB texture as source
|
||||||
D3DTexture2D* read_texture = FramebufferManager::GetResolvedEFBColorTexture();
|
D3DTexture2D* read_texture = FramebufferManager::GetResolvedEFBColorTexture();
|
||||||
D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(),
|
D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), Gamma);
|
||||||
Renderer::GetTargetWidth(), Renderer::GetTargetHeight(),
|
|
||||||
PixelShaderCache::GetColorCopyProgram(false),
|
|
||||||
VertexShaderCache::GetSimpleVertexShader(),
|
|
||||||
VertexShaderCache::GetSimpleInputLayout(), Gamma);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// done with drawing the game stuff, good moment to save a screenshot
|
// done with drawing the game stuff, good moment to save a screenshot
|
||||||
|
@ -1129,19 +1129,19 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||||
CalculateTargetSize();
|
CalculateTargetSize();
|
||||||
|
|
||||||
D3D::g_context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL);
|
||||||
|
|
||||||
delete g_framebuffer_manager;
|
delete g_framebuffer_manager;
|
||||||
g_framebuffer_manager = new FramebufferManager;
|
g_framebuffer_manager = new FramebufferManager;
|
||||||
float clear_col[4] = { 0.f, 0.f, 0.f, 1.f };
|
float clear_col[4] = { 0.f, 0.f, 0.f, 1.f };
|
||||||
D3D::g_context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(), clear_col);
|
D3D::context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(), clear_col);
|
||||||
D3D::g_context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0);
|
D3D::context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// begin next frame
|
// begin next frame
|
||||||
Renderer::RestoreAPIState();
|
Renderer::RestoreAPIState();
|
||||||
D3D::BeginFrame();
|
D3D::BeginFrame();
|
||||||
D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
|
|
||||||
Core::Callback_VideoCopiedToXFB(XFBWrited || (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB));
|
Core::Callback_VideoCopiedToXFB(XFBWrited || (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB));
|
||||||
|
@ -1189,26 +1189,25 @@ void Renderer::ApplyState(bool bUseDstAlpha)
|
||||||
gx_state.blenddc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
gx_state.blenddc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
ID3D11BlendState* blstate;
|
||||||
auto const blstate = CreateBlendStateShared(&gx_state.blenddc);
|
hr = D3D::device->CreateBlendState(&gx_state.blenddc, &blstate);
|
||||||
if (!blstate)
|
if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__);
|
||||||
PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__);
|
|
||||||
D3D::stateman->PushBlendState(blstate);
|
D3D::stateman->PushBlendState(blstate);
|
||||||
D3D::SetDebugObjectName(blstate, "blend state used to emulate the GX pipeline");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)blstate, "blend state used to emulate the GX pipeline");
|
||||||
}
|
SAFE_RELEASE(blstate);
|
||||||
|
|
||||||
ID3D11DepthStencilState* depth_state;
|
ID3D11DepthStencilState* depth_state;
|
||||||
hr = D3D::g_device->CreateDepthStencilState(&gx_state.depthdc, &depth_state);
|
hr = D3D::device->CreateDepthStencilState(&gx_state.depthdc, &depth_state);
|
||||||
if (SUCCEEDED(hr)) D3D::SetDebugObjectName(depth_state, "depth-stencil state used to emulate the GX pipeline");
|
if (SUCCEEDED(hr)) D3D::SetDebugObjectName((ID3D11DeviceChild*)depth_state, "depth-stencil state used to emulate the GX pipeline");
|
||||||
else PanicAlert("Failed to create depth state at %s %d\n", __FILE__, __LINE__);
|
else PanicAlert("Failed to create depth state at %s %d\n", __FILE__, __LINE__);
|
||||||
D3D::stateman->PushDepthState(depth_state);
|
D3D::stateman->PushDepthState(depth_state);
|
||||||
SAFE_RELEASE(depth_state);
|
SAFE_RELEASE(depth_state);
|
||||||
|
|
||||||
gx_state.rastdc.FillMode = (g_ActiveConfig.bWireFrame) ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID;
|
gx_state.rastdc.FillMode = (g_ActiveConfig.bWireFrame) ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID;
|
||||||
ID3D11RasterizerState* raststate;
|
ID3D11RasterizerState* raststate;
|
||||||
hr = D3D::g_device->CreateRasterizerState(&gx_state.rastdc, &raststate);
|
hr = D3D::device->CreateRasterizerState(&gx_state.rastdc, &raststate);
|
||||||
if (FAILED(hr)) PanicAlert("Failed to create rasterizer state at %s %d\n", __FILE__, __LINE__);
|
if (FAILED(hr)) PanicAlert("Failed to create rasterizer state at %s %d\n", __FILE__, __LINE__);
|
||||||
D3D::SetDebugObjectName(raststate, "rasterizer state used to emulate the GX pipeline");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)raststate, "rasterizer state used to emulate the GX pipeline");
|
||||||
D3D::stateman->PushRasterizerState(raststate);
|
D3D::stateman->PushRasterizerState(raststate);
|
||||||
SAFE_RELEASE(raststate);
|
SAFE_RELEASE(raststate);
|
||||||
|
|
||||||
|
@ -1219,13 +1218,13 @@ void Renderer::ApplyState(bool bUseDstAlpha)
|
||||||
//if (shader_resources[stage])
|
//if (shader_resources[stage])
|
||||||
{
|
{
|
||||||
if(g_ActiveConfig.iMaxAnisotropy > 0) gx_state.sampdc[stage].Filter = D3D11_FILTER_ANISOTROPIC;
|
if(g_ActiveConfig.iMaxAnisotropy > 0) gx_state.sampdc[stage].Filter = D3D11_FILTER_ANISOTROPIC;
|
||||||
hr = D3D::g_device->CreateSamplerState(&gx_state.sampdc[stage], &samplerstate[stage]);
|
hr = D3D::device->CreateSamplerState(&gx_state.sampdc[stage], &samplerstate[stage]);
|
||||||
if (FAILED(hr)) PanicAlert("Fail %s %d, stage=%d\n", __FILE__, __LINE__, stage);
|
if (FAILED(hr)) PanicAlert("Fail %s %d, stage=%d\n", __FILE__, __LINE__, stage);
|
||||||
else D3D::SetDebugObjectName(samplerstate[stage], "sampler state used to emulate the GX pipeline");
|
else D3D::SetDebugObjectName((ID3D11DeviceChild*)samplerstate[stage], "sampler state used to emulate the GX pipeline");
|
||||||
}
|
}
|
||||||
// else samplerstate[stage] = NULL;
|
// else samplerstate[stage] = NULL;
|
||||||
}
|
}
|
||||||
D3D::g_context->PSSetSamplers(0, 8, samplerstate);
|
D3D::context->PSSetSamplers(0, 8, samplerstate);
|
||||||
for (unsigned int stage = 0; stage < 8; stage++)
|
for (unsigned int stage = 0; stage < 8; stage++)
|
||||||
SAFE_RELEASE(samplerstate[stage]);
|
SAFE_RELEASE(samplerstate[stage]);
|
||||||
|
|
||||||
|
@ -1238,17 +1237,17 @@ void Renderer::ApplyState(bool bUseDstAlpha)
|
||||||
SetLogicOpMode();
|
SetLogicOpMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D::g_context->PSSetConstantBuffers(0, 1, &PixelShaderCache::GetConstantBuffer());
|
D3D::context->PSSetConstantBuffers(0, 1, &PixelShaderCache::GetConstantBuffer());
|
||||||
D3D::g_context->VSSetConstantBuffers(0, 1, &VertexShaderCache::GetConstantBuffer());
|
D3D::context->VSSetConstantBuffers(0, 1, &VertexShaderCache::GetConstantBuffer());
|
||||||
|
|
||||||
D3D::g_context->PSSetShader(PixelShaderCache::GetActiveShader(), NULL, 0);
|
D3D::context->PSSetShader(PixelShaderCache::GetActiveShader(), NULL, 0);
|
||||||
D3D::g_context->VSSetShader(VertexShaderCache::GetActiveShader(), NULL, 0);
|
D3D::context->VSSetShader(VertexShaderCache::GetActiveShader(), NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::RestoreState()
|
void Renderer::RestoreState()
|
||||||
{
|
{
|
||||||
ID3D11ShaderResourceView* shader_resources[8] = { NULL };
|
ID3D11ShaderResourceView* shader_resources[8] = { NULL };
|
||||||
D3D::g_context->PSSetShaderResources(0, 8, shader_resources);
|
D3D::context->PSSetShaderResources(0, 8, shader_resources);
|
||||||
|
|
||||||
D3D::stateman->PopBlendState();
|
D3D::stateman->PopBlendState();
|
||||||
D3D::stateman->PopDepthState();
|
D3D::stateman->PopDepthState();
|
||||||
|
@ -1261,9 +1260,9 @@ void Renderer::ApplyCullDisable()
|
||||||
rastDesc.CullMode = D3D11_CULL_NONE;
|
rastDesc.CullMode = D3D11_CULL_NONE;
|
||||||
|
|
||||||
ID3D11RasterizerState* raststate;
|
ID3D11RasterizerState* raststate;
|
||||||
HRESULT hr = D3D::g_device->CreateRasterizerState(&rastDesc, &raststate);
|
HRESULT hr = D3D::device->CreateRasterizerState(&rastDesc, &raststate);
|
||||||
if (FAILED(hr)) PanicAlert("Failed to create culling-disabled rasterizer state at %s %d\n", __FILE__, __LINE__);
|
if (FAILED(hr)) PanicAlert("Failed to create culling-disabled rasterizer state at %s %d\n", __FILE__, __LINE__);
|
||||||
D3D::SetDebugObjectName(raststate, "rasterizer state (culling disabled) used to emulate the GX pipeline");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)raststate, "rasterizer state (culling disabled) used to emulate the GX pipeline");
|
||||||
|
|
||||||
D3D::stateman->PushRasterizerState(raststate);
|
D3D::stateman->PushRasterizerState(raststate);
|
||||||
SAFE_RELEASE(raststate);
|
SAFE_RELEASE(raststate);
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#define _RENDER_H_
|
#define _RENDER_H_
|
||||||
|
|
||||||
#include "RenderBase.h"
|
#include "RenderBase.h"
|
||||||
#include "Television.h"
|
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
@ -61,9 +60,6 @@ public:
|
||||||
void SetVSConstant4fv(unsigned int const_number, const float *f);
|
void SetVSConstant4fv(unsigned int const_number, const float *f);
|
||||||
void SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f);
|
void SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f);
|
||||||
void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f);
|
void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f);
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<Television> m_television;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,35 +71,43 @@ static const char YUYV_DECODER_PS[] =
|
||||||
;
|
;
|
||||||
|
|
||||||
Television::Television()
|
Television::Television()
|
||||||
: m_yuyvTextureSRV(NULL)
|
: m_yuyvTexture(NULL), m_yuyvTextureSRV(NULL), m_pShader(NULL)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void Television::Init()
|
||||||
{
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
// Create YUYV texture for real XFB mode
|
// Create YUYV texture for real XFB mode
|
||||||
|
|
||||||
// This texture format is designed for YUYV data.
|
// This texture format is designed for YUYV data.
|
||||||
D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC(
|
D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC(
|
||||||
DXGI_FORMAT_G8R8_G8B8_UNORM, MAX_XFB_WIDTH, MAX_XFB_HEIGHT, 1, 1);
|
DXGI_FORMAT_G8R8_G8B8_UNORM, MAX_XFB_WIDTH, MAX_XFB_HEIGHT, 1, 1);
|
||||||
m_yuyvTexture = CreateTexture2DShared(&t2dd, NULL);
|
hr = D3D::device->CreateTexture2D(&t2dd, NULL, &m_yuyvTexture);
|
||||||
CHECK(m_yuyvTexture, "create tv yuyv texture");
|
CHECK(SUCCEEDED(hr), "create tv yuyv texture");
|
||||||
D3D::SetDebugObjectName(m_yuyvTexture, "tv yuyv texture");
|
D3D::SetDebugObjectName(m_yuyvTexture, "tv yuyv texture");
|
||||||
|
|
||||||
// Create shader resource view for YUYV texture
|
// Create shader resource view for YUYV texture
|
||||||
|
|
||||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvd = CD3D11_SHADER_RESOURCE_VIEW_DESC(
|
D3D11_SHADER_RESOURCE_VIEW_DESC srvd = CD3D11_SHADER_RESOURCE_VIEW_DESC(
|
||||||
m_yuyvTexture, D3D11_SRV_DIMENSION_TEXTURE2D, DXGI_FORMAT_G8R8_G8B8_UNORM);
|
m_yuyvTexture, D3D11_SRV_DIMENSION_TEXTURE2D,
|
||||||
HRESULT hr = D3D::g_device->CreateShaderResourceView(m_yuyvTexture, &srvd, &m_yuyvTextureSRV);
|
DXGI_FORMAT_G8R8_G8B8_UNORM);
|
||||||
|
hr = D3D::device->CreateShaderResourceView(m_yuyvTexture, &srvd, &m_yuyvTextureSRV);
|
||||||
CHECK(SUCCEEDED(hr), "create tv yuyv texture srv");
|
CHECK(SUCCEEDED(hr), "create tv yuyv texture srv");
|
||||||
D3D::SetDebugObjectName(m_yuyvTextureSRV, "tv yuyv texture srv");
|
D3D::SetDebugObjectName(m_yuyvTextureSRV, "tv yuyv texture srv");
|
||||||
|
|
||||||
// Create YUYV-decoding pixel shader
|
// Create YUYV-decoding pixel shader
|
||||||
|
|
||||||
m_pShader = D3D::CompileAndCreatePixelShader(YUYV_DECODER_PS, sizeof(YUYV_DECODER_PS));
|
m_pShader = D3D::CompileAndCreatePixelShader(YUYV_DECODER_PS, sizeof(YUYV_DECODER_PS));
|
||||||
CHECK(m_pShader, "compile and create yuyv decoder pixel shader");
|
CHECK(m_pShader != NULL, "compile and create yuyv decoder pixel shader");
|
||||||
D3D::SetDebugObjectName(m_pShader, "yuyv decoder pixel shader");
|
D3D::SetDebugObjectName(m_pShader, "yuyv decoder pixel shader");
|
||||||
}
|
}
|
||||||
|
|
||||||
Television::~Television()
|
void Television::Shutdown()
|
||||||
{
|
{
|
||||||
|
SAFE_RELEASE(m_pShader);
|
||||||
SAFE_RELEASE(m_yuyvTextureSRV);
|
SAFE_RELEASE(m_yuyvTextureSRV);
|
||||||
|
SAFE_RELEASE(m_yuyvTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Television::Submit(u32 xfbAddr, u32 width, u32 height)
|
void Television::Submit(u32 xfbAddr, u32 width, u32 height)
|
||||||
|
@ -111,7 +119,7 @@ void Television::Submit(u32 xfbAddr, u32 width, u32 height)
|
||||||
// Load data from GameCube RAM to YUYV texture
|
// Load data from GameCube RAM to YUYV texture
|
||||||
u8* yuyvSrc = Memory::GetPointer(xfbAddr);
|
u8* yuyvSrc = Memory::GetPointer(xfbAddr);
|
||||||
D3D11_BOX box = CD3D11_BOX(0, 0, 0, width, height, 1);
|
D3D11_BOX box = CD3D11_BOX(0, 0, 0, width, height, 1);
|
||||||
D3D::g_context->UpdateSubresource(m_yuyvTexture, 0, &box, yuyvSrc, 2*width, 2*width*height);
|
D3D::context->UpdateSubresource(m_yuyvTexture, 0, &box, yuyvSrc, 2*width, 2*width*height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Television::Render()
|
void Television::Render()
|
||||||
|
|
|
@ -20,16 +20,22 @@
|
||||||
|
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
|
|
||||||
#include "D3DUtil.h"
|
struct ID3D11Texture2D;
|
||||||
|
struct ID3D11ShaderResourceView;
|
||||||
|
struct ID3D11PixelShader;
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
class Television
|
class Television
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Television();
|
Television();
|
||||||
~Television();
|
|
||||||
|
void Init();
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
// Submit video data to be drawn. This will change the current state of the
|
// Submit video data to be drawn. This will change the current state of the
|
||||||
// TV. xfbAddr points to YUYV data stored in GameCube/Wii RAM, but the XFB
|
// TV. xfbAddr points to YUYV data stored in GameCube/Wii RAM, but the XFB
|
||||||
|
@ -48,9 +54,10 @@ private:
|
||||||
|
|
||||||
// Used for real XFB mode
|
// Used for real XFB mode
|
||||||
|
|
||||||
SharedPtr<ID3D11Texture2D> m_yuyvTexture;
|
ID3D11Texture2D* m_yuyvTexture;
|
||||||
ID3D11ShaderResourceView* m_yuyvTextureSRV;
|
ID3D11ShaderResourceView* m_yuyvTextureSRV;
|
||||||
SharedPtr<ID3D11PixelShader> m_pShader;
|
ID3D11PixelShader* m_pShader;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,18 +31,23 @@
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
static std::unique_ptr<TextureEncoder> g_encoder;
|
static TextureEncoder* g_encoder = NULL;
|
||||||
const size_t MAX_COPY_BUFFERS = 25;
|
const size_t MAX_COPY_BUFFERS = 25;
|
||||||
static SharedPtr<ID3D11Buffer> efbcopycbuf[MAX_COPY_BUFFERS];
|
ID3D11Buffer* efbcopycbuf[MAX_COPY_BUFFERS] = { 0 };
|
||||||
|
|
||||||
|
TextureCache::TCacheEntry::~TCacheEntry()
|
||||||
|
{
|
||||||
|
texture->Release();
|
||||||
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::Bind(unsigned int stage)
|
void TextureCache::TCacheEntry::Bind(unsigned int stage)
|
||||||
{
|
{
|
||||||
D3D::g_context->PSSetShaderResources(stage, 1, &texture->GetSRV());
|
D3D::context->PSSetShaderResources(stage, 1, &texture->GetSRV());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureCache::TCacheEntry::Save(const char filename[])
|
bool TextureCache::TCacheEntry::Save(const char filename[])
|
||||||
{
|
{
|
||||||
return SUCCEEDED(PD3DX11SaveTextureToFileA(D3D::g_context, texture->GetTex(), D3DX11_IFF_PNG, filename));
|
return SUCCEEDED(PD3DX11SaveTextureToFileA(D3D::context, texture->GetTex(), D3DX11_IFF_PNG, filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
|
void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
|
||||||
|
@ -51,7 +56,7 @@ void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
|
||||||
D3D::ReplaceRGBATexture2D(texture->GetTex(), TextureCache::temp, width, height, expanded_width, level, usage);
|
D3D::ReplaceRGBATexture2D(texture->GetTex(), TextureCache::temp, width, height, expanded_width, level, usage);
|
||||||
|
|
||||||
if (autogen_mips)
|
if (autogen_mips)
|
||||||
PD3DX11FilterTexture(D3D::g_context, texture->GetTex(), 0, D3DX11_DEFAULT);
|
PD3DX11FilterTexture(D3D::context, texture->GetTex(), 0, D3DX11_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
|
TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
|
||||||
|
@ -76,16 +81,18 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
|
||||||
const D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM,
|
const D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||||
width, height, 1, tex_levels, D3D11_BIND_SHADER_RESOURCE, usage, cpu_access);
|
width, height, 1, tex_levels, D3D11_BIND_SHADER_RESOURCE, usage, cpu_access);
|
||||||
|
|
||||||
auto const pTexture = CreateTexture2DShared(&texdesc, data);
|
ID3D11Texture2D *pTexture;
|
||||||
CHECK(pTexture, "Create texture of the TextureCache");
|
const HRESULT hr = D3D::device->CreateTexture2D(&texdesc, data, &pTexture);
|
||||||
|
CHECK(SUCCEEDED(hr), "Create texture of the TextureCache");
|
||||||
|
|
||||||
std::unique_ptr<D3DTexture2D> tx(new D3DTexture2D(pTexture, D3D11_BIND_SHADER_RESOURCE));
|
TCacheEntry* const entry = new TCacheEntry(new D3DTexture2D(pTexture, D3D11_BIND_SHADER_RESOURCE));
|
||||||
auto const entry = new TCacheEntry(std::move(tx));
|
|
||||||
entry->usage = usage;
|
entry->usage = usage;
|
||||||
|
|
||||||
// TODO: better debug names
|
// TODO: better debug names
|
||||||
D3D::SetDebugObjectName(entry->texture->GetTex(), "a texture of the TextureCache");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetTex(), "a texture of the TextureCache");
|
||||||
D3D::SetDebugObjectName(entry->texture->GetSRV(), "shader resource view of a texture of the TextureCache");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetSRV(), "shader resource view of a texture of the TextureCache");
|
||||||
|
|
||||||
|
SAFE_RELEASE(pTexture);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +108,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
|
|
||||||
// stretch picture with increased internal resolution
|
// stretch picture with increased internal resolution
|
||||||
const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)virtualW, (float)virtualH);
|
const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)virtualW, (float)virtualH);
|
||||||
D3D::g_context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
// set transformation
|
// set transformation
|
||||||
if (NULL == efbcopycbuf[cbufid])
|
if (NULL == efbcopycbuf[cbufid])
|
||||||
|
@ -109,11 +116,11 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(28 * sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT);
|
const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(28 * sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT);
|
||||||
D3D11_SUBRESOURCE_DATA data;
|
D3D11_SUBRESOURCE_DATA data;
|
||||||
data.pSysMem = colmat;
|
data.pSysMem = colmat;
|
||||||
efbcopycbuf[cbufid] = CreateBufferShared(&cbdesc, &data);
|
HRESULT hr = D3D::device->CreateBuffer(&cbdesc, &data, &efbcopycbuf[cbufid]);
|
||||||
CHECK(efbcopycbuf[cbufid], "Create efb copy constant buffer %d", cbufid);
|
CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbufid);
|
||||||
D3D::SetDebugObjectName(efbcopycbuf[cbufid], "a constant buffer used in TextureCache::CopyRenderTargetToTexture");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopycbuf[cbufid], "a constant buffer used in TextureCache::CopyRenderTargetToTexture");
|
||||||
}
|
}
|
||||||
D3D::g_context->PSSetConstantBuffers(0, 1, &efbcopycbuf[cbufid]);
|
D3D::context->PSSetConstantBuffers(0, 1, &efbcopycbuf[cbufid]);
|
||||||
|
|
||||||
const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect);
|
const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect);
|
||||||
// TODO: try targetSource.asRECT();
|
// TODO: try targetSource.asRECT();
|
||||||
|
@ -125,7 +132,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
else
|
else
|
||||||
D3D::SetPointCopySampler();
|
D3D::SetPointCopySampler();
|
||||||
|
|
||||||
D3D::g_context->OMSetRenderTargets(1, &texture->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), NULL);
|
||||||
|
|
||||||
// Create texture copy
|
// Create texture copy
|
||||||
D3D::drawShadedTexQuad(
|
D3D::drawShadedTexQuad(
|
||||||
|
@ -134,7 +141,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
(srcFormat == PIXELFMT_Z24) ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true),
|
(srcFormat == PIXELFMT_Z24) ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true),
|
||||||
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
||||||
|
|
||||||
D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
|
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
}
|
}
|
||||||
|
@ -143,7 +150,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
{
|
{
|
||||||
u8* dst = Memory::GetPointer(dstAddr);
|
u8* dst = Memory::GetPointer(dstAddr);
|
||||||
size_t encodeSize = g_encoder->Encode(dst, dstFormat, srcFormat, srcRect, isIntensity, scaleByHalf);
|
size_t encodeSize = g_encoder->Encode(dst, dstFormat, srcFormat, srcRect, isIntensity, scaleByHalf);
|
||||||
hash = GetHash64(dst, (int)encodeSize, g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
hash = GetHash64(dst, encodeSize, g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
if (g_ActiveConfig.bEFBCopyCacheEnable)
|
if (g_ActiveConfig.bEFBCopyCacheEnable)
|
||||||
{
|
{
|
||||||
// If the texture in RAM is already in the texture cache,
|
// If the texture in RAM is already in the texture cache,
|
||||||
|
@ -152,7 +159,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::MakeRangeDynamic(dstAddr, (u32)encodeSize);
|
TextureCache::MakeRangeDynamic(dstAddr, encodeSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,12 +174,18 @@ TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(
|
||||||
TextureCache::TextureCache()
|
TextureCache::TextureCache()
|
||||||
{
|
{
|
||||||
// FIXME: Is it safe here?
|
// FIXME: Is it safe here?
|
||||||
g_encoder.reset(new PSTextureEncoder);
|
g_encoder = new PSTextureEncoder;
|
||||||
|
g_encoder->Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::~TextureCache()
|
TextureCache::~TextureCache()
|
||||||
{
|
{
|
||||||
g_encoder.reset();
|
for (unsigned int k = 0; k < MAX_COPY_BUFFERS; ++k)
|
||||||
|
SAFE_RELEASE(efbcopycbuf[k]);
|
||||||
|
|
||||||
|
g_encoder->Shutdown();
|
||||||
|
delete g_encoder;
|
||||||
|
g_encoder = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,11 +33,12 @@ public:
|
||||||
private:
|
private:
|
||||||
struct TCacheEntry : TCacheEntryBase
|
struct TCacheEntry : TCacheEntryBase
|
||||||
{
|
{
|
||||||
std::unique_ptr<D3DTexture2D> const texture;
|
D3DTexture2D *const texture;
|
||||||
|
|
||||||
D3D11_USAGE usage;
|
D3D11_USAGE usage;
|
||||||
|
|
||||||
TCacheEntry(std::unique_ptr<D3DTexture2D>&& _tex) : texture(std::move(_tex)) {}
|
TCacheEntry(D3DTexture2D *_tex) : texture(_tex) {}
|
||||||
|
~TCacheEntry();
|
||||||
|
|
||||||
void Load(unsigned int width, unsigned int height,
|
void Load(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int levels, bool autogen_mips = false);
|
unsigned int expanded_width, unsigned int levels, bool autogen_mips = false);
|
||||||
|
@ -55,6 +56,7 @@ private:
|
||||||
unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt);
|
unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt);
|
||||||
|
|
||||||
TCacheEntryBase* CreateRenderTargetTexture(unsigned int scaled_tex_w, unsigned int scaled_tex_h);
|
TCacheEntryBase* CreateRenderTargetTexture(unsigned int scaled_tex_w, unsigned int scaled_tex_h);
|
||||||
|
u64 EncodeToRamFromTexture(u32 address, void* source_texture, u32 SourceW, u32 SourceH, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source) {return 0;};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,13 +116,18 @@ static const UINT MAX_BYTES_PER_ENCODE = MAX_BYTES_PER_BLOCK_ROW*(EFB_HEIGHT/4);
|
||||||
|
|
||||||
class TextureEncoder
|
class TextureEncoder
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
virtual ~TextureEncoder() {}
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~TextureEncoder() { }
|
||||||
|
|
||||||
|
virtual void Init() = 0;
|
||||||
|
virtual void Shutdown() = 0;
|
||||||
// Returns size in bytes of encoded block of memory
|
// Returns size in bytes of encoded block of memory
|
||||||
virtual size_t Encode(u8* dst, unsigned int dstFormat,
|
virtual size_t Encode(u8* dst, unsigned int dstFormat,
|
||||||
unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity,
|
unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity,
|
||||||
bool scaleByHalf) = 0;
|
bool scaleByHalf) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,21 +42,21 @@ namespace DX11
|
||||||
const UINT IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE*2 * 16;
|
const UINT IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE*2 * 16;
|
||||||
const UINT VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16;
|
const UINT VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16;
|
||||||
|
|
||||||
VertexManager::VertexManager()
|
void VertexManager::CreateDeviceObjects()
|
||||||
{
|
{
|
||||||
D3D11_BUFFER_DESC bufdesc = CD3D11_BUFFER_DESC(IBUFFER_SIZE,
|
D3D11_BUFFER_DESC bufdesc = CD3D11_BUFFER_DESC(IBUFFER_SIZE,
|
||||||
D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||||
|
|
||||||
m_indexBuffer = CreateBufferShared(&bufdesc, NULL);
|
CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_indexBuffer)),
|
||||||
CHECK(m_indexBuffer, "Failed to create index buffer.");
|
"Failed to create index buffer.");
|
||||||
D3D::SetDebugObjectName(m_indexBuffer, "index buffer of VertexManager");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_indexBuffer, "index buffer of VertexManager");
|
||||||
|
|
||||||
bufdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
bufdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||||
bufdesc.ByteWidth = VBUFFER_SIZE;
|
bufdesc.ByteWidth = VBUFFER_SIZE;
|
||||||
|
|
||||||
m_vertexBuffer = CreateBufferShared(&bufdesc, NULL);
|
CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_vertexBuffer)),
|
||||||
CHECK(m_vertexBuffer, "Failed to create vertex buffer.");
|
"Failed to create vertex buffer.");
|
||||||
D3D::SetDebugObjectName(m_vertexBuffer, "vertex buffer of VertexManager");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_vertexBuffer, "vertex buffer of VertexManager");
|
||||||
|
|
||||||
m_indexBufferCursor = 0;
|
m_indexBufferCursor = 0;
|
||||||
m_vertexBufferCursor = 0;
|
m_vertexBufferCursor = 0;
|
||||||
|
@ -65,6 +65,28 @@ VertexManager::VertexManager()
|
||||||
m_triangleDrawIndex = 0;
|
m_triangleDrawIndex = 0;
|
||||||
m_lineDrawIndex = 0;
|
m_lineDrawIndex = 0;
|
||||||
m_pointDrawIndex = 0;
|
m_pointDrawIndex = 0;
|
||||||
|
|
||||||
|
m_lineShader.Init();
|
||||||
|
m_pointShader.Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VertexManager::DestroyDeviceObjects()
|
||||||
|
{
|
||||||
|
m_pointShader.Shutdown();
|
||||||
|
m_lineShader.Shutdown();
|
||||||
|
|
||||||
|
SAFE_RELEASE(m_vertexBuffer);
|
||||||
|
SAFE_RELEASE(m_indexBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexManager::VertexManager()
|
||||||
|
{
|
||||||
|
CreateDeviceObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexManager::~VertexManager()
|
||||||
|
{
|
||||||
|
DestroyDeviceObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexManager::LoadBuffers()
|
void VertexManager::LoadBuffers()
|
||||||
|
@ -75,16 +97,16 @@ void VertexManager::LoadBuffers()
|
||||||
if (m_vertexBufferCursor + vSize >= VBUFFER_SIZE)
|
if (m_vertexBufferCursor + vSize >= VBUFFER_SIZE)
|
||||||
{
|
{
|
||||||
// Wrap around
|
// Wrap around
|
||||||
D3D::g_context->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
D3D::context->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
m_vertexBufferCursor = 0;
|
m_vertexBufferCursor = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Append data
|
// Append data
|
||||||
D3D::g_context->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map);
|
D3D::context->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map);
|
||||||
}
|
}
|
||||||
memcpy((u8*)map.pData + m_vertexBufferCursor, LocalVBuffer, vSize);
|
memcpy((u8*)map.pData + m_vertexBufferCursor, LocalVBuffer, vSize);
|
||||||
D3D::g_context->Unmap(m_vertexBuffer, 0);
|
D3D::context->Unmap(m_vertexBuffer, 0);
|
||||||
m_vertexDrawOffset = m_vertexBufferCursor;
|
m_vertexDrawOffset = m_vertexBufferCursor;
|
||||||
m_vertexBufferCursor += vSize;
|
m_vertexBufferCursor += vSize;
|
||||||
|
|
||||||
|
@ -93,13 +115,13 @@ void VertexManager::LoadBuffers()
|
||||||
if (m_indexBufferCursor + iCount >= IBUFFER_SIZE/2)
|
if (m_indexBufferCursor + iCount >= IBUFFER_SIZE/2)
|
||||||
{
|
{
|
||||||
// Wrap around
|
// Wrap around
|
||||||
D3D::g_context->Map(m_indexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
D3D::context->Map(m_indexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
m_indexBufferCursor = 0;
|
m_indexBufferCursor = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Append data
|
// Append data
|
||||||
D3D::g_context->Map(m_indexBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map);
|
D3D::context->Map(m_indexBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map);
|
||||||
}
|
}
|
||||||
m_triangleDrawIndex = m_indexBufferCursor;
|
m_triangleDrawIndex = m_indexBufferCursor;
|
||||||
m_lineDrawIndex = m_triangleDrawIndex + IndexGenerator::GetTriangleindexLen();
|
m_lineDrawIndex = m_triangleDrawIndex + IndexGenerator::GetTriangleindexLen();
|
||||||
|
@ -107,7 +129,7 @@ void VertexManager::LoadBuffers()
|
||||||
memcpy((u16*)map.pData + m_triangleDrawIndex, TIBuffer, 2*IndexGenerator::GetTriangleindexLen());
|
memcpy((u16*)map.pData + m_triangleDrawIndex, TIBuffer, 2*IndexGenerator::GetTriangleindexLen());
|
||||||
memcpy((u16*)map.pData + m_lineDrawIndex, LIBuffer, 2*IndexGenerator::GetLineindexLen());
|
memcpy((u16*)map.pData + m_lineDrawIndex, LIBuffer, 2*IndexGenerator::GetLineindexLen());
|
||||||
memcpy((u16*)map.pData + m_pointDrawIndex, PIBuffer, 2*IndexGenerator::GetPointindexLen());
|
memcpy((u16*)map.pData + m_pointDrawIndex, PIBuffer, 2*IndexGenerator::GetPointindexLen());
|
||||||
D3D::g_context->Unmap(m_indexBuffer, 0);
|
D3D::context->Unmap(m_indexBuffer, 0);
|
||||||
m_indexBufferCursor += iCount;
|
m_indexBufferCursor += iCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,13 +139,13 @@ static const float LINE_PT_TEX_OFFSETS[8] = {
|
||||||
|
|
||||||
void VertexManager::Draw(UINT stride)
|
void VertexManager::Draw(UINT stride)
|
||||||
{
|
{
|
||||||
D3D::g_context->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &m_vertexDrawOffset);
|
D3D::context->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &m_vertexDrawOffset);
|
||||||
D3D::g_context->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R16_UINT, 0);
|
D3D::context->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R16_UINT, 0);
|
||||||
|
|
||||||
if (IndexGenerator::GetNumTriangles() > 0)
|
if (IndexGenerator::GetNumTriangles() > 0)
|
||||||
{
|
{
|
||||||
D3D::g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
D3D::g_context->DrawIndexed(IndexGenerator::GetTriangleindexLen(), m_triangleDrawIndex, 0);
|
D3D::context->DrawIndexed(IndexGenerator::GetTriangleindexLen(), m_triangleDrawIndex, 0);
|
||||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||||
}
|
}
|
||||||
// Disable culling for lines and points
|
// Disable culling for lines and points
|
||||||
|
@ -137,17 +159,18 @@ void VertexManager::Draw(UINT stride)
|
||||||
float vpHeight = -2.0f * xfregs.viewport.ht;
|
float vpHeight = -2.0f * xfregs.viewport.ht;
|
||||||
|
|
||||||
bool texOffsetEnable[8];
|
bool texOffsetEnable[8];
|
||||||
|
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
texOffsetEnable[i] = bpmem.texcoords[i].s.line_offset;
|
texOffsetEnable[i] = bpmem.texcoords[i].s.line_offset;
|
||||||
|
|
||||||
if (m_lineShader.SetShader(g_nativeVertexFmt->m_components, lineWidth,
|
if (m_lineShader.SetShader(g_nativeVertexFmt->m_components, lineWidth,
|
||||||
texOffset, vpWidth, vpHeight, texOffsetEnable))
|
texOffset, vpWidth, vpHeight, texOffsetEnable))
|
||||||
{
|
{
|
||||||
D3D::g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
|
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
|
||||||
D3D::g_context->DrawIndexed(IndexGenerator::GetLineindexLen(), m_lineDrawIndex, 0);
|
D3D::context->DrawIndexed(IndexGenerator::GetLineindexLen(), m_lineDrawIndex, 0);
|
||||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||||
|
|
||||||
D3D::g_context->GSSetShader(NULL, NULL, 0);
|
D3D::context->GSSetShader(NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IndexGenerator::GetNumPoints() > 0)
|
if (IndexGenerator::GetNumPoints() > 0)
|
||||||
|
@ -158,17 +181,18 @@ void VertexManager::Draw(UINT stride)
|
||||||
float vpHeight = -2.0f * xfregs.viewport.ht;
|
float vpHeight = -2.0f * xfregs.viewport.ht;
|
||||||
|
|
||||||
bool texOffsetEnable[8];
|
bool texOffsetEnable[8];
|
||||||
|
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
texOffsetEnable[i] = bpmem.texcoords[i].s.point_offset;
|
texOffsetEnable[i] = bpmem.texcoords[i].s.point_offset;
|
||||||
|
|
||||||
if (m_pointShader.SetShader(g_nativeVertexFmt->m_components, pointSize,
|
if (m_pointShader.SetShader(g_nativeVertexFmt->m_components, pointSize,
|
||||||
texOffset, vpWidth, vpHeight, texOffsetEnable))
|
texOffset, vpWidth, vpHeight, texOffsetEnable))
|
||||||
{
|
{
|
||||||
D3D::g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||||
D3D::g_context->DrawIndexed(IndexGenerator::GetPointindexLen(), m_pointDrawIndex, 0);
|
D3D::context->DrawIndexed(IndexGenerator::GetPointindexLen(), m_pointDrawIndex, 0);
|
||||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||||
|
|
||||||
D3D::g_context->GSSetShader(NULL, NULL, 0);
|
D3D::context->GSSetShader(NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IndexGenerator::GetNumLines() > 0 || IndexGenerator::GetNumPoints() > 0)
|
if (IndexGenerator::GetNumLines() > 0 || IndexGenerator::GetNumPoints() > 0)
|
||||||
|
@ -223,14 +247,14 @@ void VertexManager::vFlush()
|
||||||
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
|
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
|
||||||
bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
|
bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
|
||||||
|
|
||||||
if (!PixelShaderCache::LoadShader(
|
if (!PixelShaderCache::SetShader(
|
||||||
useDstAlpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE,
|
useDstAlpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE,
|
||||||
g_nativeVertexFmt->m_components))
|
g_nativeVertexFmt->m_components))
|
||||||
{
|
{
|
||||||
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
|
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
|
||||||
goto shader_fail;
|
goto shader_fail;
|
||||||
}
|
}
|
||||||
if (!VertexShaderCache::LoadShader(g_nativeVertexFmt->m_components))
|
if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components))
|
||||||
{
|
{
|
||||||
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
|
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
|
||||||
goto shader_fail;
|
goto shader_fail;
|
||||||
|
|
|
@ -29,10 +29,13 @@ class VertexManager : public ::VertexManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VertexManager();
|
VertexManager();
|
||||||
|
~VertexManager();
|
||||||
|
|
||||||
NativeVertexFormat* CreateNativeVertexFormat();
|
NativeVertexFormat* CreateNativeVertexFormat();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void CreateDeviceObjects();
|
||||||
|
void DestroyDeviceObjects();
|
||||||
void LoadBuffers();
|
void LoadBuffers();
|
||||||
void Draw(UINT stride);
|
void Draw(UINT stride);
|
||||||
// temp
|
// temp
|
||||||
|
@ -44,8 +47,8 @@ private:
|
||||||
UINT m_triangleDrawIndex;
|
UINT m_triangleDrawIndex;
|
||||||
UINT m_lineDrawIndex;
|
UINT m_lineDrawIndex;
|
||||||
UINT m_pointDrawIndex;
|
UINT m_pointDrawIndex;
|
||||||
SharedPtr<ID3D11Buffer> m_indexBuffer;
|
ID3D11Buffer* m_indexBuffer;
|
||||||
SharedPtr<ID3D11Buffer> m_vertexBuffer;
|
ID3D11Buffer* m_vertexBuffer;
|
||||||
|
|
||||||
LineGeometryShader m_lineShader;
|
LineGeometryShader m_lineShader;
|
||||||
PointGeometryShader m_pointShader;
|
PointGeometryShader m_pointShader;
|
||||||
|
|
|
@ -36,13 +36,12 @@ bool vscbufchanged = true;
|
||||||
namespace DX11 {
|
namespace DX11 {
|
||||||
|
|
||||||
VertexShaderCache::VSCache VertexShaderCache::vshaders;
|
VertexShaderCache::VSCache VertexShaderCache::vshaders;
|
||||||
const VertexShaderCache::VSCacheEntry* VertexShaderCache::last_entry;
|
const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry;
|
||||||
|
|
||||||
static SharedPtr<ID3D11VertexShader> SimpleVertexShader;
|
static ID3D11VertexShader* SimpleVertexShader = NULL;
|
||||||
static SharedPtr<ID3D11VertexShader> ClearVertexShader;
|
static ID3D11VertexShader* ClearVertexShader = NULL;
|
||||||
|
static ID3D11InputLayout* SimpleLayout = NULL;
|
||||||
static SharedPtr<ID3D11InputLayout> SimpleLayout;
|
static ID3D11InputLayout* ClearLayout = NULL;
|
||||||
static SharedPtr<ID3D11InputLayout> ClearLayout;
|
|
||||||
|
|
||||||
LinearDiskCache<VERTEXSHADERUID, u8> g_vs_disk_cache;
|
LinearDiskCache<VERTEXSHADERUID, u8> g_vs_disk_cache;
|
||||||
|
|
||||||
|
@ -51,34 +50,32 @@ ID3D11VertexShader* VertexShaderCache::GetClearVertexShader() { return ClearVert
|
||||||
ID3D11InputLayout* VertexShaderCache::GetSimpleInputLayout() { return SimpleLayout; }
|
ID3D11InputLayout* VertexShaderCache::GetSimpleInputLayout() { return SimpleLayout; }
|
||||||
ID3D11InputLayout* VertexShaderCache::GetClearInputLayout() { return ClearLayout; }
|
ID3D11InputLayout* VertexShaderCache::GetClearInputLayout() { return ClearLayout; }
|
||||||
|
|
||||||
SharedPtr<ID3D11Buffer> vscbuf;
|
ID3D11Buffer* vscbuf = NULL;
|
||||||
|
|
||||||
ID3D11Buffer*const& VertexShaderCache::GetConstantBuffer()
|
ID3D11Buffer* &VertexShaderCache::GetConstantBuffer()
|
||||||
{
|
{
|
||||||
// TODO: divide the global variables of the generated shaders into about 5 constant buffers to speed this up
|
// TODO: divide the global variables of the generated shaders into about 5 constant buffers to speed this up
|
||||||
if (vscbufchanged)
|
if (vscbufchanged)
|
||||||
{
|
{
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
D3D::g_context->Map(vscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
D3D::context->Map(vscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
memcpy(map.pData, vsconstants, sizeof(vsconstants));
|
memcpy(map.pData, vsconstants, sizeof(vsconstants));
|
||||||
D3D::g_context->Unmap(vscbuf, 0);
|
D3D::context->Unmap(vscbuf, 0);
|
||||||
vscbufchanged = false;
|
vscbufchanged = false;
|
||||||
}
|
}
|
||||||
return vscbuf;
|
return vscbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this class will load the precompiled shaders into our cache
|
// this class will load the precompiled shaders into our cache
|
||||||
class VertexShaderCacheInserter
|
class VertexShaderCacheInserter : public LinearDiskCacheReader<VERTEXSHADERUID, u8>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <typename F>
|
void Read(const VERTEXSHADERUID &key, const u8 *value, u32 value_size)
|
||||||
void operator()(const VERTEXSHADERUID& key, u32 value_size, F get_data) const
|
|
||||||
{
|
{
|
||||||
ID3D10Blob* blob = nullptr;
|
D3DBlob* blob = new D3DBlob(value_size, value);
|
||||||
PD3D10CreateBlob(value_size, &blob);
|
VertexShaderCache::InsertByteCode(key, blob);
|
||||||
get_data((u8*)blob->GetBufferPointer()); // read data from file into blob
|
blob->Release();
|
||||||
|
|
||||||
VertexShaderCache::InsertByteCode(key, SharedPtr<ID3D10Blob>::FromPtr(blob));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,29 +127,26 @@ void VertexShaderCache::Init()
|
||||||
|
|
||||||
unsigned int cbsize = ((sizeof(vsconstants))&(~0xf))+0x10; // must be a multiple of 16
|
unsigned int cbsize = ((sizeof(vsconstants))&(~0xf))+0x10; // must be a multiple of 16
|
||||||
D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||||
vscbuf = CreateBufferShared(&cbdesc, NULL);
|
HRESULT hr = D3D::device->CreateBuffer(&cbdesc, NULL, &vscbuf);
|
||||||
CHECK(vscbuf, "Create vertex shader constant buffer (size=%u)", cbsize);
|
CHECK(hr==S_OK, "Create vertex shader constant buffer (size=%u)", cbsize);
|
||||||
D3D::SetDebugObjectName(vscbuf, "vertex shader constant buffer used to emulate the GX pipeline");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)vscbuf, "vertex shader constant buffer used to emulate the GX pipeline");
|
||||||
|
|
||||||
{
|
D3DBlob* blob;
|
||||||
auto const blob = D3D::CompileVertexShader(simple_shader_code, sizeof(simple_shader_code));
|
D3D::CompileVertexShader(simple_shader_code, sizeof(simple_shader_code), &blob);
|
||||||
SimpleLayout = CreateInputLayoutShared(simpleelems, 2, blob->GetBufferPointer(), blob->GetBufferSize());
|
D3D::device->CreateInputLayout(simpleelems, 2, blob->Data(), blob->Size(), &SimpleLayout);
|
||||||
SimpleVertexShader = D3D::CreateVertexShaderFromByteCode(blob);
|
SimpleVertexShader = D3D::CreateVertexShaderFromByteCode(blob);
|
||||||
if (SimpleLayout == NULL || !SimpleVertexShader)
|
if (SimpleLayout == NULL || SimpleVertexShader == NULL) PanicAlert("Failed to create simple vertex shader or input layout at %s %d\n", __FILE__, __LINE__);
|
||||||
PanicAlert("Failed to create simple vertex shader or input layout at %s %d\n", __FILE__, __LINE__);
|
blob->Release();
|
||||||
D3D::SetDebugObjectName(SimpleVertexShader, "simple vertex shader");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleVertexShader, "simple vertex shader");
|
||||||
D3D::SetDebugObjectName(SimpleLayout, "simple input layout");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleLayout, "simple input layout");
|
||||||
}
|
|
||||||
|
|
||||||
{
|
D3D::CompileVertexShader(clear_shader_code, sizeof(clear_shader_code), &blob);
|
||||||
auto const blob = D3D::CompileVertexShader(clear_shader_code, sizeof(clear_shader_code));
|
D3D::device->CreateInputLayout(clearelems, 2, blob->Data(), blob->Size(), &ClearLayout);
|
||||||
ClearLayout = CreateInputLayoutShared(clearelems, 2, blob->GetBufferPointer(), blob->GetBufferSize());
|
|
||||||
ClearVertexShader = D3D::CreateVertexShaderFromByteCode(blob);
|
ClearVertexShader = D3D::CreateVertexShaderFromByteCode(blob);
|
||||||
if (ClearLayout == NULL || !ClearVertexShader)
|
if (ClearLayout == NULL || ClearVertexShader == NULL) PanicAlert("Failed to create clear vertex shader or input layout at %s %d\n", __FILE__, __LINE__);
|
||||||
PanicAlert("Failed to create clear vertex shader or input layout at %s %d\n", __FILE__, __LINE__);
|
blob->Release();
|
||||||
D3D::SetDebugObjectName(ClearVertexShader, "clear vertex shader");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearVertexShader, "clear vertex shader");
|
||||||
D3D::SetDebugObjectName(ClearLayout, "clear input layout");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearLayout, "clear input layout");
|
||||||
}
|
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
|
@ -177,39 +171,41 @@ void VertexShaderCache::Init()
|
||||||
|
|
||||||
char cache_filename[MAX_PATH];
|
char cache_filename[MAX_PATH];
|
||||||
sprintf(cache_filename, "%sdx11-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
|
sprintf(cache_filename, "%sdx11-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
|
||||||
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
||||||
|
VertexShaderCacheInserter inserter;
|
||||||
g_vs_disk_cache.OpenAndRead(cache_filename, VertexShaderCacheInserter());
|
g_vs_disk_cache.OpenAndRead(cache_filename, inserter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::Clear()
|
void VertexShaderCache::Clear()
|
||||||
{
|
{
|
||||||
|
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter)
|
||||||
|
iter->second.Destroy();
|
||||||
vshaders.clear();
|
vshaders.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::Shutdown()
|
void VertexShaderCache::Shutdown()
|
||||||
{
|
{
|
||||||
vscbuf.reset();
|
SAFE_RELEASE(vscbuf);
|
||||||
|
|
||||||
SimpleVertexShader.reset();
|
SAFE_RELEASE(SimpleVertexShader);
|
||||||
ClearVertexShader.reset();
|
SAFE_RELEASE(ClearVertexShader);
|
||||||
|
|
||||||
SimpleLayout.reset();
|
SAFE_RELEASE(SimpleLayout);
|
||||||
ClearLayout.reset();
|
SAFE_RELEASE(ClearLayout);
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
g_vs_disk_cache.Sync();
|
g_vs_disk_cache.Sync();
|
||||||
g_vs_disk_cache.Close();
|
g_vs_disk_cache.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VertexShaderCache::LoadShader(u32 components)
|
bool VertexShaderCache::SetShader(u32 components)
|
||||||
{
|
{
|
||||||
VERTEXSHADERUID uid;
|
VERTEXSHADERUID uid;
|
||||||
GetVertexShaderId(&uid, components);
|
GetVertexShaderId(&uid, components);
|
||||||
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
|
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
|
||||||
{
|
{
|
||||||
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
||||||
return (!!vshaders[uid].shader);
|
return (vshaders[uid].shader != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
||||||
|
@ -222,37 +218,39 @@ bool VertexShaderCache::LoadShader(u32 components)
|
||||||
last_entry = &entry;
|
last_entry = &entry;
|
||||||
|
|
||||||
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
||||||
return (!!entry.shader);
|
return (entry.shader != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *code = GenerateVertexShaderCode(components, API_D3D11);
|
const char *code = GenerateVertexShaderCode(components, API_D3D11);
|
||||||
|
|
||||||
auto const pbytecode = D3D::CompileVertexShader(code, (int)strlen(code));
|
D3DBlob* pbytecode = NULL;
|
||||||
if (!pbytecode)
|
D3D::CompileVertexShader(code, (int)strlen(code), &pbytecode);
|
||||||
|
|
||||||
|
if (pbytecode == NULL)
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to compile Vertex Shader %s %d:\n\n%s", __FILE__, __LINE__, code);
|
PanicAlert("Failed to compile Vertex Shader %s %d:\n\n%s", __FILE__, __LINE__, code);
|
||||||
GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
|
GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
g_vs_disk_cache.Append(uid, (u8*)pbytecode->GetBufferPointer(), (u32)pbytecode->GetBufferSize());
|
g_vs_disk_cache.Append(uid, pbytecode->Data(), pbytecode->Size());
|
||||||
g_vs_disk_cache.Sync();
|
g_vs_disk_cache.Sync();
|
||||||
|
|
||||||
bool result = InsertByteCode(uid, pbytecode);
|
bool result = InsertByteCode(uid, pbytecode);
|
||||||
|
pbytecode->Release();
|
||||||
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, SharedPtr<ID3D10Blob> bcodeblob)
|
bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, D3DBlob* bcodeblob)
|
||||||
{
|
{
|
||||||
auto const shader = D3D::CreateVertexShaderFromByteCode(bcodeblob);
|
ID3D11VertexShader* shader = D3D::CreateVertexShaderFromByteCode(bcodeblob);
|
||||||
if (!shader)
|
if (shader == NULL)
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to create vertex shader from %p size %d at %s %d\n",
|
PanicAlert("Failed to create vertex shader from %p size %d at %s %d\n", bcodeblob->Data(), bcodeblob->Size(), __FILE__, __LINE__);
|
||||||
bcodeblob->GetBufferPointer(), bcodeblob->GetBufferSize(), __FILE__, __LINE__);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// TODO: Somehow make the debug name a bit more specific
|
// TODO: Somehow make the debug name a bit more specific
|
||||||
D3D::SetDebugObjectName(shader, "a vertex shader of VertexShaderCache");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a vertex shader of VertexShaderCache");
|
||||||
|
|
||||||
// Make an entry in the table
|
// Make an entry in the table
|
||||||
VSCacheEntry entry;
|
VSCacheEntry entry;
|
||||||
|
|
|
@ -20,12 +20,12 @@
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "D3DUtil.h"
|
#include "D3DBase.h"
|
||||||
|
#include "D3DBlob.h"
|
||||||
|
|
||||||
class VERTEXSHADERUID;
|
class VERTEXSHADERUID;
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11 {
|
||||||
{
|
|
||||||
|
|
||||||
class VertexShaderCache
|
class VertexShaderCache
|
||||||
{
|
{
|
||||||
|
@ -33,33 +33,37 @@ public:
|
||||||
static void Init();
|
static void Init();
|
||||||
static void Clear();
|
static void Clear();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
static bool LoadShader(u32 components);
|
static bool SetShader(u32 components); // TODO: Should be renamed to LoadShader
|
||||||
|
|
||||||
static SharedPtr<ID3D11VertexShader> GetActiveShader() { return last_entry->shader; }
|
static ID3D11VertexShader* GetActiveShader() { return last_entry->shader; }
|
||||||
static SharedPtr<ID3D10Blob> GetActiveShaderBytecode() { return last_entry->bytecode; }
|
static D3DBlob* GetActiveShaderBytecode() { return last_entry->bytecode; }
|
||||||
static ID3D11Buffer*const& GetConstantBuffer();
|
static ID3D11Buffer* &GetConstantBuffer();
|
||||||
|
|
||||||
static ID3D11VertexShader* GetSimpleVertexShader();
|
static ID3D11VertexShader* GetSimpleVertexShader();
|
||||||
static ID3D11VertexShader* GetClearVertexShader();
|
static ID3D11VertexShader* GetClearVertexShader();
|
||||||
static ID3D11InputLayout* GetSimpleInputLayout();
|
static ID3D11InputLayout* GetSimpleInputLayout();
|
||||||
static ID3D11InputLayout* GetClearInputLayout();
|
static ID3D11InputLayout* GetClearInputLayout();
|
||||||
|
|
||||||
static bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, SharedPtr<ID3D10Blob> bcodeblob);
|
static bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, D3DBlob* bcodeblob);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct VSCacheEntry
|
struct VSCacheEntry
|
||||||
{
|
{
|
||||||
SharedPtr<ID3D11VertexShader> shader;
|
ID3D11VertexShader* shader;
|
||||||
SharedPtr<ID3D10Blob> bytecode; // needed to initialize the input layout
|
D3DBlob* bytecode; // needed to initialize the input layout
|
||||||
int frameCount;
|
int frameCount;
|
||||||
|
|
||||||
VSCacheEntry()
|
VSCacheEntry() : shader(NULL), bytecode(NULL), frameCount(0) {}
|
||||||
: frameCount(0)
|
void SetByteCode(D3DBlob* blob)
|
||||||
{}
|
|
||||||
|
|
||||||
void SetByteCode(SharedPtr<ID3D10Blob> blob)
|
|
||||||
{
|
{
|
||||||
|
SAFE_RELEASE(bytecode);
|
||||||
bytecode = blob;
|
bytecode = blob;
|
||||||
|
blob->AddRef();
|
||||||
|
}
|
||||||
|
void Destroy()
|
||||||
|
{
|
||||||
|
SAFE_RELEASE(shader);
|
||||||
|
SAFE_RELEASE(bytecode);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
typedef std::map<VERTEXSHADERUID, VSCacheEntry> VSCache;
|
typedef std::map<VERTEXSHADERUID, VSCacheEntry> VSCache;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "XFBEncoder.h"
|
#include "XFBEncoder.h"
|
||||||
|
|
||||||
#include "D3DBase.h"
|
#include "D3DBase.h"
|
||||||
|
#include "D3DBlob.h"
|
||||||
#include "D3DShader.h"
|
#include "D3DShader.h"
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
#include "GfxState.h"
|
#include "GfxState.h"
|
||||||
|
@ -143,10 +144,16 @@ static const struct QuadVertex
|
||||||
} QUAD_VERTS[4] = { { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } };
|
} QUAD_VERTS[4] = { { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } };
|
||||||
|
|
||||||
XFBEncoder::XFBEncoder()
|
XFBEncoder::XFBEncoder()
|
||||||
: m_outRTV(NULL),
|
: m_out(NULL), m_outRTV(NULL), m_outStage(NULL), m_encodeParams(NULL),
|
||||||
m_xfbEncodeDepthState(NULL),
|
m_quad(NULL), m_vShader(NULL), m_quadLayout(NULL), m_pShader(NULL),
|
||||||
|
m_xfbEncodeBlendState(NULL), m_xfbEncodeDepthState(NULL),
|
||||||
m_xfbEncodeRastState(NULL), m_efbSampler(NULL)
|
m_xfbEncodeRastState(NULL), m_efbSampler(NULL)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void XFBEncoder::Init()
|
||||||
{
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
// Create output texture
|
// Create output texture
|
||||||
|
|
||||||
// The pixel shader can generate one YUYV entry per pixel. One YUYV entry
|
// The pixel shader can generate one YUYV entry per pixel. One YUYV entry
|
||||||
|
@ -154,15 +161,15 @@ XFBEncoder::XFBEncoder()
|
||||||
D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC(
|
D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC(
|
||||||
DXGI_FORMAT_R8G8B8A8_UNORM, MAX_XFB_WIDTH/2, MAX_XFB_HEIGHT, 1, 1,
|
DXGI_FORMAT_R8G8B8A8_UNORM, MAX_XFB_WIDTH/2, MAX_XFB_HEIGHT, 1, 1,
|
||||||
D3D11_BIND_RENDER_TARGET);
|
D3D11_BIND_RENDER_TARGET);
|
||||||
m_out = CreateTexture2DShared(&t2dd, NULL);
|
hr = D3D::device->CreateTexture2D(&t2dd, NULL, &m_out);
|
||||||
CHECK(m_out, "create xfb encoder output texture");
|
CHECK(SUCCEEDED(hr), "create xfb encoder output texture");
|
||||||
D3D::SetDebugObjectName(m_out, "xfb encoder output texture");
|
D3D::SetDebugObjectName(m_out, "xfb encoder output texture");
|
||||||
|
|
||||||
// Create output render target view
|
// Create output render target view
|
||||||
|
|
||||||
D3D11_RENDER_TARGET_VIEW_DESC rtvd = CD3D11_RENDER_TARGET_VIEW_DESC(m_out,
|
D3D11_RENDER_TARGET_VIEW_DESC rtvd = CD3D11_RENDER_TARGET_VIEW_DESC(m_out,
|
||||||
D3D11_RTV_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM);
|
D3D11_RTV_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||||
HRESULT hr = D3D::g_device->CreateRenderTargetView(m_out, &rtvd, &m_outRTV);
|
hr = D3D::device->CreateRenderTargetView(m_out, &rtvd, &m_outRTV);
|
||||||
CHECK(SUCCEEDED(hr), "create xfb encoder output texture rtv");
|
CHECK(SUCCEEDED(hr), "create xfb encoder output texture rtv");
|
||||||
D3D::SetDebugObjectName(m_outRTV, "xfb encoder output rtv");
|
D3D::SetDebugObjectName(m_outRTV, "xfb encoder output rtv");
|
||||||
|
|
||||||
|
@ -171,16 +178,16 @@ XFBEncoder::XFBEncoder()
|
||||||
t2dd.Usage = D3D11_USAGE_STAGING;
|
t2dd.Usage = D3D11_USAGE_STAGING;
|
||||||
t2dd.BindFlags = 0;
|
t2dd.BindFlags = 0;
|
||||||
t2dd.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
t2dd.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||||
m_outStage = CreateTexture2DShared(&t2dd, NULL);
|
hr = D3D::device->CreateTexture2D(&t2dd, NULL, &m_outStage);
|
||||||
CHECK(m_outStage, "create xfb encoder output staging buffer");
|
CHECK(SUCCEEDED(hr), "create xfb encoder output staging buffer");
|
||||||
D3D::SetDebugObjectName(m_outStage, "xfb encoder output staging buffer");
|
D3D::SetDebugObjectName(m_outStage, "xfb encoder output staging buffer");
|
||||||
|
|
||||||
// Create constant buffer for uploading params to shaders
|
// Create constant buffer for uploading params to shaders
|
||||||
|
|
||||||
D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(XFBEncodeParams),
|
D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(XFBEncodeParams),
|
||||||
D3D11_BIND_CONSTANT_BUFFER);
|
D3D11_BIND_CONSTANT_BUFFER);
|
||||||
m_encodeParams = CreateBufferShared(&bd, NULL);
|
hr = D3D::device->CreateBuffer(&bd, NULL, &m_encodeParams);
|
||||||
CHECK(m_encodeParams, "create xfb encode params buffer");
|
CHECK(SUCCEEDED(hr), "create xfb encode params buffer");
|
||||||
D3D::SetDebugObjectName(m_encodeParams, "xfb encoder params buffer");
|
D3D::SetDebugObjectName(m_encodeParams, "xfb encoder params buffer");
|
||||||
|
|
||||||
// Create vertex quad
|
// Create vertex quad
|
||||||
|
@ -189,24 +196,35 @@ XFBEncoder::XFBEncoder()
|
||||||
D3D11_USAGE_IMMUTABLE);
|
D3D11_USAGE_IMMUTABLE);
|
||||||
D3D11_SUBRESOURCE_DATA srd = { QUAD_VERTS, 0, 0 };
|
D3D11_SUBRESOURCE_DATA srd = { QUAD_VERTS, 0, 0 };
|
||||||
|
|
||||||
m_quad = CreateBufferShared(&bd, &srd);
|
hr = D3D::device->CreateBuffer(&bd, &srd, &m_quad);
|
||||||
CHECK(m_quad, "create xfb encode quad vertex buffer");
|
CHECK(SUCCEEDED(hr), "create xfb encode quad vertex buffer");
|
||||||
D3D::SetDebugObjectName(m_quad, "xfb encoder quad vertex buffer");
|
D3D::SetDebugObjectName(m_quad, "xfb encoder quad vertex buffer");
|
||||||
|
|
||||||
// Create vertex shader
|
// Create vertex shader
|
||||||
SharedPtr<ID3D10Blob> bytecode;
|
|
||||||
m_vShader = D3D::CompileAndCreateVertexShader(XFB_ENCODE_VS, sizeof(XFB_ENCODE_VS), std::addressof(bytecode));
|
D3DBlob* bytecode = NULL;
|
||||||
CHECK(m_vShader, "compile/create xfb encode vertex shader");
|
if (!D3D::CompileVertexShader(XFB_ENCODE_VS, sizeof(XFB_ENCODE_VS), &bytecode))
|
||||||
|
{
|
||||||
|
ERROR_LOG(VIDEO, "XFB encode vertex shader failed to compile");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = D3D::device->CreateVertexShader(bytecode->Data(), bytecode->Size(), NULL, &m_vShader);
|
||||||
|
CHECK(SUCCEEDED(hr), "create xfb encode vertex shader");
|
||||||
D3D::SetDebugObjectName(m_vShader, "xfb encoder vertex shader");
|
D3D::SetDebugObjectName(m_vShader, "xfb encoder vertex shader");
|
||||||
|
|
||||||
// Create input layout for vertex quad using bytecode from vertex shader
|
// Create input layout for vertex quad using bytecode from vertex shader
|
||||||
m_quadLayout = CreateInputLayoutShared(QUAD_LAYOUT_DESC,
|
|
||||||
sizeof(QUAD_LAYOUT_DESC) / sizeof(D3D11_INPUT_ELEMENT_DESC),
|
hr = D3D::device->CreateInputLayout(QUAD_LAYOUT_DESC,
|
||||||
bytecode->GetBufferPointer(), bytecode->GetBufferSize());
|
sizeof(QUAD_LAYOUT_DESC)/sizeof(D3D11_INPUT_ELEMENT_DESC),
|
||||||
CHECK(m_quadLayout, "create xfb encode quad vertex layout");
|
bytecode->Data(), bytecode->Size(), &m_quadLayout);
|
||||||
|
CHECK(SUCCEEDED(hr), "create xfb encode quad vertex layout");
|
||||||
D3D::SetDebugObjectName(m_quadLayout, "xfb encoder quad layout");
|
D3D::SetDebugObjectName(m_quadLayout, "xfb encoder quad layout");
|
||||||
|
|
||||||
|
bytecode->Release();
|
||||||
|
|
||||||
// Create pixel shader
|
// Create pixel shader
|
||||||
|
|
||||||
m_pShader = D3D::CompileAndCreatePixelShader(XFB_ENCODE_PS, sizeof(XFB_ENCODE_PS));
|
m_pShader = D3D::CompileAndCreatePixelShader(XFB_ENCODE_PS, sizeof(XFB_ENCODE_PS));
|
||||||
if (!m_pShader)
|
if (!m_pShader)
|
||||||
{
|
{
|
||||||
|
@ -217,44 +235,52 @@ XFBEncoder::XFBEncoder()
|
||||||
|
|
||||||
// Create blend state
|
// Create blend state
|
||||||
|
|
||||||
auto bld = CD3D11_BLEND_DESC(CD3D11_DEFAULT());
|
D3D11_BLEND_DESC bld = CD3D11_BLEND_DESC(CD3D11_DEFAULT());
|
||||||
m_xfbEncodeBlendState = CreateBlendStateShared(&bld);
|
hr = D3D::device->CreateBlendState(&bld, &m_xfbEncodeBlendState);
|
||||||
CHECK(m_xfbEncodeBlendState, "create xfb encode blend state");
|
CHECK(SUCCEEDED(hr), "create xfb encode blend state");
|
||||||
D3D::SetDebugObjectName(m_xfbEncodeBlendState, "xfb encoder blend state");
|
D3D::SetDebugObjectName(m_xfbEncodeBlendState, "xfb encoder blend state");
|
||||||
|
|
||||||
// Create depth state
|
// Create depth state
|
||||||
|
|
||||||
auto dsd = CD3D11_DEPTH_STENCIL_DESC(CD3D11_DEFAULT());
|
D3D11_DEPTH_STENCIL_DESC dsd = CD3D11_DEPTH_STENCIL_DESC(CD3D11_DEFAULT());
|
||||||
dsd.DepthEnable = FALSE;
|
dsd.DepthEnable = FALSE;
|
||||||
hr = D3D::g_device->CreateDepthStencilState(&dsd, &m_xfbEncodeDepthState);
|
hr = D3D::device->CreateDepthStencilState(&dsd, &m_xfbEncodeDepthState);
|
||||||
CHECK(SUCCEEDED(hr), "create xfb encode depth state");
|
CHECK(SUCCEEDED(hr), "create xfb encode depth state");
|
||||||
D3D::SetDebugObjectName(m_xfbEncodeDepthState, "xfb encoder depth state");
|
D3D::SetDebugObjectName(m_xfbEncodeDepthState, "xfb encoder depth state");
|
||||||
|
|
||||||
// Create rasterizer state
|
// Create rasterizer state
|
||||||
|
|
||||||
auto rd = CD3D11_RASTERIZER_DESC(CD3D11_DEFAULT());
|
D3D11_RASTERIZER_DESC rd = CD3D11_RASTERIZER_DESC(CD3D11_DEFAULT());
|
||||||
rd.CullMode = D3D11_CULL_NONE;
|
rd.CullMode = D3D11_CULL_NONE;
|
||||||
rd.DepthClipEnable = FALSE;
|
rd.DepthClipEnable = FALSE;
|
||||||
hr = D3D::g_device->CreateRasterizerState(&rd, &m_xfbEncodeRastState);
|
hr = D3D::device->CreateRasterizerState(&rd, &m_xfbEncodeRastState);
|
||||||
CHECK(SUCCEEDED(hr), "create xfb encode rasterizer state");
|
CHECK(SUCCEEDED(hr), "create xfb encode rasterizer state");
|
||||||
D3D::SetDebugObjectName(m_xfbEncodeRastState, "xfb encoder rast state");
|
D3D::SetDebugObjectName(m_xfbEncodeRastState, "xfb encoder rast state");
|
||||||
|
|
||||||
// Create EFB texture sampler
|
// Create EFB texture sampler
|
||||||
|
|
||||||
auto sd = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT());
|
D3D11_SAMPLER_DESC sd = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT());
|
||||||
// FIXME: Should we really use point sampling here?
|
// FIXME: Should we really use point sampling here?
|
||||||
sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||||
hr = D3D::g_device->CreateSamplerState(&sd, &m_efbSampler);
|
hr = D3D::device->CreateSamplerState(&sd, &m_efbSampler);
|
||||||
CHECK(SUCCEEDED(hr), "create xfb encode texture sampler");
|
CHECK(SUCCEEDED(hr), "create xfb encode texture sampler");
|
||||||
D3D::SetDebugObjectName(m_efbSampler, "xfb encoder texture sampler");
|
D3D::SetDebugObjectName(m_efbSampler, "xfb encoder texture sampler");
|
||||||
}
|
}
|
||||||
|
|
||||||
XFBEncoder::~XFBEncoder()
|
void XFBEncoder::Shutdown()
|
||||||
{
|
{
|
||||||
SAFE_RELEASE(m_efbSampler);
|
SAFE_RELEASE(m_efbSampler);
|
||||||
SAFE_RELEASE(m_xfbEncodeRastState);
|
SAFE_RELEASE(m_xfbEncodeRastState);
|
||||||
SAFE_RELEASE(m_xfbEncodeDepthState);
|
SAFE_RELEASE(m_xfbEncodeDepthState);
|
||||||
|
SAFE_RELEASE(m_xfbEncodeBlendState);
|
||||||
|
SAFE_RELEASE(m_pShader);
|
||||||
|
SAFE_RELEASE(m_quadLayout);
|
||||||
|
SAFE_RELEASE(m_vShader);
|
||||||
|
SAFE_RELEASE(m_quad);
|
||||||
|
SAFE_RELEASE(m_encodeParams);
|
||||||
|
SAFE_RELEASE(m_outStage);
|
||||||
SAFE_RELEASE(m_outRTV);
|
SAFE_RELEASE(m_outRTV);
|
||||||
|
SAFE_RELEASE(m_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcRect, float gamma)
|
void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcRect, float gamma)
|
||||||
|
@ -267,8 +293,8 @@ void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcR
|
||||||
|
|
||||||
// Set up all the state for XFB encoding
|
// Set up all the state for XFB encoding
|
||||||
|
|
||||||
D3D::g_context->PSSetShader(m_pShader, NULL, 0);
|
D3D::context->PSSetShader(m_pShader, NULL, 0);
|
||||||
D3D::g_context->VSSetShader(m_vShader, NULL, 0);
|
D3D::context->VSSetShader(m_vShader, NULL, 0);
|
||||||
|
|
||||||
D3D::stateman->PushBlendState(m_xfbEncodeBlendState);
|
D3D::stateman->PushBlendState(m_xfbEncodeBlendState);
|
||||||
D3D::stateman->PushDepthState(m_xfbEncodeDepthState);
|
D3D::stateman->PushDepthState(m_xfbEncodeDepthState);
|
||||||
|
@ -276,13 +302,13 @@ void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcR
|
||||||
D3D::stateman->Apply();
|
D3D::stateman->Apply();
|
||||||
|
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, FLOAT(width/2), FLOAT(height));
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, FLOAT(width/2), FLOAT(height));
|
||||||
D3D::g_context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
D3D::g_context->IASetInputLayout(m_quadLayout);
|
D3D::context->IASetInputLayout(m_quadLayout);
|
||||||
D3D::g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||||
UINT stride = sizeof(QuadVertex);
|
UINT stride = sizeof(QuadVertex);
|
||||||
UINT offset = 0;
|
UINT offset = 0;
|
||||||
D3D::g_context->IASetVertexBuffers(0, 1, &m_quad, &stride, &offset);
|
D3D::context->IASetVertexBuffers(0, 1, &m_quad, &stride, &offset);
|
||||||
|
|
||||||
TargetRectangle targetRect = g_renderer->ConvertEFBRectangle(srcRect);
|
TargetRectangle targetRect = g_renderer->ConvertEFBRectangle(srcRect);
|
||||||
|
|
||||||
|
@ -294,50 +320,50 @@ void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcR
|
||||||
params.TexRight = FLOAT(targetRect.right) / g_renderer->GetTargetWidth();
|
params.TexRight = FLOAT(targetRect.right) / g_renderer->GetTargetWidth();
|
||||||
params.TexBottom = FLOAT(targetRect.bottom) / g_renderer->GetTargetHeight();
|
params.TexBottom = FLOAT(targetRect.bottom) / g_renderer->GetTargetHeight();
|
||||||
params.Gamma = gamma;
|
params.Gamma = gamma;
|
||||||
D3D::g_context->UpdateSubresource(m_encodeParams, 0, NULL, ¶ms, 0, 0);
|
D3D::context->UpdateSubresource(m_encodeParams, 0, NULL, ¶ms, 0, 0);
|
||||||
|
|
||||||
D3D::g_context->VSSetConstantBuffers(0, 1, &m_encodeParams);
|
D3D::context->VSSetConstantBuffers(0, 1, &m_encodeParams);
|
||||||
|
|
||||||
D3D::g_context->OMSetRenderTargets(1, &m_outRTV, NULL);
|
D3D::context->OMSetRenderTargets(1, &m_outRTV, NULL);
|
||||||
|
|
||||||
ID3D11ShaderResourceView* pEFB = FramebufferManager::GetEFBColorTexture()->GetSRV();
|
ID3D11ShaderResourceView* pEFB = FramebufferManager::GetEFBColorTexture()->GetSRV();
|
||||||
|
|
||||||
D3D::g_context->PSSetConstantBuffers(0, 1, &m_encodeParams);
|
D3D::context->PSSetConstantBuffers(0, 1, &m_encodeParams);
|
||||||
D3D::g_context->PSSetShaderResources(0, 1, &pEFB);
|
D3D::context->PSSetShaderResources(0, 1, &pEFB);
|
||||||
D3D::g_context->PSSetSamplers(0, 1, &m_efbSampler);
|
D3D::context->PSSetSamplers(0, 1, &m_efbSampler);
|
||||||
|
|
||||||
// Encode!
|
// Encode!
|
||||||
|
|
||||||
D3D::g_context->Draw(4, 0);
|
D3D::context->Draw(4, 0);
|
||||||
|
|
||||||
// Copy to staging buffer
|
// Copy to staging buffer
|
||||||
|
|
||||||
D3D11_BOX srcBox = CD3D11_BOX(0, 0, 0, width/2, height, 1);
|
D3D11_BOX srcBox = CD3D11_BOX(0, 0, 0, width/2, height, 1);
|
||||||
D3D::g_context->CopySubresourceRegion(m_outStage, 0, 0, 0, 0, m_out, 0, &srcBox);
|
D3D::context->CopySubresourceRegion(m_outStage, 0, 0, 0, 0, m_out, 0, &srcBox);
|
||||||
|
|
||||||
// Clean up state
|
// Clean up state
|
||||||
|
|
||||||
IUnknown* nullDummy = NULL;
|
IUnknown* nullDummy = NULL;
|
||||||
|
|
||||||
D3D::g_context->PSSetSamplers(0, 1, (ID3D11SamplerState**)&nullDummy);
|
D3D::context->PSSetSamplers(0, 1, (ID3D11SamplerState**)&nullDummy);
|
||||||
D3D::g_context->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&nullDummy);
|
D3D::context->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&nullDummy);
|
||||||
D3D::g_context->PSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy);
|
D3D::context->PSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy);
|
||||||
|
|
||||||
D3D::g_context->OMSetRenderTargets(0, NULL, NULL);
|
D3D::context->OMSetRenderTargets(0, NULL, NULL);
|
||||||
|
|
||||||
D3D::g_context->VSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy);
|
D3D::context->VSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy);
|
||||||
|
|
||||||
D3D::stateman->PopRasterizerState();
|
D3D::stateman->PopRasterizerState();
|
||||||
D3D::stateman->PopDepthState();
|
D3D::stateman->PopDepthState();
|
||||||
D3D::stateman->PopBlendState();
|
D3D::stateman->PopBlendState();
|
||||||
|
|
||||||
D3D::g_context->PSSetShader(NULL, NULL, 0);
|
D3D::context->PSSetShader(NULL, NULL, 0);
|
||||||
D3D::g_context->VSSetShader(NULL, NULL, 0);
|
D3D::context->VSSetShader(NULL, NULL, 0);
|
||||||
|
|
||||||
// Transfer staging buffer to GameCube/Wii RAM
|
// Transfer staging buffer to GameCube/Wii RAM
|
||||||
|
|
||||||
D3D11_MAPPED_SUBRESOURCE map = { 0 };
|
D3D11_MAPPED_SUBRESOURCE map = { 0 };
|
||||||
hr = D3D::g_context->Map(m_outStage, 0, D3D11_MAP_READ, 0, &map);
|
hr = D3D::context->Map(m_outStage, 0, D3D11_MAP_READ, 0, &map);
|
||||||
CHECK(SUCCEEDED(hr), "map staging buffer");
|
CHECK(SUCCEEDED(hr), "map staging buffer");
|
||||||
|
|
||||||
u8* src = (u8*)map.pData;
|
u8* src = (u8*)map.pData;
|
||||||
|
@ -348,12 +374,12 @@ void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcR
|
||||||
src += map.RowPitch;
|
src += map.RowPitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D::g_context->Unmap(m_outStage, 0);
|
D3D::context->Unmap(m_outStage, 0);
|
||||||
|
|
||||||
// Restore API
|
// Restore API
|
||||||
|
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
D3D::g_context->OMSetRenderTargets(1,
|
D3D::context->OMSetRenderTargets(1,
|
||||||
&FramebufferManager::GetEFBColorTexture()->GetRTV(),
|
&FramebufferManager::GetEFBColorTexture()->GetRTV(),
|
||||||
FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,32 +20,47 @@
|
||||||
|
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
|
|
||||||
#include "D3DUtil.h"
|
struct ID3D11Texture2D;
|
||||||
|
struct ID3D11RenderTargetView;
|
||||||
|
struct ID3D11Buffer;
|
||||||
|
struct ID3D11VertexShader;
|
||||||
|
struct ID3D11PixelShader;
|
||||||
|
struct ID3D11InputLayout;
|
||||||
|
struct ID3D11BlendState;
|
||||||
|
struct ID3D11DepthStencilState;
|
||||||
|
struct ID3D11RasterizerState;
|
||||||
|
struct ID3D11SamplerState;
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
class XFBEncoder
|
class XFBEncoder
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
XFBEncoder();
|
XFBEncoder();
|
||||||
~XFBEncoder();
|
|
||||||
|
void Init();
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
void Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcRect, float gamma);
|
void Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcRect, float gamma);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SharedPtr<ID3D11Texture2D> m_out;
|
|
||||||
|
ID3D11Texture2D* m_out;
|
||||||
ID3D11RenderTargetView* m_outRTV;
|
ID3D11RenderTargetView* m_outRTV;
|
||||||
SharedPtr<ID3D11Texture2D> m_outStage;
|
ID3D11Texture2D* m_outStage;
|
||||||
SharedPtr<ID3D11Buffer> m_encodeParams;
|
ID3D11Buffer* m_encodeParams;
|
||||||
SharedPtr<ID3D11Buffer> m_quad;
|
ID3D11Buffer* m_quad;
|
||||||
SharedPtr<ID3D11VertexShader> m_vShader;
|
ID3D11VertexShader* m_vShader;
|
||||||
SharedPtr<ID3D11InputLayout> m_quadLayout;
|
ID3D11InputLayout* m_quadLayout;
|
||||||
SharedPtr<ID3D11PixelShader> m_pShader;
|
ID3D11PixelShader* m_pShader;
|
||||||
SharedPtr<ID3D11BlendState> m_xfbEncodeBlendState;
|
ID3D11BlendState* m_xfbEncodeBlendState;
|
||||||
ID3D11DepthStencilState* m_xfbEncodeDepthState;
|
ID3D11DepthStencilState* m_xfbEncodeDepthState;
|
||||||
ID3D11RasterizerState* m_xfbEncodeRastState;
|
ID3D11RasterizerState* m_xfbEncodeRastState;
|
||||||
ID3D11SamplerState* m_efbSampler;
|
ID3D11SamplerState* m_efbSampler;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,8 +115,9 @@ void InitBackendInfo()
|
||||||
if (g_Config.backend_info.Adapters.size() == g_Config.iAdapter)
|
if (g_Config.backend_info.Adapters.size() == g_Config.iAdapter)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
auto const modes = DX11::D3D::EnumAAModes(ad);
|
std::vector<DXGI_SAMPLE_DESC> modes;
|
||||||
for (size_t i = 0; i < modes.size(); ++i)
|
modes = DX11::D3D::EnumAAModes(ad);
|
||||||
|
for (unsigned int i = 0; i < modes.size(); ++i)
|
||||||
{
|
{
|
||||||
if (i == 0) sprintf_s(buf, 32, "None");
|
if (i == 0) sprintf_s(buf, 32, "None");
|
||||||
else if (modes[i].Quality) sprintf_s(buf, 32, "%d samples (quality level %d)", modes[i].Count, modes[i].Quality);
|
else if (modes[i].Quality) sprintf_s(buf, 32, "%d samples (quality level %d)", modes[i].Count, modes[i].Quality);
|
||||||
|
|
|
@ -66,16 +66,12 @@ static LPDIRECT3DPIXELSHADER9 s_ClearProgram = NULL;
|
||||||
static LPDIRECT3DPIXELSHADER9 s_rgba6_to_rgb8 = NULL;
|
static LPDIRECT3DPIXELSHADER9 s_rgba6_to_rgb8 = NULL;
|
||||||
static LPDIRECT3DPIXELSHADER9 s_rgb8_to_rgba6 = NULL;
|
static LPDIRECT3DPIXELSHADER9 s_rgb8_to_rgba6 = NULL;
|
||||||
|
|
||||||
class PixelShaderCacheInserter
|
class PixelShaderCacheInserter : public LinearDiskCacheReader<PIXELSHADERUID, u8>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <typename F>
|
void Read(const PIXELSHADERUID &key, const u8 *value, u32 value_size)
|
||||||
void operator()(const PIXELSHADERUID& key, u32 value_size, F get_data) const
|
|
||||||
{
|
{
|
||||||
std::unique_ptr<u8[]> value(new u8[value_size]);
|
PixelShaderCache::InsertByteCode(key, value, value_size, false);
|
||||||
get_data(value.get());
|
|
||||||
|
|
||||||
PixelShaderCache::InsertByteCode(key, value.get(), value_size, false);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -285,8 +281,8 @@ void PixelShaderCache::Init()
|
||||||
char cache_filename[MAX_PATH];
|
char cache_filename[MAX_PATH];
|
||||||
sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
|
sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
|
||||||
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
||||||
|
PixelShaderCacheInserter inserter;
|
||||||
g_ps_disk_cache.OpenAndRead(cache_filename, PixelShaderCacheInserter());
|
g_ps_disk_cache.OpenAndRead(cache_filename, inserter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ONLY to be used during shutdown.
|
// ONLY to be used during shutdown.
|
||||||
|
|
|
@ -57,16 +57,12 @@ LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetClearVertexShader()
|
||||||
}
|
}
|
||||||
|
|
||||||
// this class will load the precompiled shaders into our cache
|
// this class will load the precompiled shaders into our cache
|
||||||
class VertexShaderCacheInserter
|
class VertexShaderCacheInserter : public LinearDiskCacheReader<VERTEXSHADERUID, u8>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <typename F>
|
void Read(const VERTEXSHADERUID &key, const u8 *value, u32 value_size)
|
||||||
void operator()(const VERTEXSHADERUID& key, u32 value_size, F get_data) const
|
|
||||||
{
|
{
|
||||||
std::unique_ptr<u8[]> value(new u8[value_size]);
|
VertexShaderCache::InsertByteCode(key, value, value_size, false);
|
||||||
get_data(value.get());
|
|
||||||
|
|
||||||
VertexShaderCache::InsertByteCode(key, value.get(), value_size, false);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -152,9 +148,9 @@ void VertexShaderCache::Init()
|
||||||
|
|
||||||
char cache_filename[MAX_PATH];
|
char cache_filename[MAX_PATH];
|
||||||
sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
|
sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
|
||||||
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
||||||
|
VertexShaderCacheInserter inserter;
|
||||||
g_vs_disk_cache.OpenAndRead(cache_filename, VertexShaderCacheInserter());
|
g_vs_disk_cache.OpenAndRead(cache_filename, inserter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::Clear()
|
void VertexShaderCache::Clear()
|
||||||
|
|
Loading…
Reference in New Issue