Skip to content

Commit

Permalink
Libretro: add D3D12 support.
Browse files Browse the repository at this point in the history
  • Loading branch information
aliaspider committed Apr 9, 2023
1 parent ff89653 commit 8d56089
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 19 deletions.
32 changes: 29 additions & 3 deletions common/D3D12/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
#include <queue>
#include <vector>

#ifdef __LIBRETRO__
#include <libretro_d3d.h>
extern retro_environment_t environ_cb;
retro_hw_render_interface_d3d12 *d3d12;
#endif

std::unique_ptr<D3D12::Context> g_d3d12_context;

using namespace D3D12;
Expand Down Expand Up @@ -136,6 +142,18 @@ bool Context::Create(IDXGIFactory5* dxgi_factory, IDXGIAdapter1* adapter, bool e
}

g_d3d12_context.reset(new Context());
#ifdef __LIBRETRO__
d3d12 = nullptr;
if (!environ_cb(RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE, (void **)&d3d12) || !d3d12) {
printf("Failed to get HW rendering interface!\n");
return false;
}

if (d3d12->interface_version != RETRO_HW_RENDER_INTERFACE_D3D12_VERSION) {
printf("HW render interface mismatch, expected %u, got %u!\n", RETRO_HW_RENDER_INTERFACE_D3D12_VERSION, d3d12->interface_version);
return false;
}
#endif
if (!g_d3d12_context->CreateDevice(dxgi_factory, adapter, enable_debug_layer) ||
!g_d3d12_context->CreateCommandQueue() || !g_d3d12_context->CreateAllocator() ||
!g_d3d12_context->CreateFence() || !g_d3d12_context->CreateDescriptorHeaps() ||
Expand Down Expand Up @@ -171,6 +189,9 @@ u32 Context::GetAdapterVendorID() const

bool Context::CreateDevice(IDXGIFactory5* dxgi_factory, IDXGIAdapter1* adapter, bool enable_debug_layer)
{
#ifdef __LIBRETRO__
m_device = d3d12->device;
#else
HRESULT hr;

// Enabling the debug layer will fail if the Graphics Tools feature is not installed.
Expand All @@ -195,12 +216,12 @@ bool Context::CreateDevice(IDXGIFactory5* dxgi_factory, IDXGIAdapter1* adapter,
Console.Error("Failed to create D3D12 device: %08X", hr);
return false;
}

#endif
// get adapter
const LUID luid(m_device->GetAdapterLuid());
if (FAILED(dxgi_factory->EnumAdapterByLuid(luid, IID_PPV_ARGS(m_adapter.put()))))
Console.Error("Failed to get lookup adapter by device LUID");

#ifndef __LIBRETRO__
if (enable_debug_layer)
{
ComPtr<ID3D12InfoQueue> info_queue = m_device.try_query<ID3D12InfoQueue>();
Expand All @@ -225,17 +246,22 @@ bool Context::CreateDevice(IDXGIFactory5* dxgi_factory, IDXGIAdapter1* adapter,
info_queue->PushStorageFilter(&filter);
}
}

#endif
return true;
}

bool Context::CreateCommandQueue()
{
#ifdef __LIBRETRO__
m_command_queue = d3d12->queue;
return true;
#else
const D3D12_COMMAND_QUEUE_DESC queue_desc = {D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL,
D3D12_COMMAND_QUEUE_FLAG_NONE};
HRESULT hr = m_device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&m_command_queue));
pxAssertRel(SUCCEEDED(hr), "Create command queue");
return SUCCEEDED(hr);
#endif
}

bool Context::CreateAllocator()
Expand Down
6 changes: 5 additions & 1 deletion libretro/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ target_include_directories(PCSX2_FLAGS INTERFACE
"${CMAKE_SOURCE_DIR}/libretro"
)

target_include_directories(common PUBLIC
"${CMAKE_SOURCE_DIR}/libretro"
)

target_include_directories(pcsx2_libretro PRIVATE
"${CMAKE_SOURCE_DIR}"
"${CMAKE_SOURCE_DIR}/libretro"
Expand Down Expand Up @@ -72,4 +76,4 @@ else(PACKAGE_MODE)
install(TARGETS pcsx2_libretro DESTINATION ${CMAKE_SOURCE_DIR}/bin)
endif(PACKAGE_MODE)

#setup_main_executable(pcsx2-libretro)
#setup_main_executable(pcsx2-libretro)
30 changes: 27 additions & 3 deletions libretro/libretro_d3d.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* Copyright (C) 2010-2016 The RetroArch team
/* Copyright (C) 2010-2023 The RetroArch team
*
* ---------------------------------------------------------------------------------------------
* The following license statement only applies to this libretro API header (libretro_vulkan.h)
* The following license statement only applies to this libretro API header (libretro_d3d.h)
* ---------------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
Expand Down Expand Up @@ -30,7 +30,7 @@
#include "libretro.h"

#include <d3d11.h>
#include <D3Dcompiler.h>
#include <d3dcompiler.h>

#define RETRO_HW_RENDER_INTERFACE_D3D11_VERSION 1

Expand All @@ -52,5 +52,29 @@ struct retro_hw_render_interface_d3d11
pD3DCompile D3DCompile;
};

#include <d3d12.h>
#include <d3dcompiler.h>

#define RETRO_HW_RENDER_INTERFACE_D3D12_VERSION 1

struct retro_hw_render_interface_d3d12
{
/* Must be set to RETRO_HW_RENDER_INTERFACE_D3D12. */
enum retro_hw_render_interface_type interface_type;
/* Must be set to RETRO_HW_RENDER_INTERFACE_D3D12_VERSION. */
unsigned interface_version;

/* Opaque handle to the d3d12 backend in the frontend
* which must be passed along to all function pointers
* in this interface.
*/
void* handle;
ID3D12Device *device;
ID3D12CommandQueue *queue;
pD3DCompile D3DCompile;
D3D12_RESOURCE_STATES required_state;
void (*set_texture)(void* handle, ID3D12Resource* texture, DXGI_FORMAT format);
};


#endif /* LIBRETRO_DIRECT3D_H__ */
24 changes: 17 additions & 7 deletions libretro/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ static Option<bool> fast_boot("pcsx2_fastboot", "Fast Boot", true);

GfxOption<std::string> renderer("pcsx2_renderer", "Renderer", {"Auto", "OpenGL",
#ifdef _WIN32
"D3D11",
"D3D11", "D3D12",
#endif
#ifdef ENABLE_VULKAN
"Vulkan",
"Vulkan",
#endif
"Software", "Null"});

Expand Down Expand Up @@ -451,27 +451,26 @@ static bool set_hw_render(retro_hw_context_type type)
hw_render.context_destroy = context_destroy;
hw_render.bottom_left_origin = true;
hw_render.depth = true;
hw_render.cache_context = true;
hw_render.cache_context = false;

switch (type)
{
#ifdef _WIN32
case RETRO_HW_CONTEXT_DIRECT3D:
hw_render.version_major = 11;
if(!hw_render.version_major)
hw_render.version_major = 11;
hw_render.version_minor = 0;
break;
#endif
#ifdef ENABLE_VULKAN
case RETRO_HW_CONTEXT_VULKAN:
hw_render.version_major = VK_API_VERSION_1_1;
hw_render.version_minor = 0;
hw_render.cache_context = false;
break;
#endif
case RETRO_HW_CONTEXT_OPENGL_CORE:
hw_render.version_major = 3;
hw_render.version_minor = 3;
hw_render.cache_context = false;
break;

case RETRO_HW_CONTEXT_OPENGL:
Expand Down Expand Up @@ -505,7 +504,15 @@ bool select_hw_render()
}
#ifdef _WIN32
if (Options::renderer == "D3D11")
{
hw_render.version_major = 11;
return set_hw_render(RETRO_HW_CONTEXT_DIRECT3D);
}
if (Options::renderer == "D3D12")
{
hw_render.version_major = 12;
return set_hw_render(RETRO_HW_CONTEXT_DIRECT3D);
}
#endif
#ifdef ENABLE_VULKAN
if (Options::renderer == "Vulkan")
Expand Down Expand Up @@ -661,7 +668,10 @@ bool retro_load_game(const struct retro_game_info* game)
switch (hw_render.context_type)
{
case RETRO_HW_CONTEXT_DIRECT3D:
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::DX11);
if(hw_render.version_major == 12)
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::DX12);
else
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::DX11);
break;
#ifdef ENABLE_VULKAN
case RETRO_HW_CONTEXT_VULKAN:
Expand Down
Loading

0 comments on commit 8d56089

Please sign in to comment.