(D3D10/11/12)

.add a d3d10 driver.
.add more utility functions to d3d*_common files.
.add an image transfer/convert function to dxgi_common.
.various refactors / style nits.
This commit is contained in:
aliaspider 2018-01-23 18:04:55 +01:00
parent 96e96b9dfd
commit a5bf9d8dc6
21 changed files with 4838 additions and 1547 deletions

View File

@ -1186,8 +1186,7 @@ ifeq ($(HAVE_VULKAN), 1)
-I$(DEPS_DIR)/glslang \
-I$(DEPS_DIR)/SPIRV-Cross
CXXFLAGS += -Wno-switch -Wno-sign-compare -fno-strict-aliasing -Wno-maybe-uninitialized -Wno-reorder -Wno-parentheses -Igfx/include
CFLAGS += -Igfx/include
CXXFLAGS += -Wno-switch -Wno-sign-compare -fno-strict-aliasing -Wno-maybe-uninitialized -Wno-reorder -Wno-parentheses
GLSLANG_OBJ := $(GLSLANG_SOURCES:.cpp=.o)
SPIRV_CROSS_OBJ := $(SPIRV_CROSS_SOURCES:.cpp=.o)
@ -1213,6 +1212,10 @@ ifeq ($(HAVE_VULKAN), 1)
DEFINES += -DHAVE_SLANG
endif
ifeq ($(findstring 1, $(HAVE_VULKAN) $(HAVE_D3D10) $(HAVE_D3D11) $(HAVE_D3D12)),1)
INCLUDE_DIRS += -Igfx/include
endif
ifeq ($(WANT_WGL), 1)
OBJ += gfx/drivers_context/wgl_ctx.o
LIBS += -lcomctl32
@ -1289,30 +1292,25 @@ endif
endif
endif
ifeq ($(HAVE_D3D10), 1)
OBJ += gfx/drivers/d3d10.o gfx/common/d3d10_common.o
DEFINES += -DHAVE_D3D10
endif
ifeq ($(HAVE_D3D11), 1)
OBJ += gfx/drivers/d3d11.o gfx/common/d3d11_common.o
DEFINES += -DHAVE_D3D11
# LIBS += -ld3d11
WANT_DXGI = 1
WANT_D3DCOMPILER = 1
endif
ifeq ($(HAVE_D3D12), 1)
OBJ += gfx/drivers/d3d12.o gfx/common/d3d12_common.o
DEFINES += -DHAVE_D3D12
# LIBS += -ld3d12
WANT_DXGI = 1
WANT_D3DCOMPILER = 1
endif
ifeq ($(WANT_D3DCOMPILER), 1)
ifneq ($(findstring 1, $(HAVE_D3D10) $(HAVE_D3D11) $(HAVE_D3D12)),)
OBJ += gfx/common/d3dcompiler_common.o
# LIBS += -ld3dcompiler
endif
ifeq ($(WANT_DXGI), 1)
OBJ += gfx/common/dxgi_common.o
# LIBS += -ldxgi
CFLAGS += -Wno-unknown-pragmas
endif
ifeq ($(HAVE_D3D8), 1)

View File

@ -14,6 +14,7 @@ VCINSTALLDIR := C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\$(NOTHING
HAVE_D3DX := 1
HAVE_D3D8 := 0
HAVE_D3D9 := 1
HAVE_D3D10 := 1
HAVE_D3D11 := 1
HAVE_D3D12 := 1
HAVE_CG := 1
@ -50,6 +51,7 @@ HAVE_CHEEVOS := 1
HAVE_KEYMAPPER := 1
include Makefile.common
CFLAGS := $(filter-out -Wno-unknown-pragmas,$(CFLAGS))
CXXFLAGS := $(filter-out -fpermissive -Wno-switch -Wno-sign-compare -fno-strict-aliasing -Wno-maybe-uninitialized -Wno-reorder -Wno-parentheses,$(CXXFLAGS))
CXXFLAGS += $(CFLAGS)
LIBS := $(filter-out -lstdc++,$(LIBS))

View File

@ -132,6 +132,7 @@ enum video_driver_enum
VIDEO_SWITCH,
VIDEO_D3D8,
VIDEO_D3D9,
VIDEO_D3D10,
VIDEO_D3D11,
VIDEO_D3D12,
VIDEO_VG,
@ -698,6 +699,8 @@ const char *config_get_default_video(void)
return "d3d8";
case VIDEO_D3D9:
return "d3d9";
case VIDEO_D3D10:
return "d3d10";
case VIDEO_D3D11:
return "d3d11";
case VIDEO_D3D12:

128
gfx/common/d3d10_common.c Normal file
View File

@ -0,0 +1,128 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2018 - Ali Bouhlel
*
* RetroArch 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 Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch 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 for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "d3d10_common.h"
#include <dynamic/dylib.h>
static dylib_t d3d10_dll;
typedef HRESULT (WINAPI *PFN_D3D10_CREATE_DEVICE_AND_SWAP_CHAIN)(
IDXGIAdapter *pAdapter,
D3D10_DRIVER_TYPE DriverType,
HMODULE Software,
UINT Flags,
UINT SDKVersion,
DXGI_SWAP_CHAIN_DESC *pSwapChainDesc,
IDXGISwapChain **ppSwapChain,
ID3D10Device **ppDevice);
HRESULT WINAPI D3D10CreateDeviceAndSwapChain(
IDXGIAdapter *pAdapter,
D3D10_DRIVER_TYPE DriverType,
HMODULE Software,
UINT Flags,
UINT SDKVersion,
DXGI_SWAP_CHAIN_DESC *pSwapChainDesc,
IDXGISwapChain **ppSwapChain,
ID3D10Device **ppDevice)
{
static PFN_D3D10_CREATE_DEVICE_AND_SWAP_CHAIN fp;
if(!d3d10_dll)
d3d10_dll = dylib_load("d3d10.dll");
if(!d3d10_dll)
return TYPE_E_CANTLOADLIBRARY;
if(!fp)
fp = (PFN_D3D10_CREATE_DEVICE_AND_SWAP_CHAIN)dylib_proc(d3d10_dll, "D3D10CreateDeviceAndSwapChain");
if(!fp)
return TYPE_E_CANTLOADLIBRARY;
return fp(pAdapter,DriverType,Software, Flags, SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice);
}
void d3d10_init_texture(D3D10Device device, d3d10_texture_t* texture)
{
Release(texture->handle);
Release(texture->staging);
Release(texture->view);
// .Usage = D3D10_USAGE_DYNAMIC,
// .CPUAccessFlags = D3D10_CPU_ACCESS_WRITE,
texture->desc.MipLevels = 1;
texture->desc.ArraySize = 1;
texture->desc.SampleDesc.Count = 1;
texture->desc.SampleDesc.Quality = 0;
texture->desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
texture->desc.CPUAccessFlags = 0;
texture->desc.MiscFlags = 0;
D3D10CreateTexture2D(device, &texture->desc, NULL, &texture->handle);
{
D3D10_SHADER_RESOURCE_VIEW_DESC view_desc =
{
.Format = texture->desc.Format,
.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D,
.Texture2D.MostDetailedMip = 0,
.Texture2D.MipLevels = -1,
};
D3D10CreateTexture2DShaderResourceView(device, texture->handle, &view_desc, &texture->view);
}
{
D3D10_TEXTURE2D_DESC desc = texture->desc;
desc.BindFlags = 0;
desc.Usage = D3D10_USAGE_STAGING;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
D3D10CreateTexture2D(device, &desc, NULL, &texture->staging);
}
}
void d3d10_update_texture(int width, int height, int pitch, DXGI_FORMAT format, const void* data, d3d10_texture_t* texture)
{
D3D10_MAPPED_TEXTURE2D mapped_texture;
D3D10MapTexture2D(texture->staging, 0, D3D10_MAP_WRITE, 0, &mapped_texture);
dxgi_copy(width, height, format, pitch, data, texture->desc.Format, mapped_texture.RowPitch, mapped_texture.pData);
D3D10UnmapTexture2D(texture->staging, 0);
if(texture->desc.Usage == D3D10_USAGE_DEFAULT)
texture->dirty = true;
}
DXGI_FORMAT d3d10_get_closest_match(D3D10Device device, DXGI_FORMAT desired_format, UINT desired_format_support)
{
DXGI_FORMAT* format = dxgi_get_format_fallback_list(desired_format);
UINT format_support;
while(*format != DXGI_FORMAT_UNKNOWN)
{
if(SUCCEEDED(D3D10CheckFormatSupport(device, *format, &format_support))
&& ((format_support & desired_format_support) == desired_format_support))
break;
format++;
}
assert(*format);
return *format;
}

1147
gfx/common/d3d10_common.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -41,3 +41,71 @@ HRESULT WINAPI D3D11CreateDeviceAndSwapChain( IDXGIAdapter* pAdapter,D3D_DRIVER_
ppSwapChain, ppDevice, pFeatureLevel, ppImmediateContext);
}
void d3d11_init_texture(D3D11Device device, d3d11_texture_t* texture)
{
Release(texture->handle);
Release(texture->staging);
Release(texture->view);
// .Usage = D3D11_USAGE_DYNAMIC,
// .CPUAccessFlags = D3D11_CPU_ACCESS_WRITE,
texture->desc.MipLevels = 1;
texture->desc.ArraySize = 1;
texture->desc.SampleDesc.Count = 1;
texture->desc.SampleDesc.Quality = 0;
texture->desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texture->desc.CPUAccessFlags = 0;
texture->desc.MiscFlags = 0;
D3D11CreateTexture2D(device, &texture->desc, NULL, &texture->handle);
{
D3D11_SHADER_RESOURCE_VIEW_DESC view_desc =
{
.Format = texture->desc.Format,
.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D,
.Texture2D.MostDetailedMip = 0,
.Texture2D.MipLevels = -1,
};
D3D11CreateTexture2DShaderResourceView(device, texture->handle, &view_desc, &texture->view);
}
{
D3D11_TEXTURE2D_DESC desc = texture->desc;
desc.BindFlags = 0;
desc.Usage = D3D11_USAGE_STAGING;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
D3D11CreateTexture2D(device, &desc, NULL, &texture->staging);
}
}
void d3d11_update_texture(D3D11DeviceContext ctx, int width, int height, int pitch, DXGI_FORMAT format, const void* data, d3d11_texture_t* texture)
{
D3D11_MAPPED_SUBRESOURCE mapped_texture;
D3D11MapTexture2D(ctx, texture->staging, 0, D3D11_MAP_WRITE, 0, &mapped_texture);
dxgi_copy(width, height, format, pitch, data, texture->desc.Format, mapped_texture.RowPitch, mapped_texture.pData);
D3D11UnmapTexture2D(ctx, texture->staging, 0);
if(texture->desc.Usage == D3D11_USAGE_DEFAULT)
texture->dirty = true;
}
DXGI_FORMAT d3d11_get_closest_match(D3D11Device device, DXGI_FORMAT desired_format, UINT desired_format_support)
{
DXGI_FORMAT* format = dxgi_get_format_fallback_list(desired_format);
UINT format_support;
while(*format != DXGI_FORMAT_UNKNOWN)
{
if(SUCCEEDED(D3D11CheckFormatSupport(device, *format, &format_support))
&& ((format_support & desired_format_support) == desired_format_support))
break;
format++;
}
assert(*format);
return *format;
}

File diff suppressed because it is too large Load Diff

View File

@ -21,13 +21,11 @@
#include "verbosity.h"
static dylib_t d3d12_dll;
static dylib_t d3d12_dll;
static const char *d3d12_dll_name = "d3d12.dll";
HRESULT WINAPI
D3D12CreateDevice(IUnknown *pAdapter,
D3D_FEATURE_LEVEL MinimumFeatureLevel,
REFIID riid, void **ppDevice)
HRESULT WINAPI D3D12CreateDevice(
IUnknown *pAdapter, D3D_FEATURE_LEVEL MinimumFeatureLevel, REFIID riid, void **ppDevice)
{
if (!d3d12_dll)
d3d12_dll = dylib_load(d3d12_dll_name);
@ -46,8 +44,7 @@ D3D12CreateDevice(IUnknown *pAdapter,
return TYPE_E_CANTLOADLIBRARY;
}
HRESULT WINAPI
D3D12GetDebugInterface(REFIID riid, void **ppvDebug)
HRESULT WINAPI D3D12GetDebugInterface(REFIID riid, void **ppvDebug)
{
if (!d3d12_dll)
d3d12_dll = dylib_load(d3d12_dll_name);
@ -66,10 +63,10 @@ D3D12GetDebugInterface(REFIID riid, void **ppvDebug)
return TYPE_E_CANTLOADLIBRARY;
}
HRESULT WINAPI
D3D12SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC *pRootSignature,
D3D_ROOT_SIGNATURE_VERSION Version,
ID3DBlob **ppBlob, ID3DBlob **ppErrorBlob)
HRESULT WINAPI D3D12SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC *pRootSignature,
D3D_ROOT_SIGNATURE_VERSION Version,
ID3DBlob ** ppBlob,
ID3DBlob ** ppErrorBlob)
{
if (!d3d12_dll)
d3d12_dll = dylib_load(d3d12_dll_name);
@ -79,7 +76,8 @@ D3D12SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC *pRootSignature,
static PFN_D3D12_SERIALIZE_ROOT_SIGNATURE fp;
if (!fp)
fp = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)dylib_proc(d3d12_dll, "D3D12SerializeRootSignature");
fp = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)dylib_proc(
d3d12_dll, "D3D12SerializeRootSignature");
if (fp)
return fp(pRootSignature, Version, ppBlob, ppErrorBlob);
@ -88,9 +86,10 @@ D3D12SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC *pRootSignature,
return TYPE_E_CANTLOADLIBRARY;
}
HRESULT WINAPI
D3D12SerializeVersionedRootSignature(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *pRootSignature,
ID3DBlob **ppBlob, ID3DBlob **ppErrorBlob)
HRESULT WINAPI D3D12SerializeVersionedRootSignature(
const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *pRootSignature,
ID3DBlob ** ppBlob,
ID3DBlob ** ppErrorBlob)
{
if (!d3d12_dll)
d3d12_dll = dylib_load(d3d12_dll_name);
@ -100,8 +99,8 @@ D3D12SerializeVersionedRootSignature(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *
static PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE fp;
if (!fp)
fp = (PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)dylib_proc(d3d12_dll,
"D3D12SerializeRootSignature");
fp = (PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)dylib_proc(
d3d12_dll, "D3D12SerializeRootSignature");
if (fp)
return fp(pRootSignature, ppBlob, ppErrorBlob);
@ -110,7 +109,6 @@ D3D12SerializeVersionedRootSignature(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *
return TYPE_E_CANTLOADLIBRARY;
}
#include <wiiu/wiiu_dbg.h>
bool d3d12_init_base(d3d12_video_t *d3d12)
@ -144,19 +142,18 @@ bool d3d12_init_base(d3d12_video_t *d3d12)
bool d3d12_init_queue(d3d12_video_t *d3d12)
{
{
static const D3D12_COMMAND_QUEUE_DESC desc =
{
.Type = D3D12_COMMAND_LIST_TYPE_DIRECT,
static const D3D12_COMMAND_QUEUE_DESC desc = {
.Type = D3D12_COMMAND_LIST_TYPE_DIRECT,
.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE,
};
D3D12CreateCommandQueue(d3d12->device, &desc, &d3d12->queue.handle);
}
D3D12CreateCommandAllocator(d3d12->device, D3D12_COMMAND_LIST_TYPE_DIRECT,
&d3d12->queue.allocator);
D3D12CreateCommandAllocator(
d3d12->device, D3D12_COMMAND_LIST_TYPE_DIRECT, &d3d12->queue.allocator);
D3D12CreateGraphicsCommandList(d3d12->device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
d3d12->queue.allocator, d3d12->pipe.handle, &d3d12->queue.cmd);
d3d12->queue.allocator, d3d12->pipe.handle, &d3d12->queue.cmd);
D3D12CloseGraphicsCommandList(d3d12->queue.cmd);
@ -170,22 +167,21 @@ bool d3d12_init_queue(d3d12_video_t *d3d12)
bool d3d12_init_swapchain(d3d12_video_t *d3d12, int width, int height, HWND hwnd)
{
{
DXGI_SWAP_CHAIN_DESC desc =
{
.BufferCount = countof(d3d12->chain.renderTargets),
.BufferDesc.Width = width,
DXGI_SWAP_CHAIN_DESC desc = {
.BufferCount = countof(d3d12->chain.renderTargets),
.BufferDesc.Width = width,
.BufferDesc.Height = height,
.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM,
.SampleDesc.Count = 1,
.SampleDesc.Count = 1,
#if 0
.BufferDesc.RefreshRate.Numerator = 60,
.BufferDesc.RefreshRate.Denominator = 1,
.SampleDesc.Quality = 0,
#endif
.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT,
.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT,
.OutputWindow = hwnd,
.Windowed = TRUE,
#if 1
.Windowed = TRUE,
#if 0
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL,
#else
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD,
@ -200,15 +196,16 @@ bool d3d12_init_swapchain(d3d12_video_t *d3d12, int width, int height, HWND hwnd
for (int i = 0; i < countof(d3d12->chain.renderTargets); i++)
{
d3d12->chain.desc_handles[i].ptr = d3d12->pipe.rtv_heap.cpu.ptr + i * d3d12->pipe.rtv_heap.stride;
d3d12->chain.desc_handles[i].ptr =
d3d12->pipe.rtv_heap.cpu.ptr + i * d3d12->pipe.rtv_heap.stride;
DXGIGetSwapChainBuffer(d3d12->chain.handle, i, &d3d12->chain.renderTargets[i]);
D3D12CreateRenderTargetView(d3d12->device, d3d12->chain.renderTargets[i],
NULL, d3d12->chain.desc_handles[i]);
D3D12CreateRenderTargetView(
d3d12->device, d3d12->chain.renderTargets[i], NULL, d3d12->chain.desc_handles[i]);
}
d3d12->chain.viewport.Width = width;
d3d12->chain.viewport.Height = height;
d3d12->chain.scissorRect.right = width;
d3d12->chain.viewport.Width = width;
d3d12->chain.viewport.Height = height;
d3d12->chain.scissorRect.right = width;
d3d12->chain.scissorRect.bottom = height;
return true;
@ -217,74 +214,74 @@ bool d3d12_init_swapchain(d3d12_video_t *d3d12, int width, int height, HWND hwnd
static void d3d12_init_descriptor_heap(D3D12Device device, d3d12_descriptor_heap_t *out)
{
D3D12CreateDescriptorHeap(device, &out->desc, &out->handle);
out->cpu = D3D12GetCPUDescriptorHandleForHeapStart(out->handle);
out->gpu = D3D12GetGPUDescriptorHandleForHeapStart(out->handle);
out->cpu = D3D12GetCPUDescriptorHandleForHeapStart(out->handle);
out->gpu = D3D12GetGPUDescriptorHandleForHeapStart(out->handle);
out->stride = D3D12GetDescriptorHandleIncrementSize(device, out->desc.Type);
}
static void d3d12_init_sampler(D3D12Device device, d3d12_descriptor_heap_t *heap, descriptor_heap_slot_t heap_index,
D3D12_FILTER filter, D3D12_TEXTURE_ADDRESS_MODE address_mode, D3D12_GPU_DESCRIPTOR_HANDLE* dst)
static void d3d12_init_sampler(D3D12Device device,
d3d12_descriptor_heap_t * heap,
descriptor_heap_slot_t heap_index,
D3D12_FILTER filter,
D3D12_TEXTURE_ADDRESS_MODE address_mode,
D3D12_GPU_DESCRIPTOR_HANDLE * dst)
{
D3D12_SAMPLER_DESC sampler_desc =
{
.Filter = filter,
.AddressU = address_mode,
.AddressV = address_mode,
.AddressW = address_mode,
.MipLODBias = 0,
.MaxAnisotropy = 0,
D3D12_SAMPLER_DESC sampler_desc = {
.Filter = filter,
.AddressU = address_mode,
.AddressV = address_mode,
.AddressW = address_mode,
.MipLODBias = 0,
.MaxAnisotropy = 0,
.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER,
.BorderColor = {0.0f},
.MinLOD = 0.0f,
.MaxLOD = D3D12_FLOAT32_MAX,
.BorderColor = { 0.0f },
.MinLOD = 0.0f,
.MaxLOD = D3D12_FLOAT32_MAX,
};
D3D12_CPU_DESCRIPTOR_HANDLE handle = {heap->cpu.ptr + heap_index * heap->stride};
D3D12_CPU_DESCRIPTOR_HANDLE handle = { heap->cpu.ptr + heap_index * heap->stride };
D3D12CreateSampler(device, &sampler_desc, handle);
dst->ptr = heap->gpu.ptr + heap_index * heap->stride;
}
bool d3d12_init_descriptors(d3d12_video_t *d3d12)
{
static const D3D12_DESCRIPTOR_RANGE srv_table[] =
{
static const D3D12_DESCRIPTOR_RANGE srv_table[] = {
{
.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV,
.NumDescriptors = 1,
.BaseShaderRegister = 0,
.RegisterSpace = 0,
.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV,
.NumDescriptors = 1,
.BaseShaderRegister = 0,
.RegisterSpace = 0,
#if 0
.Flags = D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC, /* version 1_1 only */
#endif
.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND,
.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND,
},
};
static const D3D12_DESCRIPTOR_RANGE sampler_table[] =
{
static const D3D12_DESCRIPTOR_RANGE sampler_table[] = {
{
.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER,
.NumDescriptors = 1,
.BaseShaderRegister = 0,
.RegisterSpace = 0,
.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND,
.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER,
.NumDescriptors = 1,
.BaseShaderRegister = 0,
.RegisterSpace = 0,
.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND,
},
};
static const D3D12_ROOT_PARAMETER rootParameters[] =
{
static const D3D12_ROOT_PARAMETER rootParameters[] = {
{
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
.DescriptorTable = {countof(srv_table), srv_table},
.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL,
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
.DescriptorTable = { countof(srv_table), srv_table },
.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL,
},
{
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
.DescriptorTable = {countof(sampler_table), sampler_table},
.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL,
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
.DescriptorTable = { countof(sampler_table), sampler_table },
.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL,
},
};
static const D3D12_ROOT_SIGNATURE_DESC desc =
{
.NumParameters = countof(rootParameters), rootParameters,
static const D3D12_ROOT_SIGNATURE_DESC desc = {
.NumParameters = countof(rootParameters),
rootParameters,
.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT,
};
@ -295,37 +292,38 @@ bool d3d12_init_descriptors(d3d12_video_t *d3d12)
if (error)
{
RARCH_ERR("[D3D12]: CreateRootSignature failed :\n%s\n", (const char *)D3DGetBufferPointer(error));
RARCH_ERR("[D3D12]: CreateRootSignature failed :\n%s\n",
(const char *)D3DGetBufferPointer(error));
Release(error);
return false;
}
D3D12CreateRootSignature(d3d12->device, 0, D3DGetBufferPointer(signature),
D3DGetBufferSize(signature), &d3d12->pipe.rootSignature);
D3DGetBufferSize(signature), &d3d12->pipe.rootSignature);
Release(signature);
}
d3d12->pipe.rtv_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
d3d12->pipe.rtv_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
d3d12->pipe.rtv_heap.desc.NumDescriptors = countof(d3d12->chain.renderTargets);
d3d12->pipe.rtv_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
d3d12->pipe.rtv_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
d3d12_init_descriptor_heap(d3d12->device, &d3d12->pipe.rtv_heap);
d3d12->pipe.srv_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
d3d12->pipe.srv_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
d3d12->pipe.srv_heap.desc.NumDescriptors = SRV_HEAP_SLOT_MAX;
d3d12->pipe.srv_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
d3d12->pipe.srv_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
d3d12_init_descriptor_heap(d3d12->device, &d3d12->pipe.srv_heap);
d3d12->pipe.sampler_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
d3d12->pipe.sampler_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
d3d12->pipe.sampler_heap.desc.NumDescriptors = SAMPLER_HEAP_SLOT_MAX;
d3d12->pipe.sampler_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
d3d12->pipe.sampler_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
d3d12_init_descriptor_heap(d3d12->device, &d3d12->pipe.sampler_heap);
d3d12_init_sampler(d3d12->device, &d3d12->pipe.sampler_heap,
SAMPLER_HEAP_SLOT_LINEAR, D3D12_FILTER_MIN_MAG_MIP_LINEAR,
D3D12_TEXTURE_ADDRESS_MODE_BORDER, &d3d12->sampler_linear);
d3d12_init_sampler(d3d12->device, &d3d12->pipe.sampler_heap,
SAMPLER_HEAP_SLOT_NEAREST, D3D12_FILTER_MIN_MAG_MIP_POINT,
D3D12_TEXTURE_ADDRESS_MODE_BORDER, &d3d12->sampler_nearest);
d3d12_init_sampler(d3d12->device, &d3d12->pipe.sampler_heap, SAMPLER_HEAP_SLOT_LINEAR,
D3D12_FILTER_MIN_MAG_MIP_LINEAR, D3D12_TEXTURE_ADDRESS_MODE_BORDER,
&d3d12->sampler_linear);
d3d12_init_sampler(d3d12->device, &d3d12->pipe.sampler_heap, SAMPLER_HEAP_SLOT_NEAREST,
D3D12_FILTER_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_BORDER,
&d3d12->sampler_nearest);
return true;
}
@ -334,44 +332,49 @@ bool d3d12_init_pipeline(d3d12_video_t *d3d12)
D3DBlob vs_code;
D3DBlob ps_code;
static const char stock [] =
static const char stock[] =
#include "gfx/drivers/d3d_shaders/opaque_sm5.hlsl.h"
;
;
static const D3D12_INPUT_ELEMENT_DESC inputElementDesc[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, position), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, texcoord), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d12_vertex_t, color), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
static const D3D12_INPUT_ELEMENT_DESC inputElementDesc[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, position),
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, texcoord),
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d12_vertex_t, color),
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
};
static const D3D12_RASTERIZER_DESC rasterizerDesc =
{
.FillMode = D3D12_FILL_MODE_SOLID,
.CullMode = D3D12_CULL_MODE_BACK,
static const D3D12_RASTERIZER_DESC rasterizerDesc = {
.FillMode = D3D12_FILL_MODE_SOLID,
.CullMode = D3D12_CULL_MODE_BACK,
.FrontCounterClockwise = FALSE,
.DepthBias = D3D12_DEFAULT_DEPTH_BIAS,
.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP,
.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,
.DepthClipEnable = TRUE,
.MultisampleEnable = FALSE,
.DepthBias = D3D12_DEFAULT_DEPTH_BIAS,
.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP,
.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,
.DepthClipEnable = TRUE,
.MultisampleEnable = FALSE,
.AntialiasedLineEnable = FALSE,
.ForcedSampleCount = 0,
.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF,
.ForcedSampleCount = 0,
.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF,
};
static const D3D12_BLEND_DESC blendDesc =
{
.AlphaToCoverageEnable = FALSE,
static const D3D12_BLEND_DESC blendDesc = {
.AlphaToCoverageEnable = FALSE,
.IndependentBlendEnable = FALSE,
.RenderTarget[0] =
{
.BlendEnable = TRUE, .LogicOpEnable = FALSE,
D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
D3D12_LOGIC_OP_NOOP, D3D12_COLOR_WRITE_ENABLE_ALL,
},
{
.BlendEnable = TRUE,
.LogicOpEnable = FALSE,
D3D12_BLEND_SRC_ALPHA,
D3D12_BLEND_INV_SRC_ALPHA,
D3D12_BLEND_OP_ADD,
D3D12_BLEND_SRC_ALPHA,
D3D12_BLEND_INV_SRC_ALPHA,
D3D12_BLEND_OP_ADD,
D3D12_LOGIC_OP_NOOP,
D3D12_COLOR_WRITE_ENABLE_ALL,
},
};
if (!d3d_compile(stock, sizeof(stock), "VSMain", "vs_5_0", &vs_code))
@ -381,21 +384,23 @@ bool d3d12_init_pipeline(d3d12_video_t *d3d12)
return false;
{
D3D12_GRAPHICS_PIPELINE_STATE_DESC psodesc =
{
.pRootSignature = d3d12->pipe.rootSignature,
.VS.pShaderBytecode = D3DGetBufferPointer(vs_code), D3DGetBufferSize(vs_code),
.PS.pShaderBytecode = D3DGetBufferPointer(ps_code), D3DGetBufferSize(ps_code),
.BlendState = blendDesc,
.SampleMask = UINT_MAX,
.RasterizerState = rasterizerDesc,
.DepthStencilState.DepthEnable = FALSE,
D3D12_GRAPHICS_PIPELINE_STATE_DESC psodesc = {
.pRootSignature = d3d12->pipe.rootSignature,
.VS.pShaderBytecode = D3DGetBufferPointer(vs_code),
D3DGetBufferSize(vs_code),
.PS.pShaderBytecode = D3DGetBufferPointer(ps_code),
D3DGetBufferSize(ps_code),
.BlendState = blendDesc,
.SampleMask = UINT_MAX,
.RasterizerState = rasterizerDesc,
.DepthStencilState.DepthEnable = FALSE,
.DepthStencilState.StencilEnable = FALSE,
.InputLayout.pInputElementDescs = inputElementDesc, countof(inputElementDesc),
.InputLayout.pInputElementDescs = inputElementDesc,
countof(inputElementDesc),
.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
.NumRenderTargets = 1,
.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM,
.SampleDesc.Count = 1,
.NumRenderTargets = 1,
.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM,
.SampleDesc.Count = 1,
};
D3D12CreateGraphicsPipelineState(d3d12->device, &psodesc, &d3d12->pipe.handle);
@ -407,128 +412,144 @@ bool d3d12_init_pipeline(d3d12_video_t *d3d12)
return true;
}
void d3d12_create_vertex_buffer(D3D12Device device, D3D12_VERTEX_BUFFER_VIEW *view,
D3D12Resource *vbo)
void d3d12_create_vertex_buffer(
D3D12Device device, D3D12_VERTEX_BUFFER_VIEW *view, D3D12Resource *vbo)
{
static const D3D12_HEAP_PROPERTIES heap_props =
{
.Type = D3D12_HEAP_TYPE_UPLOAD,
static const D3D12_HEAP_PROPERTIES heap_props = {
.Type = D3D12_HEAP_TYPE_UPLOAD,
.CreationNodeMask = 1,
.VisibleNodeMask = 1,
.VisibleNodeMask = 1,
};
D3D12_RESOURCE_DESC resource_desc =
{
.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
.Width = view->SizeInBytes,
.Height = 1,
D3D12_RESOURCE_DESC resource_desc = {
.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
.Width = view->SizeInBytes,
.Height = 1,
.DepthOrArraySize = 1,
.MipLevels = 1,
.MipLevels = 1,
.SampleDesc.Count = 1,
.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
};
D3D12CreateCommittedResource(device, &heap_props, D3D12_HEAP_FLAG_NONE, &resource_desc,
D3D12_RESOURCE_STATE_GENERIC_READ, NULL, vbo);
D3D12_RESOURCE_STATE_GENERIC_READ, NULL, vbo);
view->BufferLocation = D3D12GetGPUVirtualAddress(*vbo);
}
void d3d12_create_texture(D3D12Device device, d3d12_descriptor_heap_t *heap, descriptor_heap_slot_t heap_index,
d3d12_texture_t *tex)
void d3d12_init_texture(D3D12Device device,
d3d12_descriptor_heap_t * heap,
descriptor_heap_slot_t heap_index,
d3d12_texture_t * texture)
{
{
tex->desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
tex->desc.DepthOrArraySize = 1;
tex->desc.MipLevels = 1;
tex->desc.SampleDesc.Count = 1;
Release(texture->handle);
Release(texture->upload_buffer);
D3D12_HEAP_PROPERTIES heap_props = {D3D12_HEAP_TYPE_DEFAULT, 0, 0, 1, 1};
D3D12CreateCommittedResource(device, &heap_props, D3D12_HEAP_FLAG_NONE, &tex->desc,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, NULL, &tex->handle);
{
texture->desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
texture->desc.DepthOrArraySize = 1;
texture->desc.MipLevels = 1;
texture->desc.SampleDesc.Count = 1;
D3D12_HEAP_PROPERTIES heap_props = { D3D12_HEAP_TYPE_DEFAULT, 0, 0, 1, 1 };
D3D12CreateCommittedResource(device, &heap_props, D3D12_HEAP_FLAG_NONE, &texture->desc,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, NULL, &texture->handle);
}
D3D12GetCopyableFootprints(device, &tex->desc, 0, 1, 0, &tex->layout, &tex->num_rows,
&tex->row_size_in_bytes, &tex->total_bytes);
D3D12GetCopyableFootprints(device, &texture->desc, 0, 1, 0, &texture->layout, &texture->num_rows,
&texture->row_size_in_bytes, &texture->total_bytes);
{
D3D12_RESOURCE_DESC buffer_desc =
{
.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
.Width = tex->total_bytes,
.Height = 1,
D3D12_RESOURCE_DESC buffer_desc = {
.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
.Width = texture->total_bytes,
.Height = 1,
.DepthOrArraySize = 1,
.MipLevels = 1,
.MipLevels = 1,
.SampleDesc.Count = 1,
.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
};
D3D12_HEAP_PROPERTIES heap_props = {D3D12_HEAP_TYPE_UPLOAD, 0, 0, 1, 1};
D3D12_HEAP_PROPERTIES heap_props = { D3D12_HEAP_TYPE_UPLOAD, 0, 0, 1, 1 };
D3D12CreateCommittedResource(device, &heap_props, D3D12_HEAP_FLAG_NONE, &buffer_desc,
D3D12_RESOURCE_STATE_GENERIC_READ, NULL, &tex->upload_buffer);
D3D12_RESOURCE_STATE_GENERIC_READ, NULL, &texture->upload_buffer);
}
{
D3D12_SHADER_RESOURCE_VIEW_DESC view_desc =
{
D3D12_SHADER_RESOURCE_VIEW_DESC view_desc = {
.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
.Format = tex->desc.Format,
.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D,
.Texture2D.MipLevels = tex->desc.MipLevels,
.Format = texture->desc.Format,
.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D,
.Texture2D.MipLevels = texture->desc.MipLevels,
};
D3D12_CPU_DESCRIPTOR_HANDLE handle = {heap->cpu.ptr + heap_index * heap->stride};
D3D12CreateShaderResourceView(device, tex->handle, &view_desc, handle);
tex->gpu_descriptor.ptr = heap->gpu.ptr + heap_index * heap->stride;
D3D12_CPU_DESCRIPTOR_HANDLE handle = { heap->cpu.ptr + heap_index * heap->stride };
D3D12CreateShaderResourceView(device, texture->handle, &view_desc, handle);
texture->gpu_descriptor.ptr = heap->gpu.ptr + heap_index * heap->stride;
}
}
void d3d12_upload_texture(D3D12GraphicsCommandList cmd, d3d12_texture_t *texture)
{
D3D12_TEXTURE_COPY_LOCATION src =
{
.pResource = texture->upload_buffer,
.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
D3D12_TEXTURE_COPY_LOCATION src = {
.pResource = texture->upload_buffer,
.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
.PlacedFootprint = texture->layout,
};
D3D12_TEXTURE_COPY_LOCATION dst =
{
.pResource = texture->handle,
.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
D3D12_TEXTURE_COPY_LOCATION dst = {
.pResource = texture->handle,
.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
.SubresourceIndex = 0,
};
d3d12_resource_transition(cmd, texture->handle,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST);
d3d12_resource_transition(cmd, texture->handle, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
D3D12_RESOURCE_STATE_COPY_DEST);
D3D12CopyTextureRegion(cmd, &dst, 0, 0, 0, &src, NULL);
d3d12_resource_transition(cmd, texture->handle,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
d3d12_resource_transition(cmd, texture->handle, D3D12_RESOURCE_STATE_COPY_DEST,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
texture->dirty = false;
}
void d3d12_create_fullscreen_quad_vbo(D3D12Device device, D3D12_VERTEX_BUFFER_VIEW *view, D3D12Resource *vbo)
void d3d12_create_fullscreen_quad_vbo(
D3D12Device device, D3D12_VERTEX_BUFFER_VIEW *view, D3D12Resource *vbo)
{
static const d3d12_vertex_t vertices[] =
{
{{ -1.0f, -1.0f}, {0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}},
{{ -1.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}},
{{ 1.0f, -1.0f}, {1.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}},
{{ 1.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}},
static const d3d12_vertex_t vertices[] = {
{ { -1.0f, -1.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { -1.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, -1.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
};
view->SizeInBytes = sizeof(vertices);
view->SizeInBytes = sizeof(vertices);
view->StrideInBytes = sizeof(*vertices);
d3d12_create_vertex_buffer(device, view, vbo);
{
void *vertex_data_begin;
D3D12_RANGE read_range = {0, 0};
void * vertex_data_begin;
D3D12_RANGE read_range = { 0, 0 };
D3D12Map(*vbo, 0, &read_range, &vertex_data_begin);
memcpy(vertex_data_begin, vertices, sizeof(vertices));
D3D12Unmap(*vbo, 0, NULL);
}
}
DXGI_FORMAT d3d12_get_closest_match(
D3D12Device device, DXGI_FORMAT desired_format, D3D12_FORMAT_SUPPORT1 desired_format_support)
{
DXGI_FORMAT *format = dxgi_get_format_fallback_list(desired_format);
UINT format_support;
while (*format != DXGI_FORMAT_UNKNOWN)
{
D3D12_FEATURE_DATA_FORMAT_SUPPORT format_support = { *format };
if (SUCCEEDED(D3D12CheckFeatureSupport(
device, D3D12_FEATURE_FORMAT_SUPPORT, &format_support, sizeof(format_support))) &&
((format_support.Support1 & desired_format_support) == desired_format_support))
break;
format++;
}
assert(*format);
return *format;
}

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,7 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <dynamic/dylib.h>
#include "dxgi_common.h"
@ -20,20 +21,222 @@
HRESULT WINAPI CreateDXGIFactory1(REFIID riid, void **ppFactory)
{
static dylib_t dxgi_dll;
static HRESULT (WINAPI *fp)(REFIID, void **);
static HRESULT(WINAPI * fp)(REFIID, void **);
if(!dxgi_dll)
if (!dxgi_dll)
dxgi_dll = dylib_load("dxgi.dll");
if(!dxgi_dll)
if (!dxgi_dll)
return TYPE_E_CANTLOADLIBRARY;
if(!fp)
fp = (HRESULT (WINAPI *)(REFIID, void **))dylib_proc(dxgi_dll, "CreateDXGIFactory1");
if (!fp)
fp = (HRESULT(WINAPI *)(REFIID, void **))dylib_proc(dxgi_dll, "CreateDXGIFactory1");
if(!fp)
if (!fp)
return TYPE_E_CANTLOADLIBRARY;
return fp(riid, ppFactory);
}
DXGI_FORMAT *dxgi_get_format_fallback_list(DXGI_FORMAT format)
{
static DXGI_FORMAT format_unknown = DXGI_FORMAT_UNKNOWN;
switch ((unsigned)format)
{
case DXGI_FORMAT_R8G8B8A8_UNORM:
{
static DXGI_FORMAT formats[] = { DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM,
DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_UNKNOWN };
return formats;
}
case DXGI_FORMAT_B8G8R8A8_UNORM:
{
static DXGI_FORMAT formats[] = { DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM,
DXGI_FORMAT_UNKNOWN };
return formats;
}
case DXGI_FORMAT_B8G8R8X8_UNORM:
{
static DXGI_FORMAT formats[] = { DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM,
DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN };
return formats;
}
case DXGI_FORMAT_B5G6R5_UNORM:
{
static DXGI_FORMAT formats[] = { DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B8G8R8X8_UNORM,
DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM,
DXGI_FORMAT_UNKNOWN };
return formats;
}
case DXGI_FORMAT_EX_A4R4G4B4_UNORM:
case DXGI_FORMAT_B4G4R4A4_UNORM:
{
static DXGI_FORMAT formats[] = { DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM,
DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN };
return formats;
}
default:
assert(0);
}
return &format_unknown;
}
#define FORMAT_PROCESS_( \
src_type, src_rb, src_gb, src_bb, src_ab, src_rs, src_gs, src_bs, src_as, dst_type, dst_rb, \
dst_gb, dst_bb, dst_ab, dst_rs, dst_gs, dst_bs, dst_as) \
do \
{ \
if (((src_rs == dst_rs && src_rb == dst_rb) || !dst_rb) && \
((src_gs == dst_gs && src_gb == dst_gb) || !dst_gb) && \
((src_bs == dst_bs && src_bb == dst_bb) || !dst_bb) && \
((src_as == dst_as && src_ab == dst_ab) || !dst_ab)) \
{ \
const UINT8 *in = src_data; \
UINT8 * out = dst_data; \
for (i = 0; i < height; i++) \
{ \
memcpy(out, in, width * sizeof(src_type)); \
in += src_pitch ? src_pitch : width * sizeof(src_type); \
out += dst_pitch ? dst_pitch : width * sizeof(dst_type); \
} \
} \
else \
{ \
const src_type *src_ptr = (const src_type *)src_data; \
dst_type * dst_ptr = (dst_type *)dst_data; \
if (src_pitch) \
src_pitch -= width * sizeof(*src_ptr); \
if (dst_pitch) \
dst_pitch -= width * sizeof(*dst_ptr); \
for (i = 0; i < height; i++) \
{ \
for (j = 0; j < width; j++) \
{ \
unsigned r, g, b, a; \
src_type src_val = *src_ptr++; \
if (src_rb) \
{ \
r = (src_val >> src_rs) & ((1 << src_rb) - 1); \
r = (src_rb < dst_rb) \
? (r << (dst_rb - src_rb)) | \
(r >> ((2 * src_rb > dst_rb) ? 2 * src_rb - dst_rb : 0)) \
: r >> (src_rb - dst_rb); \
} \
if (src_gb) \
{ \
g = (src_val >> src_gs) & ((1 << src_gb) - 1); \
g = (src_gb < dst_gb) \
? (g << (dst_gb - src_gb)) | \
(g >> ((2 * src_gb > dst_gb) ? 2 * src_gb - dst_gb : 0)) \
: g >> (src_gb - dst_gb); \
} \
if (src_bb) \
{ \
b = (src_val >> src_bs) & ((1 << src_bb) - 1); \
b = (src_bb < dst_bb) \
? (b << (dst_bb - src_bb)) | \
(b >> ((2 * src_bb > dst_bb) ? 2 * src_bb - dst_bb : 0)) \
: b >> (src_bb - dst_bb); \
} \
if (src_ab) \
{ \
a = (src_val >> src_as) & ((1 << src_ab) - 1); \
a = (src_ab < dst_ab) \
? (a << (dst_ab - src_ab)) | \
(a >> ((2 * src_ab > dst_ab) ? 2 * src_ab - dst_ab : 0)) \
: a >> (src_ab - dst_ab); \
} \
*dst_ptr++ = ((src_rb ? r : 0) << dst_rs) | ((src_gb ? g : 0) << dst_gs) | \
((src_bb ? b : 0) << dst_bs) | \
((src_ab ? a : ((1 << dst_ab) - 1)) << dst_as); \
} \
src_ptr = (src_type *)((UINT8 *)src_ptr + src_pitch); \
dst_ptr = (dst_type *)((UINT8 *)dst_ptr + dst_pitch); \
} \
} \
} while (0)
#define FORMAT_PROCESS(args) FORMAT_PROCESS_ args
#define FORMAT_DST(st, dt) \
case dt: \
{ \
FORMAT_PROCESS((st##_DESCS, dt##_DESCS)); \
break; \
}
#define FORMAT_SRC(st) \
case st: \
{ \
switch ((unsigned)dst_format) \
{ \
FORMAT_DST_LIST(st); \
default: \
assert(0); \
break; \
} \
break; \
}
/* r, g, b, a r, g, b, a */
#define DXGI_FORMAT_R8G8B8A8_UNORM_DESCS UINT32, 8, 8, 8, 8, 0, 8, 16, 24
#define DXGI_FORMAT_B8G8R8X8_UNORM_DESCS UINT32, 8, 8, 8, 0, 16, 8, 0, 0
#define DXGI_FORMAT_B8G8R8A8_UNORM_DESCS UINT32, 8, 8, 8, 8, 16, 8, 0, 24
#define DXGI_FORMAT_B5G6R5_UNORM_DESCS UINT16, 5, 6, 5, 0, 11, 5, 0, 0
#define DXGI_FORMAT_B5G5R5A1_UNORM_DESCS UINT16, 5, 5, 5, 1, 10, 5, 0, 11
#define DXGI_FORMAT_B4G4R4A4_UNORM_DESCS UINT16, 4, 4, 4, 4, 8, 4, 0, 12
#define DXGI_FORMAT_EX_A4R4G4B4_UNORM_DESCS UINT16, 4, 4, 4, 4, 4, 8, 12, 0
#define FORMAT_SRC_LIST() \
FORMAT_SRC(DXGI_FORMAT_R8G8B8A8_UNORM); \
FORMAT_SRC(DXGI_FORMAT_B8G8R8X8_UNORM); \
FORMAT_SRC(DXGI_FORMAT_B5G6R5_UNORM); \
FORMAT_SRC(DXGI_FORMAT_B5G5R5A1_UNORM); \
FORMAT_SRC(DXGI_FORMAT_B4G4R4A4_UNORM); \
FORMAT_SRC(DXGI_FORMAT_B8G8R8A8_UNORM); \
FORMAT_SRC(DXGI_FORMAT_EX_A4R4G4B4_UNORM)
#define FORMAT_DST_LIST(srcfmt) \
FORMAT_DST(srcfmt, DXGI_FORMAT_R8G8B8A8_UNORM); \
FORMAT_DST(srcfmt, DXGI_FORMAT_B8G8R8X8_UNORM); \
FORMAT_DST(srcfmt, DXGI_FORMAT_B5G6R5_UNORM); \
FORMAT_DST(srcfmt, DXGI_FORMAT_B5G5R5A1_UNORM); \
FORMAT_DST(srcfmt, DXGI_FORMAT_B4G4R4A4_UNORM); \
FORMAT_DST(srcfmt, DXGI_FORMAT_B8G8R8A8_UNORM); \
FORMAT_DST(srcfmt, DXGI_FORMAT_EX_A4R4G4B4_UNORM)
#ifdef _MSC_VER
#pragma warning(disable : 4293)
#endif
void dxgi_copy(
int width,
int height,
DXGI_FORMAT src_format,
int src_pitch,
const void *src_data,
DXGI_FORMAT dst_format,
int dst_pitch,
void * dst_data)
{
int i, j;
#if defined(PERF_START) && defined(PERF_STOP)
PERF_START();
#endif
switch ((unsigned)src_format)
{
FORMAT_SRC_LIST();
default:
assert(0);
break;
}
#if defined(PERF_START) && defined(PERF_STOP)
PERF_STOP();
#endif
}
#ifdef _MSC_VER
#pragma warning(default : 4293)
#endif

View File

@ -10,14 +10,15 @@
#endif
#define CINTERFACE
#include <assert.h>
#include <dxgi1_5.h>
#ifndef countof
#define countof(a) (sizeof(a)/ sizeof(*a))
#define countof(a) (sizeof(a) / sizeof(*a))
#endif
#ifndef __uuidof
#define __uuidof(type) &IID_##type
#define __uuidof(type) & IID_##type
#endif
#ifndef COM_RELEASE_DECLARED
@ -25,12 +26,18 @@
#if defined(__cplusplus) && !defined(CINTERFACE)
static inline ULONG Release(IUnknown* object)
{
return object->Release();
if (object)
return object->Release();
return 0;
}
#else
static inline ULONG Release(void* object)
{
return ((IUnknown*)object)->lpVtbl->Release(object);
if (object)
return ((IUnknown*)object)->lpVtbl->Release(object);
return 0;
}
#endif
#endif
@ -93,10 +100,7 @@ static inline HRESULT DXGIMap(DXGISurface surface, DXGI_MAPPED_RECT* locked_rect
{
return surface->lpVtbl->Map(surface, locked_rect, map_flags);
}
static inline HRESULT DXGIUnmap(DXGISurface surface)
{
return surface->lpVtbl->Unmap(surface);
}
static inline HRESULT DXGIUnmap(DXGISurface surface) { return surface->lpVtbl->Unmap(surface); }
static inline HRESULT DXGIGetDC(DXGISurface surface, BOOL discard, HDC* hdc)
{
return surface->lpVtbl->GetDC(surface, discard, hdc);
@ -105,17 +109,20 @@ static inline HRESULT DXGIReleaseDC(DXGISurface surface, RECT* dirty_rect)
{
return surface->lpVtbl->ReleaseDC(surface, dirty_rect);
}
static inline ULONG DXGIReleaseOutput(DXGIOutput output)
{
return output->lpVtbl->Release(output);
}
static inline HRESULT DXGIGetDisplayModeList(DXGIOutput output, DXGI_FORMAT enum_format, UINT flags, UINT* num_modes, DXGI_MODE_DESC* desc)
static inline ULONG DXGIReleaseOutput(DXGIOutput output) { return output->lpVtbl->Release(output); }
static inline HRESULT DXGIGetDisplayModeList(
DXGIOutput output, DXGI_FORMAT enum_format, UINT flags, UINT* num_modes, DXGI_MODE_DESC* desc)
{
return output->lpVtbl->GetDisplayModeList(output, enum_format, flags, num_modes, desc);
}
static inline HRESULT DXGIFindClosestMatchingMode(DXGIOutput output, DXGI_MODE_DESC* mode_to_match, DXGI_MODE_DESC* closest_match, void* concerned_device)
static inline HRESULT DXGIFindClosestMatchingMode(
DXGIOutput output,
DXGI_MODE_DESC* mode_to_match,
DXGI_MODE_DESC* closest_match,
void* concerned_device)
{
return output->lpVtbl->FindClosestMatchingMode(output, mode_to_match, closest_match, (IUnknown*)concerned_device);
return output->lpVtbl->FindClosestMatchingMode(
output, mode_to_match, closest_match, (IUnknown*)concerned_device);
}
static inline HRESULT DXGIWaitForVBlank(DXGIOutput output)
{
@ -129,7 +136,8 @@ static inline void DXGIReleaseOwnership(DXGIOutput output)
{
output->lpVtbl->ReleaseOwnership(output);
}
static inline HRESULT DXGIGetGammaControlCapabilities(DXGIOutput output, DXGI_GAMMA_CONTROL_CAPABILITIES* gamma_caps)
static inline HRESULT
DXGIGetGammaControlCapabilities(DXGIOutput output, DXGI_GAMMA_CONTROL_CAPABILITIES* gamma_caps)
{
return output->lpVtbl->GetGammaControlCapabilities(output, gamma_caps);
}
@ -149,13 +157,17 @@ static inline HRESULT DXGIGetDisplaySurfaceData(DXGIOutput output, DXGISurface d
{
return output->lpVtbl->GetDisplaySurfaceData(output, (IDXGISurface*)destination);
}
static inline ULONG DXGIReleaseDevice(DXGIDevice device)
static inline ULONG DXGIReleaseDevice(DXGIDevice device) { return device->lpVtbl->Release(device); }
static inline HRESULT DXGICreateSurface(
DXGIDevice device,
DXGI_SURFACE_DESC* desc,
UINT num_surfaces,
DXGI_USAGE usage,
DXGI_SHARED_RESOURCE* shared_resource,
DXGISurface* surface)
{
return device->lpVtbl->Release(device);
}
static inline HRESULT DXGICreateSurface(DXGIDevice device, DXGI_SURFACE_DESC* desc, UINT num_surfaces, DXGI_USAGE usage, DXGI_SHARED_RESOURCE* shared_resource, DXGISurface* surface)
{
return device->lpVtbl->CreateSurface(device, desc, num_surfaces, usage, shared_resource, (IDXGISurface**)surface);
return device->lpVtbl->CreateSurface(
device, desc, num_surfaces, usage, shared_resource, (IDXGISurface**)surface);
}
static inline HRESULT DXGISetGPUThreadPriority(DXGIDevice device, INT priority)
{
@ -177,11 +189,14 @@ static inline HRESULT DXGIGetWindowAssociation(DXGIFactory factory, HWND* window
{
return factory->lpVtbl->GetWindowAssociation(factory, window_handle);
}
static inline HRESULT DXGICreateSwapChain(DXGIFactory factory, void* device, DXGI_SWAP_CHAIN_DESC* desc, DXGISwapChain* swap_chain)
static inline HRESULT DXGICreateSwapChain(
DXGIFactory factory, void* device, DXGI_SWAP_CHAIN_DESC* desc, DXGISwapChain* swap_chain)
{
return factory->lpVtbl->CreateSwapChain(factory, (IUnknown*)device, desc, (IDXGISwapChain**)swap_chain);
return factory->lpVtbl->CreateSwapChain(
factory, (IUnknown*)device, desc, (IDXGISwapChain**)swap_chain);
}
static inline HRESULT DXGICreateSoftwareAdapter(DXGIFactory factory, HMODULE module, DXGIAdapter* adapter)
static inline HRESULT
DXGICreateSoftwareAdapter(DXGIFactory factory, HMODULE module, DXGIAdapter* adapter)
{
return factory->lpVtbl->CreateSoftwareAdapter(factory, module, (IDXGIAdapter**)adapter);
}
@ -201,7 +216,8 @@ static inline HRESULT DXGIEnumOutputs(DXGIAdapter adapter, UINT id, DXGIOutput*
{
return adapter->lpVtbl->EnumOutputs(adapter, id, output);
}
static inline HRESULT DXGICheckInterfaceSupport(DXGIAdapter adapter, REFGUID interface_name, LARGE_INTEGER* u_m_d_version)
static inline HRESULT
DXGICheckInterfaceSupport(DXGIAdapter adapter, REFGUID interface_name, LARGE_INTEGER* u_m_d_version)
{
return adapter->lpVtbl->CheckInterfaceSupport(adapter, interface_name, u_m_d_version);
}
@ -225,23 +241,49 @@ static inline ULONG DXGIReleaseOutputDuplication(DXGIOutputDuplication output_du
{
return output_duplication->lpVtbl->Release(output_duplication);
}
static inline HRESULT DXGIAcquireNextFrame(DXGIOutputDuplication output_duplication, UINT timeout_in_milliseconds, DXGI_OUTDUPL_FRAME_INFO* frame_info, void* desktop_resource)
static inline HRESULT DXGIAcquireNextFrame(
DXGIOutputDuplication output_duplication,
UINT timeout_in_milliseconds,
DXGI_OUTDUPL_FRAME_INFO* frame_info,
void* desktop_resource)
{
return output_duplication->lpVtbl->AcquireNextFrame(output_duplication, timeout_in_milliseconds, frame_info, (IDXGIResource**)desktop_resource);
return output_duplication->lpVtbl->AcquireNextFrame(
output_duplication, timeout_in_milliseconds, frame_info,
(IDXGIResource**)desktop_resource);
}
static inline HRESULT DXGIGetFrameDirtyRects(DXGIOutputDuplication output_duplication, UINT dirty_rects_buffer_size, RECT* dirty_rects_buffer, UINT* dirty_rects_buffer_size_required)
static inline HRESULT DXGIGetFrameDirtyRects(
DXGIOutputDuplication output_duplication,
UINT dirty_rects_buffer_size,
RECT* dirty_rects_buffer,
UINT* dirty_rects_buffer_size_required)
{
return output_duplication->lpVtbl->GetFrameDirtyRects(output_duplication, dirty_rects_buffer_size, dirty_rects_buffer, dirty_rects_buffer_size_required);
return output_duplication->lpVtbl->GetFrameDirtyRects(
output_duplication, dirty_rects_buffer_size, dirty_rects_buffer,
dirty_rects_buffer_size_required);
}
static inline HRESULT DXGIGetFrameMoveRects(DXGIOutputDuplication output_duplication, UINT move_rects_buffer_size, DXGI_OUTDUPL_MOVE_RECT* move_rect_buffer, UINT* move_rects_buffer_size_required)
static inline HRESULT DXGIGetFrameMoveRects(
DXGIOutputDuplication output_duplication,
UINT move_rects_buffer_size,
DXGI_OUTDUPL_MOVE_RECT* move_rect_buffer,
UINT* move_rects_buffer_size_required)
{
return output_duplication->lpVtbl->GetFrameMoveRects(output_duplication, move_rects_buffer_size, move_rect_buffer, move_rects_buffer_size_required);
return output_duplication->lpVtbl->GetFrameMoveRects(
output_duplication, move_rects_buffer_size, move_rect_buffer,
move_rects_buffer_size_required);
}
static inline HRESULT DXGIGetFramePointerShape(DXGIOutputDuplication output_duplication, UINT pointer_shape_buffer_size, void* pointer_shape_buffer, UINT* pointer_shape_buffer_size_required, DXGI_OUTDUPL_POINTER_SHAPE_INFO* pointer_shape_info)
static inline HRESULT DXGIGetFramePointerShape(
DXGIOutputDuplication output_duplication,
UINT pointer_shape_buffer_size,
void* pointer_shape_buffer,
UINT* pointer_shape_buffer_size_required,
DXGI_OUTDUPL_POINTER_SHAPE_INFO* pointer_shape_info)
{
return output_duplication->lpVtbl->GetFramePointerShape(output_duplication, pointer_shape_buffer_size, pointer_shape_buffer, pointer_shape_buffer_size_required, pointer_shape_info);
return output_duplication->lpVtbl->GetFramePointerShape(
output_duplication, pointer_shape_buffer_size, pointer_shape_buffer,
pointer_shape_buffer_size_required, pointer_shape_info);
}
static inline HRESULT DXGIMapDesktopSurface(DXGIOutputDuplication output_duplication, DXGI_MAPPED_RECT* locked_rect)
static inline HRESULT
DXGIMapDesktopSurface(DXGIOutputDuplication output_duplication, DXGI_MAPPED_RECT* locked_rect)
{
return output_duplication->lpVtbl->MapDesktopSurface(output_duplication, locked_rect);
}
@ -257,9 +299,11 @@ static inline ULONG DXGIReleaseDecodeSwapChain(DXGIDecodeSwapChain decode_swap_c
{
return decode_swap_chain->lpVtbl->Release(decode_swap_chain);
}
static inline HRESULT DXGIPresentBuffer(DXGIDecodeSwapChain decode_swap_chain, UINT buffer_to_present, UINT sync_interval, UINT flags)
static inline HRESULT DXGIPresentBuffer(
DXGIDecodeSwapChain decode_swap_chain, UINT buffer_to_present, UINT sync_interval, UINT flags)
{
return decode_swap_chain->lpVtbl->PresentBuffer(decode_swap_chain, buffer_to_present, sync_interval, flags);
return decode_swap_chain->lpVtbl->PresentBuffer(
decode_swap_chain, buffer_to_present, sync_interval, flags);
}
static inline HRESULT DXGISetSourceRect(DXGIDecodeSwapChain decode_swap_chain, RECT* rect)
{
@ -269,7 +313,8 @@ static inline HRESULT DXGISetTargetRect(DXGIDecodeSwapChain decode_swap_chain, R
{
return decode_swap_chain->lpVtbl->SetTargetRect(decode_swap_chain, rect);
}
static inline HRESULT DXGISetDestSize(DXGIDecodeSwapChain decode_swap_chain, UINT width, UINT height)
static inline HRESULT
DXGISetDestSize(DXGIDecodeSwapChain decode_swap_chain, UINT width, UINT height)
{
return decode_swap_chain->lpVtbl->SetDestSize(decode_swap_chain, width, height);
}
@ -281,15 +326,18 @@ static inline HRESULT DXGIGetTargetRect(DXGIDecodeSwapChain decode_swap_chain, R
{
return decode_swap_chain->lpVtbl->GetTargetRect(decode_swap_chain, rect);
}
static inline HRESULT DXGIGetDestSize(DXGIDecodeSwapChain decode_swap_chain, UINT* width, UINT* height)
static inline HRESULT
DXGIGetDestSize(DXGIDecodeSwapChain decode_swap_chain, UINT* width, UINT* height)
{
return decode_swap_chain->lpVtbl->GetDestSize(decode_swap_chain, width, height);
}
static inline HRESULT DXGISetColorSpace(DXGIDecodeSwapChain decode_swap_chain, DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAGS color_space)
static inline HRESULT DXGISetColorSpace(
DXGIDecodeSwapChain decode_swap_chain, DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAGS color_space)
{
return decode_swap_chain->lpVtbl->SetColorSpace(decode_swap_chain, color_space);
}
static inline DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAGS DXGIGetColorSpace(DXGIDecodeSwapChain decode_swap_chain)
static inline DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAGS
DXGIGetColorSpace(DXGIDecodeSwapChain decode_swap_chain)
{
return decode_swap_chain->lpVtbl->GetColorSpace(decode_swap_chain);
}
@ -297,19 +345,37 @@ static inline ULONG DXGIReleaseFactoryMedia(DXGIFactoryMedia factory_media)
{
return factory_media->lpVtbl->Release(factory_media);
}
static inline HRESULT DXGICreateSwapChainForCompositionSurfaceHandle(DXGIFactoryMedia factory_media, void* device, HANDLE h_surface, DXGI_SWAP_CHAIN_DESC1* desc, DXGIOutput restrict_to_output, DXGISwapChain* swap_chain)
static inline HRESULT DXGICreateSwapChainForCompositionSurfaceHandle(
DXGIFactoryMedia factory_media,
void* device,
HANDLE h_surface,
DXGI_SWAP_CHAIN_DESC1* desc,
DXGIOutput restrict_to_output,
DXGISwapChain* swap_chain)
{
return factory_media->lpVtbl->CreateSwapChainForCompositionSurfaceHandle(factory_media, (IUnknown*)device, h_surface, desc, restrict_to_output, (IDXGISwapChain1**)swap_chain);
return factory_media->lpVtbl->CreateSwapChainForCompositionSurfaceHandle(
factory_media, (IUnknown*)device, h_surface, desc, restrict_to_output,
(IDXGISwapChain1**)swap_chain);
}
static inline HRESULT DXGICreateDecodeSwapChainForCompositionSurfaceHandle(DXGIFactoryMedia factory_media, void* device, HANDLE h_surface, DXGI_DECODE_SWAP_CHAIN_DESC* desc, void* yuv_decode_buffers, DXGIOutput restrict_to_output, DXGIDecodeSwapChain* swap_chain)
static inline HRESULT DXGICreateDecodeSwapChainForCompositionSurfaceHandle(
DXGIFactoryMedia factory_media,
void* device,
HANDLE h_surface,
DXGI_DECODE_SWAP_CHAIN_DESC* desc,
void* yuv_decode_buffers,
DXGIOutput restrict_to_output,
DXGIDecodeSwapChain* swap_chain)
{
return factory_media->lpVtbl->CreateDecodeSwapChainForCompositionSurfaceHandle(factory_media, (IUnknown*)device, h_surface, desc, (IDXGIResource*)yuv_decode_buffers, restrict_to_output, swap_chain);
return factory_media->lpVtbl->CreateDecodeSwapChainForCompositionSurfaceHandle(
factory_media, (IUnknown*)device, h_surface, desc, (IDXGIResource*)yuv_decode_buffers,
restrict_to_output, swap_chain);
}
static inline ULONG DXGIReleaseSwapChainMedia(DXGISwapChainMedia swap_chain_media)
{
return swap_chain_media->lpVtbl->Release(swap_chain_media);
}
static inline HRESULT DXGIGetFrameStatisticsMedia(DXGISwapChainMedia swap_chain_media, DXGI_FRAME_STATISTICS_MEDIA* stats)
static inline HRESULT
DXGIGetFrameStatisticsMedia(DXGISwapChainMedia swap_chain_media, DXGI_FRAME_STATISTICS_MEDIA* stats)
{
return swap_chain_media->lpVtbl->GetFrameStatisticsMedia(swap_chain_media, stats);
}
@ -317,9 +383,15 @@ static inline HRESULT DXGISetPresentDuration(DXGISwapChainMedia swap_chain_media
{
return swap_chain_media->lpVtbl->SetPresentDuration(swap_chain_media, duration);
}
static inline HRESULT DXGICheckPresentDurationSupport(DXGISwapChainMedia swap_chain_media, UINT desired_present_duration, UINT* closest_smaller_present_duration, UINT* closest_larger_present_duration)
static inline HRESULT DXGICheckPresentDurationSupport(
DXGISwapChainMedia swap_chain_media,
UINT desired_present_duration,
UINT* closest_smaller_present_duration,
UINT* closest_larger_present_duration)
{
return swap_chain_media->lpVtbl->CheckPresentDurationSupport(swap_chain_media, desired_present_duration, closest_smaller_present_duration, closest_larger_present_duration);
return swap_chain_media->lpVtbl->CheckPresentDurationSupport(
swap_chain_media, desired_present_duration, closest_smaller_present_duration,
closest_larger_present_duration);
}
static inline ULONG DXGIReleaseSwapChain(DXGISwapChain swap_chain)
{
@ -333,19 +405,29 @@ static inline HRESULT DXGIGetBuffer(DXGISwapChain swap_chain, UINT buffer, IDXGI
{
return swap_chain->lpVtbl->GetBuffer(swap_chain, buffer, __uuidof(IDXGISurface), (void**)out);
}
static inline HRESULT DXGISetFullscreenState(DXGISwapChain swap_chain, BOOL fullscreen, DXGIOutput target)
static inline HRESULT
DXGISetFullscreenState(DXGISwapChain swap_chain, BOOL fullscreen, DXGIOutput target)
{
return swap_chain->lpVtbl->SetFullscreenState(swap_chain, fullscreen, target);
}
static inline HRESULT DXGIGetFullscreenState(DXGISwapChain swap_chain, BOOL* fullscreen, DXGIOutput* target)
static inline HRESULT
DXGIGetFullscreenState(DXGISwapChain swap_chain, BOOL* fullscreen, DXGIOutput* target)
{
return swap_chain->lpVtbl->GetFullscreenState(swap_chain, fullscreen, target);
}
static inline HRESULT DXGIResizeBuffers(DXGISwapChain swap_chain, UINT buffer_count, UINT width, UINT height, DXGI_FORMAT new_format, UINT swap_chain_flags)
static inline HRESULT DXGIResizeBuffers(
DXGISwapChain swap_chain,
UINT buffer_count,
UINT width,
UINT height,
DXGI_FORMAT new_format,
UINT swap_chain_flags)
{
return swap_chain->lpVtbl->ResizeBuffers(swap_chain, buffer_count, width, height, new_format, swap_chain_flags);
return swap_chain->lpVtbl->ResizeBuffers(
swap_chain, buffer_count, width, height, new_format, swap_chain_flags);
}
static inline HRESULT DXGIResizeTarget(DXGISwapChain swap_chain, DXGI_MODE_DESC* new_target_parameters)
static inline HRESULT
DXGIResizeTarget(DXGISwapChain swap_chain, DXGI_MODE_DESC* new_target_parameters)
{
return swap_chain->lpVtbl->ResizeTarget(swap_chain, new_target_parameters);
}
@ -365,7 +447,8 @@ static inline HRESULT DXGIGetSwapChainDesc1(DXGISwapChain swap_chain, DXGI_SWAP_
{
return swap_chain->lpVtbl->GetDesc1(swap_chain, desc);
}
static inline HRESULT DXGIGetFullscreenDesc(DXGISwapChain swap_chain, DXGI_SWAP_CHAIN_FULLSCREEN_DESC* desc)
static inline HRESULT
DXGIGetFullscreenDesc(DXGISwapChain swap_chain, DXGI_SWAP_CHAIN_FULLSCREEN_DESC* desc)
{
return swap_chain->lpVtbl->GetFullscreenDesc(swap_chain, desc);
}
@ -373,15 +456,21 @@ static inline HRESULT DXGIGetHwnd(DXGISwapChain swap_chain, HWND* hwnd)
{
return swap_chain->lpVtbl->GetHwnd(swap_chain, hwnd);
}
static inline HRESULT DXGIPresent1(DXGISwapChain swap_chain, UINT sync_interval, UINT present_flags, DXGI_PRESENT_PARAMETERS* present_parameters)
static inline HRESULT DXGIPresent1(
DXGISwapChain swap_chain,
UINT sync_interval,
UINT present_flags,
DXGI_PRESENT_PARAMETERS* present_parameters)
{
return swap_chain->lpVtbl->Present1(swap_chain, sync_interval, present_flags, present_parameters);
return swap_chain->lpVtbl->Present1(
swap_chain, sync_interval, present_flags, present_parameters);
}
static inline BOOL DXGIIsTemporaryMonoSupported(DXGISwapChain swap_chain)
{
return swap_chain->lpVtbl->IsTemporaryMonoSupported(swap_chain);
}
static inline HRESULT DXGIGetRestrictToOutput(DXGISwapChain swap_chain, DXGIOutput* restrict_to_output)
static inline HRESULT
DXGIGetRestrictToOutput(DXGISwapChain swap_chain, DXGIOutput* restrict_to_output)
{
return swap_chain->lpVtbl->GetRestrictToOutput(swap_chain, restrict_to_output);
}
@ -433,11 +522,13 @@ static inline UINT DXGIGetCurrentBackBufferIndex(DXGISwapChain swap_chain)
{
return swap_chain->lpVtbl->GetCurrentBackBufferIndex(swap_chain);
}
static inline HRESULT DXGICheckColorSpaceSupport(DXGISwapChain swap_chain, DXGI_COLOR_SPACE_TYPE color_space, UINT* color_space_support)
static inline HRESULT DXGICheckColorSpaceSupport(
DXGISwapChain swap_chain, DXGI_COLOR_SPACE_TYPE color_space, UINT* color_space_support)
{
return swap_chain->lpVtbl->CheckColorSpaceSupport(swap_chain, color_space, color_space_support);
}
static inline HRESULT DXGISetColorSpace1(DXGISwapChain swap_chain, DXGI_COLOR_SPACE_TYPE color_space)
static inline HRESULT
DXGISetColorSpace1(DXGISwapChain swap_chain, DXGI_COLOR_SPACE_TYPE color_space)
{
return swap_chain->lpVtbl->SetColorSpace1(swap_chain, color_space);
}
@ -448,3 +539,40 @@ static inline HRESULT DXGICreateFactory(DXGIFactory* factory)
{
return CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)factory);
}
/* internal */
typedef enum {
DXGI_FORMAT_EX_A4R4G4B4_UNORM = 1000,
} DXGI_FORMAT_EX;
DXGI_FORMAT* dxgi_get_format_fallback_list(DXGI_FORMAT format);
void dxgi_copy(
int width,
int height,
DXGI_FORMAT src_format,
int src_pitch,
const void* src_data,
DXGI_FORMAT dst_format,
int dst_pitch,
void* dst_data);
#if 1
#include <performance_counters.h>
#ifndef PERF_START
#define PERF_START() \
static struct retro_perf_counter perfcounter = { __FUNCTION__ }; \
LARGE_INTEGER start, stop; \
rarch_perf_register(&perfcounter); \
perfcounter.call_cnt++; \
QueryPerformanceCounter(&start)
#define PERF_STOP() \
QueryPerformanceCounter(&stop); \
perfcounter.total += stop.QuadPart - start.QuadPart
#endif
#else
#define PERF_START()
#define PERF_STOP()
#endif

View File

@ -75,7 +75,7 @@ const GUID GUID_DEVINTERFACE_HID = { 0x4d1e55b2, 0xf16f, 0x11Cf, { 0x88, 0xcb, 0
static HDEVNOTIFY notification_handler;
#endif
#if defined(HAVE_D3D9) || defined(HAVE_D3D8)
#if defined(HAVE_D3D8) || defined(HAVE_D3D9) || defined (HAVE_D3D10) || defined (HAVE_D3D11) || defined (HAVE_D3D12)
extern bool dinput_handle_message(void *dinput, UINT message,
WPARAM wParam, LPARAM lParam);
extern void *dinput_gdi;
@ -569,7 +569,7 @@ static void win32_set_droppable(ui_window_win32_t *window, bool droppable)
DragAcceptFiles_func(window->hwnd, droppable);
}
#if defined(HAVE_D3D9) || defined(HAVE_D3D8)
#if defined(HAVE_D3D8) || defined(HAVE_D3D9) || defined (HAVE_D3D10) || defined (HAVE_D3D11) || defined (HAVE_D3D12)
LRESULT CALLBACK WndProcD3D(HWND hwnd, UINT message,
WPARAM wparam, LPARAM lparam)
{

View File

@ -127,7 +127,7 @@ bool win32_taskbar_is_created(void);
void win32_set_taskbar_created(bool created);
#if defined(HAVE_D3D9) || defined(HAVE_D3D8)
#if defined(HAVE_D3D8) || defined(HAVE_D3D9) || defined (HAVE_D3D10) || defined (HAVE_D3D11) || defined (HAVE_D3D12)
LRESULT CALLBACK WndProcD3D(HWND hwnd, UINT message,
WPARAM wparam, LPARAM lparam);
#endif

View File

@ -37,7 +37,9 @@
#include "../font_driver.h"
#include "../video_driver.h"
#if defined(HAVE_D3D8) || defined(HAVE_D3D9)
#include "../common/d3d_common.h"
#endif
#ifdef _XBOX
#include "../../defines/xdk_defines.h"
#endif

446
gfx/drivers/d3d10.c Normal file
View File

@ -0,0 +1,446 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2018 - Ali Bouhlel
*
* RetroArch 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 Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch 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 for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <string/stdstring.h>
#include "driver.h"
#include "verbosity.h"
#include "configuration.h"
#include "gfx/video_driver.h"
#include "gfx/common/win32_common.h"
#include "gfx/common/d3d10_common.h"
#include "gfx/common/dxgi_common.h"
#include "gfx/common/d3dcompiler_common.h"
static void*
d3d10_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data)
{
WNDCLASSEX wndclass = { 0 };
settings_t* settings = config_get_ptr();
gfx_ctx_input_t inp = { input, input_data };
d3d10_video_t* d3d10 = (d3d10_video_t*)calloc(1, sizeof(*d3d10));
if (!d3d10)
return NULL;
win32_window_reset();
win32_monitor_init();
wndclass.lpfnWndProc = WndProcD3D;
win32_window_init(&wndclass, true, NULL);
if (!win32_set_video_mode(d3d10, video->width, video->height, video->fullscreen))
{
RARCH_ERR("[D3D10]: win32_set_video_mode failed.\n");
goto error;
}
gfx_ctx_d3d.input_driver(NULL, settings->arrays.input_joypad_driver, input, input_data);
{
UINT flags = 0;
DXGI_SWAP_CHAIN_DESC desc = {
.BufferCount = 2,
.BufferDesc.Width = video->width,
.BufferDesc.Height = video->height,
.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM,
// .BufferDesc.RefreshRate.Numerator = 60,
// .BufferDesc.RefreshRate.Denominator = 1,
.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT,
.OutputWindow = main_window.hwnd,
.SampleDesc.Count = 1,
.SampleDesc.Quality = 0,
.Windowed = TRUE,
.SwapEffect = DXGI_SWAP_EFFECT_DISCARD,
#if 0
.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL,
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL,
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD,
#endif
};
#ifdef DEBUG
flags |= D3D10_CREATE_DEVICE_DEBUG;
#endif
D3D10CreateDeviceAndSwapChain(
NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D10_SDK_VERSION, &desc,
(IDXGISwapChain**)&d3d10->swapChain, &d3d10->device);
}
{
D3D10Texture2D backBuffer;
DXGIGetSwapChainBufferD3D10(d3d10->swapChain, 0, &backBuffer);
D3D10CreateTexture2DRenderTargetView(
d3d10->device, backBuffer, NULL, &d3d10->renderTargetView);
Release(backBuffer);
}
D3D10SetRenderTargets(d3d10->device, 1, &d3d10->renderTargetView, NULL);
{
D3D10_VIEWPORT vp = { 0, 0, video->width, video->height, 0.0f, 1.0f };
D3D10SetViewports(d3d10->device, 1, &vp);
}
d3d10->vsync = video->vsync;
d3d10->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM;
d3d10->frame.texture.desc.Format =
d3d10_get_closest_match_texture2D(d3d10->device, d3d10->format);
d3d10->frame.texture.desc.Usage = D3D10_USAGE_DEFAULT;
d3d10->menu.texture.desc.Usage = D3D10_USAGE_DEFAULT;
{
D3D10_SAMPLER_DESC desc = {
.Filter = D3D10_FILTER_MIN_MAG_MIP_POINT,
.AddressU = D3D10_TEXTURE_ADDRESS_BORDER,
.AddressV = D3D10_TEXTURE_ADDRESS_BORDER,
.AddressW = D3D10_TEXTURE_ADDRESS_BORDER,
.MaxAnisotropy = 1,
.ComparisonFunc = D3D10_COMPARISON_NEVER,
.MinLOD = -D3D10_FLOAT32_MAX,
.MaxLOD = D3D10_FLOAT32_MAX,
};
D3D10CreateSamplerState(d3d10->device, &desc, &d3d10->sampler_nearest);
desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
D3D10CreateSamplerState(d3d10->device, &desc, &d3d10->sampler_linear);
}
{
d3d10_vertex_t vertices[] = {
{ { -1.0f, -1.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { -1.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, -1.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
};
{
D3D10_BUFFER_DESC desc = {
.ByteWidth = sizeof(vertices),
.Usage = D3D10_USAGE_DYNAMIC,
.BindFlags = D3D10_BIND_VERTEX_BUFFER,
.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE,
};
D3D10_SUBRESOURCE_DATA vertexData = { vertices };
D3D10CreateBuffer(d3d10->device, &desc, &vertexData, &d3d10->frame.vbo);
desc.Usage = D3D10_USAGE_IMMUTABLE;
desc.CPUAccessFlags = 0;
D3D10CreateBuffer(d3d10->device, &desc, &vertexData, &d3d10->menu.vbo);
}
D3D10SetPrimitiveTopology(d3d10->device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
}
{
D3DBlob vs_code;
D3DBlob ps_code;
static const char stock[] =
#include "d3d_shaders/opaque_sm5.hlsl.h"
;
D3D10_INPUT_ELEMENT_DESC desc[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d10_vertex_t, position),
D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d10_vertex_t, texcoord),
D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d10_vertex_t, color),
D3D10_INPUT_PER_VERTEX_DATA, 0 },
};
d3d_compile(stock, sizeof(stock), "VSMain", "vs_4_0", &vs_code);
d3d_compile(stock, sizeof(stock), "PSMain", "ps_4_0", &ps_code);
D3D10CreateVertexShader(
d3d10->device, D3DGetBufferPointer(vs_code), D3DGetBufferSize(vs_code), &d3d10->vs);
D3D10CreatePixelShader(
d3d10->device, D3DGetBufferPointer(ps_code), D3DGetBufferSize(ps_code), &d3d10->ps);
D3D10CreateInputLayout(
d3d10->device, desc, countof(desc), D3DGetBufferPointer(vs_code),
D3DGetBufferSize(vs_code), &d3d10->layout);
Release(vs_code);
Release(ps_code);
}
D3D10SetInputLayout(d3d10->device, d3d10->layout);
D3D10SetVShader(d3d10->device, d3d10->vs);
D3D10SetPShader(d3d10->device, d3d10->ps);
{
D3D10_BLEND_DESC blend_desc = {
.AlphaToCoverageEnable = FALSE,
.BlendEnable = { TRUE },
D3D10_BLEND_SRC_ALPHA,
D3D10_BLEND_INV_SRC_ALPHA,
D3D10_BLEND_OP_ADD,
D3D10_BLEND_SRC_ALPHA,
D3D10_BLEND_INV_SRC_ALPHA,
D3D10_BLEND_OP_ADD,
{ D3D10_COLOR_WRITE_ENABLE_ALL },
};
D3D10CreateBlendState(d3d10->device, &blend_desc, &d3d10->blend_enable);
blend_desc.BlendEnable[0] = FALSE;
D3D10CreateBlendState(d3d10->device, &blend_desc, &d3d10->blend_disable);
}
return d3d10;
error:
free(d3d10);
return NULL;
}
static bool d3d10_gfx_frame(
void* data,
const void* frame,
unsigned width,
unsigned height,
uint64_t frame_count,
unsigned pitch,
const char* msg,
video_frame_info_t* video_info)
{
(void)msg;
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
PERF_START();
D3D10ClearRenderTargetView(d3d10->device, d3d10->renderTargetView, d3d10->clearcolor);
if (frame && width && height)
{
D3D10_BOX frame_box = { 0, 0, 0, width, height, 1 };
if (d3d10->frame.texture.desc.Width != width || d3d10->frame.texture.desc.Height != height)
{
d3d10->frame.texture.desc.Width = width;
d3d10->frame.texture.desc.Height = height;
d3d10_init_texture(d3d10->device, &d3d10->frame.texture);
}
d3d10_update_texture(width, height, pitch, d3d10->format, frame, &d3d10->frame.texture);
D3D10CopyTexture2DSubresourceRegion(
d3d10->device, d3d10->frame.texture.handle, 0, 0, 0, 0, d3d10->frame.texture.staging, 0,
&frame_box);
}
{
UINT stride = sizeof(d3d10_vertex_t);
UINT offset = 0;
D3D10SetVertexBuffers(d3d10->device, 0, 1, &d3d10->frame.vbo, &stride, &offset);
D3D10SetPShaderResources(d3d10->device, 0, 1, &d3d10->frame.texture.view);
D3D10SetPShaderSamplers(d3d10->device, 0, 1, &d3d10->sampler_linear);
D3D10SetBlendState(d3d10->device, d3d10->blend_disable, NULL, D3D10_DEFAULT_SAMPLE_MASK);
D3D10Draw(d3d10->device, 4, 0);
D3D10SetBlendState(d3d10->device, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK);
if (d3d10->menu.enabled)
{
if (d3d10->menu.texture.dirty)
D3D10CopyTexture2DSubresourceRegion(
d3d10->device, d3d10->menu.texture.handle, 0, 0, 0, 0,
d3d10->menu.texture.staging, 0, NULL);
D3D10SetVertexBuffers(d3d10->device, 0, 1, &d3d10->menu.vbo, &stride, &offset);
D3D10SetPShaderResources(d3d10->device, 0, 1, &d3d10->menu.texture.view);
D3D10SetPShaderSamplers(d3d10->device, 0, 1, &d3d10->sampler_linear);
D3D10Draw(d3d10->device, 4, 0);
}
}
DXGIPresent(d3d10->swapChain, !d3d10->vsync, 0);
PERF_STOP();
if (msg && *msg)
gfx_ctx_d3d.update_window_title(NULL, video_info);
return true;
}
static void d3d10_gfx_set_nonblock_state(void* data, bool toggle)
{
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
d3d10->vsync = !toggle;
}
static bool d3d10_gfx_alive(void* data)
{
(void)data;
bool quit;
bool resize;
unsigned width;
unsigned height;
win32_check_window(&quit, &resize, &width, &height);
if (width != 0 && height != 0)
video_driver_set_size(&width, &height);
return !quit;
}
static bool d3d10_gfx_focus(void* data) { return win32_has_focus(); }
static bool d3d10_gfx_suppress_screensaver(void* data, bool enable)
{
(void)data;
(void)enable;
return false;
}
static bool d3d10_gfx_has_windowed(void* data)
{
(void)data;
return true;
}
static void d3d10_gfx_free(void* data)
{
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
Release(d3d10->frame.texture.view);
Release(d3d10->frame.texture.handle);
Release(d3d10->frame.texture.staging);
Release(d3d10->frame.vbo);
Release(d3d10->menu.texture.handle);
Release(d3d10->menu.texture.staging);
Release(d3d10->menu.texture.view);
Release(d3d10->menu.vbo);
Release(d3d10->blend_enable);
Release(d3d10->blend_disable);
Release(d3d10->sampler_nearest);
Release(d3d10->sampler_linear);
Release(d3d10->ps);
Release(d3d10->vs);
Release(d3d10->layout);
Release(d3d10->renderTargetView);
Release(d3d10->swapChain);
Release(d3d10->device);
win32_monitor_from_window();
win32_destroy_window();
free(d3d10);
}
static bool d3d10_gfx_set_shader(void* data, enum rarch_shader_type type, const char* path)
{
(void)data;
(void)type;
(void)path;
return false;
}
static void d3d10_gfx_set_rotation(void* data, unsigned rotation)
{
(void)data;
(void)rotation;
}
static void d3d10_gfx_viewport_info(void* data, struct video_viewport* vp)
{
(void)data;
(void)vp;
}
static bool d3d10_gfx_read_viewport(void* data, uint8_t* buffer, bool is_idle)
{
(void)data;
(void)buffer;
return true;
}
static void d3d10_set_menu_texture_frame(
void* data, const void* frame, bool rgb32, unsigned width, unsigned height, float alpha)
{
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
int pitch = width * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t));
DXGI_FORMAT format = rgb32 ? DXGI_FORMAT_B8G8R8A8_UNORM : DXGI_FORMAT_EX_A4R4G4B4_UNORM;
if (d3d10->menu.texture.desc.Width != width || d3d10->menu.texture.desc.Height != height)
{
d3d10->menu.texture.desc.Format = d3d10_get_closest_match_texture2D(d3d10->device, format);
d3d10->menu.texture.desc.Width = width;
d3d10->menu.texture.desc.Height = height;
d3d10_init_texture(d3d10->device, &d3d10->menu.texture);
}
d3d10_update_texture(width, height, pitch, format, frame, &d3d10->menu.texture);
}
static void d3d10_set_menu_texture_enable(void* data, bool state, bool full_screen)
{
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
d3d10->menu.enabled = state;
d3d10->menu.fullscreen = full_screen;
}
static const video_poke_interface_t d3d10_poke_interface = {
NULL, /* set_coords */
NULL, /* set_mvp */
NULL, /* load_texture */
NULL, /* unload_texture */
NULL, /* set_video_mode */
NULL, /* set_filtering */
NULL, /* get_video_output_size */
NULL, /* get_video_output_prev */
NULL, /* get_video_output_next */
NULL, /* get_current_framebuffer */
NULL, /* get_proc_address */
NULL, /* set_aspect_ratio */
NULL, /* apply_state_changes */
d3d10_set_menu_texture_frame, /* set_texture_frame */
d3d10_set_menu_texture_enable, /* set_texture_enable */
NULL, /* set_osd_msg */
NULL, /* show_mouse */
NULL, /* grab_mouse_toggle */
NULL, /* get_current_shader */
NULL, /* get_current_software_framebuffer */
NULL, /* get_hw_render_interface */
};
static void d3d10_gfx_get_poke_interface(void* data, const video_poke_interface_t** iface)
{
*iface = &d3d10_poke_interface;
}
video_driver_t video_d3d10 = {
d3d10_gfx_init,
d3d10_gfx_frame,
d3d10_gfx_set_nonblock_state,
d3d10_gfx_alive,
d3d10_gfx_focus,
d3d10_gfx_suppress_screensaver,
d3d10_gfx_has_windowed,
d3d10_gfx_set_shader,
d3d10_gfx_free,
"d3d10",
NULL, /* set_viewport */
d3d10_gfx_set_rotation,
d3d10_gfx_viewport_info,
d3d10_gfx_read_viewport,
NULL, /* read_frame_raw */
#ifdef HAVE_OVERLAY
NULL, /* overlay_interface */
#endif
d3d10_gfx_get_poke_interface,
};

View File

@ -24,55 +24,16 @@
#include "gfx/common/d3d11_common.h"
#include "gfx/common/dxgi_common.h"
#include "gfx/common/d3dcompiler_common.h"
#include "performance_counters.h"
#include <gfx/scaler/pixconv.h>
typedef struct d3d11_vertex_t
static void*
d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data)
{
float position[2];
float texcoord[2];
float color[4];
} d3d11_vertex_t;
typedef struct
{
unsigned cur_mon_id;
DXGISwapChain swapChain;
D3D11Device device;
D3D_FEATURE_LEVEL supportedFeatureLevel;
D3D11DeviceContext context;
D3D11RenderTargetView renderTargetView;
D3D11Buffer vertexBuffer;
D3D11InputLayout layout;
D3D11VertexShader vs;
D3D11PixelShader ps;
D3D11SamplerState sampler_nearest;
D3D11SamplerState sampler_linear;
D3D11Texture2D frame_default;
D3D11Texture2D frame_staging;
struct
{
D3D11Texture2D tex;
D3D11ShaderResourceView view;
D3D11Buffer vbo;
int width;
int height;
bool enabled;
bool fullscreen;
} menu;
int frame_width;
int frame_height;
D3D11ShaderResourceView frame_view;
float clearcolor[4];
bool vsync;
bool rgb32;
} d3d11_video_t;
static void* d3d11_gfx_init(const video_info_t* video,
const input_driver_t** input, void** input_data)
{
WNDCLASSEX wndclass = {0};
settings_t* settings = config_get_ptr();
gfx_ctx_input_t inp = {input, input_data};
d3d11_video_t* d3d11 = (d3d11_video_t*)calloc(1, sizeof(*d3d11));
WNDCLASSEX wndclass = { 0 };
settings_t* settings = config_get_ptr();
gfx_ctx_input_t inp = { input, input_data };
d3d11_video_t* d3d11 = (d3d11_video_t*)calloc(1, sizeof(*d3d11));
if (!d3d11)
return NULL;
@ -82,24 +43,18 @@ static void* d3d11_gfx_init(const video_info_t* video,
wndclass.lpfnWndProc = WndProcD3D;
win32_window_init(&wndclass, true, NULL);
if (!win32_set_video_mode(d3d11, video->width,
video->height, video->fullscreen))
if (!win32_set_video_mode(d3d11, video->width, video->height, video->fullscreen))
{
RARCH_ERR("[D3D11]: win32_set_video_mode failed.\n");
goto error;
}
gfx_ctx_d3d.input_driver(NULL, settings->arrays.input_joypad_driver,
input, input_data);
d3d11->rgb32 = video->rgb32;
d3d11->vsync = video->vsync;
gfx_ctx_d3d.input_driver(NULL, settings->arrays.input_joypad_driver, input, input_data);
{
UINT flags = 0;
D3D_FEATURE_LEVEL requested_feature_level = D3D_FEATURE_LEVEL_11_0;
DXGI_SWAP_CHAIN_DESC desc =
{
UINT flags = 0;
D3D_FEATURE_LEVEL requested_feature_level = D3D_FEATURE_LEVEL_11_0;
DXGI_SWAP_CHAIN_DESC desc = {
.BufferCount = 1,
.BufferDesc.Width = video->width,
.BufferDesc.Height = video->height,
@ -120,78 +75,42 @@ static void* d3d11_gfx_init(const video_info_t* video,
};
#ifdef DEBUG
flags |= D3D11_CREATE_DEVICE_DEBUG;
flags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE,
NULL, flags,
&requested_feature_level, 1, D3D11_SDK_VERSION, &desc,
(IDXGISwapChain**)&d3d11->swapChain, &d3d11->device,
&d3d11->supportedFeatureLevel, &d3d11->context);
D3D11CreateDeviceAndSwapChain(
NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, &requested_feature_level, 1,
D3D11_SDK_VERSION, &desc, (IDXGISwapChain**)&d3d11->swapChain, &d3d11->device,
&d3d11->supportedFeatureLevel, &d3d11->ctx);
}
{
D3D11Texture2D backBuffer;
DXGIGetSwapChainBufferD3D11(d3d11->swapChain, 0, &backBuffer);
D3D11CreateTexture2DRenderTargetView(d3d11->device, backBuffer,
NULL, &d3d11->renderTargetView);
D3D11CreateTexture2DRenderTargetView(
d3d11->device, backBuffer, NULL, &d3d11->renderTargetView);
Release(backBuffer);
}
D3D11SetRenderTargets(d3d11->context, 1,
&d3d11->renderTargetView, NULL);
D3D11SetRenderTargets(d3d11->ctx, 1, &d3d11->renderTargetView, NULL);
{
D3D11_VIEWPORT vp = {0, 0, video->width, video->height, 0.0f, 1.0f};
D3D11SetViewports(d3d11->context, 1, &vp);
D3D11_VIEWPORT vp = { 0, 0, video->width, video->height, 0.0f, 1.0f };
D3D11SetViewports(d3d11->ctx, 1, &vp);
}
d3d11->vsync = video->vsync;
d3d11->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM;
d3d11->frame_width = video->input_scale * RARCH_SCALE_BASE;
d3d11->frame_height = video->input_scale * RARCH_SCALE_BASE;
{
D3D11_TEXTURE2D_DESC desc =
{
.Width = d3d11->frame_width,
.Height = d3d11->frame_height,
.MipLevels = 1,
.ArraySize = 1,
.Format = DXGI_FORMAT_B8G8R8A8_UNORM,
#if 0
.Format = d3d11->rgb32 ?
DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM,
#endif
.SampleDesc.Count = 1,
.SampleDesc.Quality = 0,
.Usage = D3D11_USAGE_DEFAULT,
.BindFlags = D3D11_BIND_SHADER_RESOURCE,
.CPUAccessFlags = 0,
.MiscFlags = 0,
};
D3D11_SHADER_RESOURCE_VIEW_DESC view_desc =
{
.Format = desc.Format,
.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D,
.Texture2D.MostDetailedMip = 0,
.Texture2D.MipLevels = -1,
};
d3d11->frame.texture.desc.Format =
d3d11_get_closest_match_texture2D(d3d11->device, d3d11->format);
d3d11->frame.texture.desc.Usage = D3D11_USAGE_DEFAULT;
D3D11CreateTexture2D(d3d11->device,
&desc, NULL, &d3d11->frame_default);
D3D11CreateTexture2DShaderResourceView(d3d11->device,
d3d11->frame_default, &view_desc, &d3d11->frame_view);
desc.Format = desc.Format;
desc.BindFlags = 0;
desc.Usage = D3D11_USAGE_STAGING;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
D3D11CreateTexture2D(d3d11->device, &desc,
NULL, &d3d11->frame_staging);
}
d3d11->menu.texture.desc.Format = DXGI_FORMAT_B4G4R4A4_UNORM;
d3d11->menu.texture.desc.Usage = D3D11_USAGE_DEFAULT;
{
D3D11_SAMPLER_DESC desc =
{
D3D11_SAMPLER_DESC desc = {
.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT,
.AddressU = D3D11_TEXTURE_ADDRESS_BORDER,
.AddressV = D3D11_TEXTURE_ADDRESS_BORDER,
@ -208,70 +127,89 @@ static void* d3d11_gfx_init(const video_info_t* video,
}
{
d3d11_vertex_t vertices[] =
{
{{ -1.0f, -1.0f}, {0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}},
{{ -1.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}},
{{ 1.0f, -1.0f}, {1.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}},
{{ 1.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}},
d3d11_vertex_t vertices[] = {
{ { -1.0f, -1.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { -1.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, -1.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
};
{
D3D11_BUFFER_DESC desc =
{
D3D11_BUFFER_DESC desc = {
.Usage = D3D11_USAGE_DYNAMIC,
.ByteWidth = sizeof(vertices),
.BindFlags = D3D11_BIND_VERTEX_BUFFER,
.StructureByteStride = 0, /* sizeof(Vertex) ? */
.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE,
};
D3D11_SUBRESOURCE_DATA vertexData = {vertices};
D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->vertexBuffer);
D3D11_SUBRESOURCE_DATA vertexData = { vertices };
D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->frame.vbo);
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.CPUAccessFlags = 0;
D3D11CreateBuffer(d3d11->device, &desc,
&vertexData, &d3d11->menu.vbo);
D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->menu.vbo);
}
D3D11SetPrimitiveTopology(d3d11->context,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
D3D11SetPrimitiveTopology(d3d11->ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
}
{
D3DBlob vs_code;
D3DBlob ps_code;
static const char stock [] =
static const char stock[] =
#include "d3d_shaders/opaque_sm5.hlsl.h"
;
;
D3D11_INPUT_ELEMENT_DESC desc[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_vertex_t, position), D3D11_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_vertex_t, texcoord), D3D11_INPUT_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d11_vertex_t, color), D3D11_INPUT_PER_VERTEX_DATA, 0},
D3D11_INPUT_ELEMENT_DESC desc[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_vertex_t, position),
D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_vertex_t, texcoord),
D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d11_vertex_t, color),
D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
d3d_compile(stock, sizeof(stock), "VSMain", "vs_5_0", &vs_code);
d3d_compile(stock, sizeof(stock), "PSMain", "ps_5_0", &ps_code);
D3D11CreateVertexShader(d3d11->device,
D3DGetBufferPointer(vs_code), D3DGetBufferSize(vs_code),
NULL, &d3d11->vs);
D3D11CreatePixelShader(d3d11->device,
D3DGetBufferPointer(ps_code), D3DGetBufferSize(ps_code),
NULL, &d3d11->ps);
D3D11CreateInputLayout(d3d11->device, desc, countof(desc),
D3DGetBufferPointer(vs_code),
D3D11CreateVertexShader(
d3d11->device, D3DGetBufferPointer(vs_code), D3DGetBufferSize(vs_code), NULL,
&d3d11->vs);
D3D11CreatePixelShader(
d3d11->device, D3DGetBufferPointer(ps_code), D3DGetBufferSize(ps_code), NULL,
&d3d11->ps);
D3D11CreateInputLayout(
d3d11->device, desc, countof(desc), D3DGetBufferPointer(vs_code),
D3DGetBufferSize(vs_code), &d3d11->layout);
Release(vs_code);
Release(ps_code);
}
D3D11SetInputLayout(d3d11->context, d3d11->layout);
D3D11SetVShader(d3d11->context, d3d11->vs, NULL, 0);
D3D11SetPShader(d3d11->context, d3d11->ps, NULL, 0);
D3D11SetInputLayout(d3d11->ctx, d3d11->layout);
D3D11SetVShader(d3d11->ctx, d3d11->vs, NULL, 0);
D3D11SetPShader(d3d11->ctx, d3d11->ps, NULL, 0);
{
D3D11_BLEND_DESC blend_desc = {
.AlphaToCoverageEnable = FALSE,
.IndependentBlendEnable = FALSE,
.RenderTarget[0] =
{
.BlendEnable = TRUE,
D3D11_BLEND_SRC_ALPHA,
D3D11_BLEND_INV_SRC_ALPHA,
D3D11_BLEND_OP_ADD,
D3D11_BLEND_SRC_ALPHA,
D3D11_BLEND_INV_SRC_ALPHA,
D3D11_BLEND_OP_ADD,
D3D11_COLOR_WRITE_ENABLE_ALL,
},
};
D3D11CreateBlendState(d3d11->device, &blend_desc, &d3d11->blend_enable);
blend_desc.RenderTarget[0].BlendEnable = FALSE;
D3D11CreateBlendState(d3d11->device, &blend_desc, &d3d11->blend_disable);
}
return d3d11;
@ -280,113 +218,69 @@ error:
return NULL;
}
static bool d3d11_gfx_frame(void* data, const void* frame,
unsigned width, unsigned height, uint64_t frame_count,
unsigned pitch, const char* msg, video_frame_info_t* video_info)
static bool d3d11_gfx_frame(
void* data,
const void* frame,
unsigned width,
unsigned height,
uint64_t frame_count,
unsigned pitch,
const char* msg,
video_frame_info_t* video_info)
{
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
(void)msg;
PERF_START();
D3D11ClearRenderTargetView(d3d11->ctx, d3d11->renderTargetView, d3d11->clearcolor);
if(frame && width && height)
if (frame && width && height)
{
D3D11_MAPPED_SUBRESOURCE mapped_frame;
D3D11MapTexture2D(d3d11->context,
d3d11->frame_staging, 0, D3D11_MAP_WRITE, 0, &mapped_frame);
D3D11_BOX frame_box = { 0, 0, 0, width, height, 1 };
if (d3d11->frame.texture.desc.Width != width || d3d11->frame.texture.desc.Height != height)
{
unsigned i, j;
if (d3d11->rgb32)
{
const uint8_t *in = frame;
uint8_t *out = mapped_frame.pData;
for (i = 0; i < height; i++)
{
memcpy(out, in, width * (d3d11->rgb32? 4 : 2));
in += pitch;
out += mapped_frame.RowPitch;
}
}
else
{
const uint16_t *in = frame;
uint32_t *out = mapped_frame.pData;
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
unsigned b = ((in[j] >> 11) & 0x1F);
unsigned g = ((in[j] >> 5) & 0x3F);
unsigned r = ((in[j] >> 0) & 0x1F);
out[j] = ((r >> 2) << 0) | (r << 3) |
((g >> 4) << 8) | (g << 10) |
((b >> 2) << 16) | (b << 19);
}
in += width;
out += mapped_frame.RowPitch / 4;
}
}
d3d11->frame.texture.desc.Width = width;
d3d11->frame.texture.desc.Height = height;
d3d11_init_texture(d3d11->device, &d3d11->frame.texture);
}
D3D11UnmapTexture2D(d3d11->context, d3d11->frame_staging, 0);
D3D11_BOX frame_box = {0, 0, 0, width, height, 1};
D3D11CopyTexture2DSubresourceRegion(d3d11->context,
d3d11->frame_default, 0, 0 , 0 , 0,
d3d11->frame_staging, 0, &frame_box);
{
D3D11_MAPPED_SUBRESOURCE mapped_vbo;
D3D11MapBuffer(d3d11->context, d3d11->vertexBuffer,
0, D3D11_MAP_WRITE_NO_OVERWRITE, 0,
&mapped_vbo);
{
d3d11_vertex_t* vbo = mapped_vbo.pData;
vbo[0].texcoord[0] = 0.0f * (width / (float)d3d11->frame_width);
vbo[0].texcoord[1] = 1.0f * (height / (float)d3d11->frame_height);
vbo[1].texcoord[0] = 0.0f * (width / (float)d3d11->frame_width);
vbo[1].texcoord[1] = 0.0f * (height / (float)d3d11->frame_height);
vbo[2].texcoord[0] = 1.0f * (width / (float)d3d11->frame_width);
vbo[2].texcoord[1] = 1.0f * (height / (float)d3d11->frame_height);
vbo[3].texcoord[0] = 1.0f * (width / (float)d3d11->frame_width);
vbo[3].texcoord[1] = 0.0f * (height / (float)d3d11->frame_height);
}
D3D11UnmapBuffer(d3d11->context, d3d11->vertexBuffer, 0);
}
d3d11_update_texture(
d3d11->ctx, width, height, pitch, d3d11->format, frame, &d3d11->frame.texture);
D3D11CopyTexture2DSubresourceRegion(
d3d11->ctx, d3d11->frame.texture.handle, 0, 0, 0, 0, d3d11->frame.texture.staging, 0,
&frame_box);
}
D3D11ClearRenderTargetView(d3d11->context,
d3d11->renderTargetView, d3d11->clearcolor);
{
UINT stride = sizeof(d3d11_vertex_t);
UINT offset = 0;
D3D11SetVertexBuffers(d3d11->context, 0, 1,
&d3d11->vertexBuffer, &stride, &offset);
D3D11SetPShaderResources(d3d11->context, 0, 1, &d3d11->frame_view);
D3D11SetPShaderSamplers(d3d11->context, 0, 1, &d3d11->sampler_linear);
D3D11SetVertexBuffers(d3d11->ctx, 0, 1, &d3d11->frame.vbo, &stride, &offset);
D3D11SetPShaderResources(d3d11->ctx, 0, 1, &d3d11->frame.texture.view);
D3D11SetPShaderSamplers(d3d11->ctx, 0, 1, &d3d11->sampler_linear);
D3D11Draw(d3d11->context, 4, 0);
D3D11SetBlendState(d3d11->ctx, d3d11->blend_disable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
D3D11Draw(d3d11->ctx, 4, 0);
D3D11SetBlendState(d3d11->ctx, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
if (d3d11->menu.enabled)
if (d3d11->menu.enabled && d3d11->menu.texture.handle)
{
D3D11SetVertexBuffers(d3d11->context, 0, 1,
&d3d11->menu.vbo, &stride, &offset);
D3D11SetPShaderResources(d3d11->context, 0, 1,
&d3d11->menu.view);
D3D11SetPShaderSamplers(d3d11->context, 0, 1,
&d3d11->sampler_linear);
if (d3d11->menu.texture.dirty)
D3D11CopyTexture2DSubresourceRegion(
d3d11->ctx, d3d11->menu.texture.handle, 0, 0, 0, 0, d3d11->menu.texture.staging,
0, NULL);
D3D11Draw(d3d11->context, 4, 0);
D3D11SetVertexBuffers(d3d11->ctx, 0, 1, &d3d11->menu.vbo, &stride, &offset);
D3D11SetPShaderResources(d3d11->ctx, 0, 1, &d3d11->menu.texture.view);
D3D11SetPShaderSamplers(d3d11->ctx, 0, 1, &d3d11->sampler_linear);
D3D11Draw(d3d11->ctx, 4, 0);
}
}
DXGIPresent(d3d11->swapChain, !!d3d11->vsync, 0);
PERF_STOP();
if(msg && *msg)
if (msg && *msg)
gfx_ctx_d3d.update_window_title(NULL, video_info);
return true;
@ -404,8 +298,8 @@ static void d3d11_gfx_set_nonblock_state(void* data, bool toggle)
static bool d3d11_gfx_alive(void* data)
{
bool quit;
bool resize;
bool quit;
bool resize;
unsigned width;
unsigned height;
@ -419,10 +313,7 @@ static bool d3d11_gfx_alive(void* data)
return !quit;
}
static bool d3d11_gfx_focus(void* data)
{
return win32_has_focus();
}
static bool d3d11_gfx_focus(void* data) { return win32_has_focus(); }
static bool d3d11_gfx_suppress_screensaver(void* data, bool enable)
{
@ -444,25 +335,26 @@ static void d3d11_gfx_free(void* data)
if (!d3d11)
return;
if(d3d11->menu.tex)
Release(d3d11->menu.tex);
if(d3d11->menu.view)
Release(d3d11->menu.view);
Release(d3d11->frame.texture.view);
Release(d3d11->frame.texture.handle);
Release(d3d11->frame.texture.staging);
Release(d3d11->frame.vbo);
Release(d3d11->menu.texture.handle);
Release(d3d11->menu.texture.staging);
Release(d3d11->menu.texture.view);
Release(d3d11->menu.vbo);
Release(d3d11->blend_enable);
Release(d3d11->blend_disable);
Release(d3d11->sampler_nearest);
Release(d3d11->sampler_linear);
Release(d3d11->frame_view);
Release(d3d11->frame_default);
Release(d3d11->frame_staging);
Release(d3d11->ps);
Release(d3d11->vs);
Release(d3d11->vertexBuffer);
Release(d3d11->layout);
Release(d3d11->renderTargetView);
Release(d3d11->swapChain);
Release(d3d11->context);
Release(d3d11->ctx);
Release(d3d11->device);
win32_monitor_from_window();
@ -470,8 +362,7 @@ static void d3d11_gfx_free(void* data)
free(d3d11);
}
static bool d3d11_gfx_set_shader(void* data,
enum rarch_shader_type type, const char* path)
static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const char* path)
{
(void)data;
(void)type;
@ -480,22 +371,19 @@ static bool d3d11_gfx_set_shader(void* data,
return false;
}
static void d3d11_gfx_set_rotation(void* data,
unsigned rotation)
static void d3d11_gfx_set_rotation(void* data, unsigned rotation)
{
(void)data;
(void)rotation;
}
static void d3d11_gfx_viewport_info(void* data,
struct video_viewport* vp)
static void d3d11_gfx_viewport_info(void* data, struct video_viewport* vp)
{
(void)data;
(void)vp;
}
static bool d3d11_gfx_read_viewport(void* data,
uint8_t* buffer, bool is_idle)
static bool d3d11_gfx_read_viewport(void* data, uint8_t* buffer, bool is_idle)
{
(void)data;
(void)buffer;
@ -503,144 +391,64 @@ static bool d3d11_gfx_read_viewport(void* data,
return true;
}
static void d3d11_set_menu_texture_frame(void* data,
const void* frame, bool rgb32, unsigned width, unsigned height,
float alpha)
static void d3d11_set_menu_texture_frame(
void* data, const void* frame, bool rgb32, unsigned width, unsigned height, float alpha)
{
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
int pitch = width * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t));
DXGI_FORMAT format = rgb32 ? DXGI_FORMAT_B8G8R8A8_UNORM : DXGI_FORMAT_EX_A4R4G4B4_UNORM;
if ( d3d11->menu.tex &&
(d3d11->menu.width != width ||
d3d11->menu.height != height))
if (d3d11->menu.texture.desc.Width != width || d3d11->menu.texture.desc.Height != height)
{
Release(d3d11->menu.tex);
d3d11->menu.tex = NULL;
d3d11->menu.texture.desc.Format = d3d11_get_closest_match_texture2D(d3d11->device, format);
d3d11->menu.texture.desc.Width = width;
d3d11->menu.texture.desc.Height = height;
d3d11_init_texture(d3d11->device, &d3d11->menu.texture);
}
if (!d3d11->menu.tex)
{
d3d11->menu.width = width;
d3d11->menu.height = height;
D3D11_TEXTURE2D_DESC desc =
{
.Width = d3d11->menu.width,
.Height = d3d11->menu.height,
.MipLevels = 1,
.ArraySize = 1,
.Format = DXGI_FORMAT_R8G8B8A8_UNORM,
.SampleDesc.Count = 1,
.SampleDesc.Quality = 0,
.Usage = D3D11_USAGE_DYNAMIC,
.BindFlags = D3D11_BIND_SHADER_RESOURCE,
.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE,
.MiscFlags = 0,
};
D3D11_SHADER_RESOURCE_VIEW_DESC view_desc =
{
.Format = desc.Format,
.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D,
.Texture2D.MostDetailedMip = 0,
.Texture2D.MipLevels = -1,
};
D3D11CreateTexture2D(d3d11->device, &desc, NULL, &d3d11->menu.tex);
D3D11CreateTexture2DShaderResourceView(d3d11->device,
d3d11->menu.tex, &view_desc, &d3d11->menu.view);
}
{
D3D11_MAPPED_SUBRESOURCE mapped_frame;
D3D11MapTexture2D(d3d11->context,
d3d11->menu.tex, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_frame);
{
unsigned i, j;
if (rgb32)
{
const uint32_t *in = frame;
uint32_t *out = mapped_frame.pData;
for (i = 0; i < height; i++)
{
memcpy(out, in, width * 4);
in += width;
out += mapped_frame.RowPitch / 4;
}
}
else
{
const uint16_t *in = frame;
uint32_t *out = mapped_frame.pData;
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
unsigned r = ((in[j] >> 12) & 0xF);
unsigned g = ((in[j] >> 8) & 0xF);
unsigned b = ((in[j] >> 4) & 0xF);
unsigned a = ((in[j] >> 0) & 0xF);
out[j] = (r << 0) | (r << 4) | (g << 8)
| (g << 12) |(b << 16) | (b << 20)
| (a << 24) | (a << 28);
}
in += width;
out += mapped_frame.RowPitch / 4;
}
}
}
D3D11UnmapTexture2D(d3d11->context, d3d11->menu.tex, 0);
}
d3d11_update_texture(d3d11->ctx, width, height, pitch, format, frame, &d3d11->menu.texture);
}
static void d3d11_set_menu_texture_enable(void* data,
bool state, bool full_screen)
static void d3d11_set_menu_texture_enable(void* data, bool state, bool full_screen)
{
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
if (!d3d11)
return;
d3d11->menu.enabled = state;
d3d11->menu.fullscreen = full_screen;
d3d11->menu.enabled = state;
d3d11->menu.fullscreen = full_screen;
}
static const video_poke_interface_t d3d11_poke_interface =
{
NULL, /* set_coords */
NULL, /* set_mvp */
NULL, /* load_texture */
NULL, /* unload_texture */
NULL, /* set_video_mode */
NULL, /* set_filtering */
NULL, /* get_video_output_size */
NULL, /* get_video_output_prev */
NULL, /* get_video_output_next */
NULL, /* get_current_framebuffer */
NULL, /* get_proc_address */
NULL, /* set_aspect_ratio */
NULL, /* apply_state_changes */
d3d11_set_menu_texture_frame, /* set_texture_frame */
static const video_poke_interface_t d3d11_poke_interface = {
NULL, /* set_coords */
NULL, /* set_mvp */
NULL, /* load_texture */
NULL, /* unload_texture */
NULL, /* set_video_mode */
NULL, /* set_filtering */
NULL, /* get_video_output_size */
NULL, /* get_video_output_prev */
NULL, /* get_video_output_next */
NULL, /* get_current_framebuffer */
NULL, /* get_proc_address */
NULL, /* set_aspect_ratio */
NULL, /* apply_state_changes */
d3d11_set_menu_texture_frame, /* set_texture_frame */
d3d11_set_menu_texture_enable, /* set_texture_enable */
NULL, /* set_osd_msg */
NULL, /* show_mouse */
NULL, /* grab_mouse_toggle */
NULL, /* get_current_shader */
NULL, /* get_current_software_framebuffer */
NULL, /* get_hw_render_interface */
NULL, /* set_osd_msg */
NULL, /* show_mouse */
NULL, /* grab_mouse_toggle */
NULL, /* get_current_shader */
NULL, /* get_current_software_framebuffer */
NULL, /* get_hw_render_interface */
};
static void d3d11_gfx_get_poke_interface(void* data,
const video_poke_interface_t** iface)
static void d3d11_gfx_get_poke_interface(void* data, const video_poke_interface_t** iface)
{
*iface = &d3d11_poke_interface;
}
video_driver_t video_d3d11 =
{
video_driver_t video_d3d11 = {
d3d11_gfx_init,
d3d11_gfx_frame,
d3d11_gfx_set_nonblock_state,

View File

@ -25,9 +25,9 @@
#include "gfx/common/d3d12_common.h"
#include "gfx/common/d3dcompiler_common.h"
static void d3d12_set_filtering(void *data, unsigned index, bool smooth)
static void d3d12_set_filtering(void* data, unsigned index, bool smooth)
{
d3d12_video_t *d3d12 = (d3d12_video_t *)data;
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
if (smooth)
d3d12->frame.sampler = d3d12->sampler_linear;
@ -35,13 +35,13 @@ static void d3d12_set_filtering(void *data, unsigned index, bool smooth)
d3d12->frame.sampler = d3d12->sampler_nearest;
}
static void *d3d12_gfx_init(const video_info_t *video,
const input_driver_t **input, void **input_data)
static void*
d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data)
{
WNDCLASSEX wndclass = {0};
settings_t *settings = config_get_ptr();
gfx_ctx_input_t inp = {input, input_data};
d3d12_video_t *d3d12 = (d3d12_video_t *)calloc(1, sizeof(*d3d12));
WNDCLASSEX wndclass = { 0 };
settings_t* settings = config_get_ptr();
gfx_ctx_input_t inp = { input, input_data };
d3d12_video_t* d3d12 = (d3d12_video_t*)calloc(1, sizeof(*d3d12));
if (!d3d12)
return NULL;
@ -59,9 +59,6 @@ static void *d3d12_gfx_init(const video_info_t *video,
gfx_ctx_d3d.input_driver(NULL, settings->arrays.input_joypad_driver, input, input_data);
d3d12->chain.vsync = video->vsync;
d3d12->frame.rgb32 = video->rgb32;
if (!d3d12_init_base(d3d12))
goto error;
@ -78,10 +75,14 @@ static void *d3d12_gfx_init(const video_info_t *video,
goto error;
d3d12_create_fullscreen_quad_vbo(d3d12->device, &d3d12->frame.vbo_view, &d3d12->frame.vbo);
d3d12_create_fullscreen_quad_vbo(d3d12->device, &d3d12->menu.vbo_view, &d3d12->menu.vbo);
d3d12_create_fullscreen_quad_vbo(d3d12->device, &d3d12->menu.vbo_view, &d3d12->menu.vbo);
d3d12_set_filtering(d3d12, 0, video->smooth);
d3d12->chain.vsync = video->vsync;
d3d12->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM;
d3d12->frame.texture.desc.Format = d3d12_get_closest_match_texture2D(d3d12->device, d3d12->format);
return d3d12;
error:
@ -90,105 +91,87 @@ error:
return NULL;
}
static bool d3d12_gfx_frame(void *data, const void *frame,
unsigned width, unsigned height, uint64_t frame_count,
unsigned pitch, const char *msg, video_frame_info_t *video_info)
static bool d3d12_gfx_frame(
void* data,
const void* frame,
unsigned width,
unsigned height,
uint64_t frame_count,
unsigned pitch,
const char* msg,
video_frame_info_t* video_info)
{
d3d12_video_t *d3d12 = (d3d12_video_t *)data;
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
(void)msg;
PERF_START();
D3D12ResetCommandAllocator(d3d12->queue.allocator);
D3D12ResetGraphicsCommandList(d3d12->queue.cmd, d3d12->queue.allocator, d3d12->pipe.handle);
D3D12SetGraphicsRootSignature(d3d12->queue.cmd, d3d12->pipe.rootSignature);
{
D3D12DescriptorHeap desc_heaps [] = {d3d12->pipe.srv_heap.handle, d3d12->pipe.sampler_heap.handle};
D3D12DescriptorHeap desc_heaps[] = { d3d12->pipe.srv_heap.handle,
d3d12->pipe.sampler_heap.handle };
D3D12SetDescriptorHeaps(d3d12->queue.cmd, countof(desc_heaps), desc_heaps);
}
d3d12_resource_transition(d3d12->queue.cmd, d3d12->chain.renderTargets[d3d12->chain.frame_index],
D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
d3d12_resource_transition(
d3d12->queue.cmd, d3d12->chain.renderTargets[d3d12->chain.frame_index],
D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->chain.viewport);
D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->chain.scissorRect);
D3D12OMSetRenderTargets(d3d12->queue.cmd, 1, &d3d12->chain.desc_handles[d3d12->chain.frame_index],
FALSE, NULL);
D3D12ClearRenderTargetView(d3d12->queue.cmd, d3d12->chain.desc_handles[d3d12->chain.frame_index],
d3d12->chain.clearcolor, 0, NULL);
D3D12OMSetRenderTargets(
d3d12->queue.cmd, 1, &d3d12->chain.desc_handles[d3d12->chain.frame_index], FALSE, NULL);
D3D12ClearRenderTargetView(
d3d12->queue.cmd, d3d12->chain.desc_handles[d3d12->chain.frame_index],
d3d12->chain.clearcolor, 0, NULL);
D3D12IASetPrimitiveTopology(d3d12->queue.cmd, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
if (data && width && height)
{
if (!d3d12->frame.tex.handle || (d3d12->frame.tex.desc.Width != width)
|| (d3d12->frame.tex.desc.Height != height))
if (!d3d12->frame.texture.handle || (d3d12->frame.texture.desc.Width != width) ||
(d3d12->frame.texture.desc.Height != height))
{
if (d3d12->frame.tex.handle)
Release(d3d12->frame.tex.handle);
if (d3d12->frame.tex.upload_buffer)
Release(d3d12->frame.tex.upload_buffer);
d3d12->frame.tex.desc.Width = width;
d3d12->frame.tex.desc.Height = height;
d3d12->frame.tex.desc.Format = d3d12->frame.rgb32 ? DXGI_FORMAT_B8G8R8A8_UNORM :
DXGI_FORMAT_B5G6R5_UNORM;
d3d12_create_texture(d3d12->device, &d3d12->pipe.srv_heap, SRV_HEAP_SLOT_FRAME_TEXTURE,
&d3d12->frame.tex);
d3d12->frame.texture.desc.Width = width;
d3d12->frame.texture.desc.Height = height;
d3d12_init_texture(
d3d12->device, &d3d12->pipe.srv_heap, SRV_HEAP_SLOT_FRAME_TEXTURE,
&d3d12->frame.texture);
}
d3d12_update_texture(width, height, pitch, d3d12->format, frame, &d3d12->frame.texture);
{
unsigned i;
D3D12_RANGE read_range = {0, 0};
const uint8_t *in = frame;
uint8_t *out = NULL;
D3D12Map(d3d12->frame.tex.upload_buffer, 0, &read_range, &out);
out += d3d12->frame.tex.layout.Offset;
for (i = 0; i < height; i++)
{
memcpy(out, in, width * (d3d12->frame.rgb32 ? 4 : 2));
in += pitch;
out += d3d12->frame.tex.layout.Footprint.RowPitch;
}
D3D12Unmap(d3d12->frame.tex.upload_buffer, 0, NULL);
}
d3d12_upload_texture(d3d12->queue.cmd, &d3d12->frame.tex);
d3d12_set_texture(d3d12->queue.cmd, &d3d12->frame.tex);
d3d12_upload_texture(d3d12->queue.cmd, &d3d12->frame.texture);
d3d12_set_texture(d3d12->queue.cmd, &d3d12->frame.texture);
d3d12_set_sampler(d3d12->queue.cmd, d3d12->frame.sampler);
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->frame.vbo_view);
D3D12DrawInstanced(d3d12->queue.cmd, 4, 1, 0, 0);
}
if (d3d12->menu.enabled && d3d12->menu.tex.handle)
if (d3d12->menu.enabled && d3d12->menu.texture.handle)
{
if (d3d12->menu.tex.dirty)
d3d12_upload_texture(d3d12->queue.cmd, &d3d12->menu.tex);
if (d3d12->menu.texture.dirty)
d3d12_upload_texture(d3d12->queue.cmd, &d3d12->menu.texture);
d3d12_set_texture(d3d12->queue.cmd, &d3d12->menu.tex);
d3d12_set_texture(d3d12->queue.cmd, &d3d12->menu.texture);
d3d12_set_sampler(d3d12->queue.cmd, d3d12->menu.sampler);
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->menu.vbo_view);
D3D12DrawInstanced(d3d12->queue.cmd, 4, 1, 0, 0);
}
d3d12_resource_transition(d3d12->queue.cmd, d3d12->chain.renderTargets[d3d12->chain.frame_index],
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
d3d12_resource_transition(
d3d12->queue.cmd, d3d12->chain.renderTargets[d3d12->chain.frame_index],
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
D3D12CloseGraphicsCommandList(d3d12->queue.cmd);
D3D12ExecuteGraphicsCommandLists(d3d12->queue.handle, 1, &d3d12->queue.cmd);
#if 1
DXGIPresent(d3d12->chain.handle, !!d3d12->chain.vsync, 0);
// DXGIPresent(d3d12->chain.handle, !!d3d12->chain.vsync, 0);
DXGIPresent(d3d12->chain.handle, 0, 0);
#else
DXGI_PRESENT_PARAMETERS pp = {0};
DXGI_PRESENT_PARAMETERS pp = { 0 };
DXGIPresent1(d3d12->swapchain, 0, 0, &pp);
#endif
@ -197,12 +180,14 @@ static bool d3d12_gfx_frame(void *data, const void *frame,
if (D3D12GetCompletedValue(d3d12->queue.fence) < d3d12->queue.fenceValue)
{
D3D12SetEventOnCompletion(d3d12->queue.fence, d3d12->queue.fenceValue, d3d12->queue.fenceEvent);
D3D12SetEventOnCompletion(
d3d12->queue.fence, d3d12->queue.fenceValue, d3d12->queue.fenceEvent);
WaitForSingleObject(d3d12->queue.fenceEvent, INFINITE);
}
d3d12->queue.fenceValue++;
d3d12->chain.frame_index = DXGIGetCurrentBackBufferIndex(d3d12->chain.handle);
PERF_STOP();
if (msg && *msg)
gfx_ctx_d3d.update_window_title(NULL, video_info);
@ -210,17 +195,17 @@ static bool d3d12_gfx_frame(void *data, const void *frame,
return true;
}
static void d3d12_gfx_set_nonblock_state(void *data, bool toggle)
static void d3d12_gfx_set_nonblock_state(void* data, bool toggle)
{
d3d12_video_t *d3d12 = (d3d12_video_t *)data;
d3d12->chain.vsync = !toggle;
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
d3d12->chain.vsync = !toggle;
}
static bool d3d12_gfx_alive(void *data)
static bool d3d12_gfx_alive(void* data)
{
(void)data;
bool quit;
bool resize;
bool quit;
bool resize;
unsigned width;
unsigned height;
@ -232,43 +217,31 @@ static bool d3d12_gfx_alive(void *data)
return !quit;
}
static bool d3d12_gfx_focus(void *data)
{
return win32_has_focus();
}
static bool d3d12_gfx_focus(void* data) { return win32_has_focus(); }
static bool d3d12_gfx_suppress_screensaver(void *data, bool enable)
static bool d3d12_gfx_suppress_screensaver(void* data, bool enable)
{
(void)data;
(void)enable;
return false;
}
static bool d3d12_gfx_has_windowed(void *data)
static bool d3d12_gfx_has_windowed(void* data)
{
(void)data;
return true;
}
static void d3d12_gfx_free(void *data)
static void d3d12_gfx_free(void* data)
{
d3d12_video_t *d3d12 = (d3d12_video_t *)data;
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
Release(d3d12->frame.vbo);
if (d3d12->frame.tex.handle)
Release(d3d12->frame.tex.handle);
if (d3d12->frame.tex.upload_buffer)
Release(d3d12->frame.tex.upload_buffer);
Release(d3d12->frame.texture.handle);
Release(d3d12->frame.texture.upload_buffer);
Release(d3d12->menu.vbo);
if (d3d12->menu.tex.handle)
Release(d3d12->menu.tex.handle);
if (d3d12->menu.tex.handle)
Release(d3d12->menu.tex.upload_buffer);
Release(d3d12->menu.texture.handle);
Release(d3d12->menu.texture.upload_buffer);
Release(d3d12->pipe.sampler_heap.handle);
Release(d3d12->pipe.srv_heap.handle);
@ -295,8 +268,7 @@ static void d3d12_gfx_free(void *data)
free(d3d12);
}
static bool d3d12_gfx_set_shader(void *data,
enum rarch_shader_type type, const char *path)
static bool d3d12_gfx_set_shader(void* data, enum rarch_shader_type type, const char* path)
{
(void)data;
(void)type;
@ -305,21 +277,19 @@ static bool d3d12_gfx_set_shader(void *data,
return false;
}
static void d3d12_gfx_set_rotation(void *data,
unsigned rotation)
static void d3d12_gfx_set_rotation(void* data, unsigned rotation)
{
(void)data;
(void)rotation;
}
static void d3d12_gfx_viewport_info(void *data,
struct video_viewport *vp)
static void d3d12_gfx_viewport_info(void* data, struct video_viewport* vp)
{
(void)data;
(void)vp;
}
static bool d3d12_gfx_read_viewport(void *data, uint8_t *buffer, bool is_idle)
static bool d3d12_gfx_read_viewport(void* data, uint8_t* buffer, bool is_idle)
{
(void)data;
(void)buffer;
@ -327,78 +297,29 @@ static bool d3d12_gfx_read_viewport(void *data, uint8_t *buffer, bool is_idle)
return true;
}
static void d3d12_set_menu_texture_frame(void *data,
const void *frame, bool rgb32, unsigned width, unsigned height,
float alpha)
static void d3d12_set_menu_texture_frame(
void* data, const void* frame, bool rgb32, unsigned width, unsigned height, float alpha)
{
d3d12_video_t *d3d12 = (d3d12_video_t *)data;
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
int pitch = width * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t));
DXGI_FORMAT format = rgb32 ? DXGI_FORMAT_B8G8R8A8_UNORM : DXGI_FORMAT_EX_A4R4G4B4_UNORM;
if (!d3d12->menu.tex.handle || (d3d12->menu.tex.desc.Width != width)
|| (d3d12->menu.tex.desc.Height = height))
if (d3d12->menu.texture.desc.Width != width || d3d12->menu.texture.desc.Height != height)
{
if (d3d12->menu.tex.handle)
Release(d3d12->menu.tex.handle);
if (d3d12->menu.tex.upload_buffer)
Release(d3d12->menu.tex.upload_buffer);
d3d12->menu.tex.desc.Width = width;
d3d12->menu.tex.desc.Height = height;
d3d12->menu.tex.desc.Format = rgb32 ? DXGI_FORMAT_B8G8R8A8_UNORM : DXGI_FORMAT_B4G4R4A4_UNORM;
d3d12_create_texture(d3d12->device, &d3d12->pipe.srv_heap, SRV_HEAP_SLOT_MENU_TEXTURE,
&d3d12->menu.tex);
d3d12->menu.texture.desc.Width = width;
d3d12->menu.texture.desc.Height = height;
d3d12->menu.texture.desc.Format = d3d12_get_closest_match_texture2D(d3d12->device, format);
d3d12_init_texture(
d3d12->device, &d3d12->pipe.srv_heap, SRV_HEAP_SLOT_MENU_TEXTURE, &d3d12->menu.texture);
}
{
unsigned i, j;
D3D12_RANGE read_range = {0, 0};
uint8_t *out = NULL;
d3d12_update_texture(width, height, pitch, format, frame, &d3d12->menu.texture);
D3D12Map(d3d12->menu.tex.upload_buffer, 0, &read_range, &out);
out += d3d12->menu.tex.layout.Offset;
if (rgb32)
{
const uint32_t *in = frame;
for (i = 0; i < height; i++)
{
memcpy(out, in, width * sizeof(*in));
in += width;
out += d3d12->menu.tex.layout.Footprint.RowPitch;
}
}
else
{
const uint16_t *in = frame;
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
unsigned r = ((in[j] >> 12) & 0xF);
unsigned g = ((in[j] >> 8) & 0xF);
unsigned b = ((in[j] >> 4) & 0xF);
unsigned a = ((in[j] >> 0) & 0xF);
((uint16_t *)out)[j] = (b << 0) | (g << 4) | (r << 8) | (a << 12);
}
in += width;
out += d3d12->menu.tex.layout.Footprint.RowPitch;
}
}
D3D12Unmap(d3d12->menu.tex.upload_buffer, 0, NULL);
}
d3d12->menu.tex.dirty = true;
d3d12->menu.alpha = alpha;
{
D3D12_RANGE read_range = {0, 0};
d3d12_vertex_t *v;
D3D12_RANGE read_range = { 0, 0 };
d3d12_vertex_t* v;
D3D12Map(d3d12->menu.vbo, 0, &read_range, &v);
v[0].color[3] = alpha;
@ -407,51 +328,47 @@ static void d3d12_set_menu_texture_frame(void *data,
v[3].color[3] = alpha;
D3D12Unmap(d3d12->menu.vbo, 0, NULL);
}
d3d12->menu.sampler = config_get_ptr()->bools.menu_linear_filter ?
d3d12->sampler_linear : d3d12->sampler_nearest;
d3d12->menu.sampler = config_get_ptr()->bools.menu_linear_filter ? d3d12->sampler_linear
: d3d12->sampler_nearest;
}
static void d3d12_set_menu_texture_enable(void *data,
bool state, bool full_screen)
static void d3d12_set_menu_texture_enable(void* data, bool state, bool full_screen)
{
d3d12_video_t *d3d12 = (d3d12_video_t *)data;
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
d3d12->menu.enabled = state;
d3d12->menu.fullscreen = full_screen;
d3d12->menu.enabled = state;
d3d12->menu.fullscreen = full_screen;
}
static const video_poke_interface_t d3d12_poke_interface =
{
NULL, /* set_coords */
NULL, /* set_mvp */
NULL, /* load_texture */
NULL, /* unload_texture */
NULL, /* set_video_mode */
NULL, /* set_filtering */
NULL, /* get_video_output_size */
NULL, /* get_video_output_prev */
NULL, /* get_video_output_next */
NULL, /* get_current_framebuffer */
NULL, /* get_proc_address */
NULL, /* set_aspect_ratio */
NULL, /* apply_state_changes */
d3d12_set_menu_texture_frame, /* set_texture_frame */
static const video_poke_interface_t d3d12_poke_interface = {
NULL, /* set_coords */
NULL, /* set_mvp */
NULL, /* load_texture */
NULL, /* unload_texture */
NULL, /* set_video_mode */
NULL, /* set_filtering */
NULL, /* get_video_output_size */
NULL, /* get_video_output_prev */
NULL, /* get_video_output_next */
NULL, /* get_current_framebuffer */
NULL, /* get_proc_address */
NULL, /* set_aspect_ratio */
NULL, /* apply_state_changes */
d3d12_set_menu_texture_frame, /* set_texture_frame */
d3d12_set_menu_texture_enable, /* set_texture_enable */
NULL, /* set_osd_msg */
NULL, /* show_mouse */
NULL, /* grab_mouse_toggle */
NULL, /* get_current_shader */
NULL, /* get_current_software_framebuffer */
NULL, /* get_hw_render_interface */
NULL, /* set_osd_msg */
NULL, /* show_mouse */
NULL, /* grab_mouse_toggle */
NULL, /* get_current_shader */
NULL, /* get_current_software_framebuffer */
NULL, /* get_hw_render_interface */
};
static void d3d12_gfx_get_poke_interface(void *data,
const video_poke_interface_t **iface)
static void d3d12_gfx_get_poke_interface(void* data, const video_poke_interface_t** iface)
{
*iface = &d3d12_poke_interface;
}
video_driver_t video_d3d12 =
{
video_driver_t video_d3d12 = {
d3d12_gfx_init,
d3d12_gfx_frame,
d3d12_gfx_set_nonblock_state,

View File

@ -262,6 +262,9 @@ static const video_driver_t *video_drivers[] = {
#ifdef XENON
&video_xenon360,
#endif
#if defined(HAVE_D3D10)
&video_d3d10,
#endif
#if defined(HAVE_D3D11)
&video_d3d11,
#endif

View File

@ -1337,6 +1337,7 @@ extern video_driver_t video_ctr;
extern video_driver_t video_switch;
extern video_driver_t video_d3d8;
extern video_driver_t video_d3d9;
extern video_driver_t video_d3d10;
extern video_driver_t video_d3d11;
extern video_driver_t video_d3d12;
extern video_driver_t video_gx;

View File

@ -345,6 +345,11 @@ VIDEO DRIVER
#endif
#if defined(HAVE_D3D10)
#include "../gfx/drivers/d3d10.c"
#include "../gfx/common/d3d10_common.c"
#endif
#if defined(HAVE_D3D11)
#include "../gfx/drivers/d3d11.c"
#include "../gfx/common/d3d11_common.c"
@ -355,7 +360,7 @@ VIDEO DRIVER
#include "../gfx/common/d3d12_common.c"
#endif
#if defined(HAVE_D3D11) || defined(HAVE_D3D12)
#if defined(HAVE_D3D10) || defined(HAVE_D3D11) || defined(HAVE_D3D12)
#include "../gfx/common/d3dcompiler_common.c"
#include "../gfx/common/dxgi_common.c"
#endif

View File

@ -119,6 +119,8 @@ vector<string> overloaded_list =
"SetPrivateDataInterface",
"SetPrivateData",
"GetPrivateData",
"Map",
"Unmap",
"Reset",
"Signal",
"BeginEvent",
@ -136,6 +138,13 @@ vector<string> overloaded_list =
"GetContextFlags",
"GetCertificate",
"GetCertificateSize",
"Begin",
"End",
"GetData",
"CopySubresourceRegion",
"CreateRenderTargetView",
"CreateShaderResourceView",
};
vector<string> action_list =
@ -174,10 +183,11 @@ vector<string> base_objects_list =
{
"IUnknown",
"ID3D12Object",
"ID3D12Resource",
// "ID3D12Resource",
"IDXGIObject",
"IDXGIResource",
"D3D11Resource",
// "ID3D11Resource",
// "ID3D10Resource",
};
//string insert_name(const char* fname, const char* name)