mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-19 19:15:26 +00:00
vulkan bringup on linux
cleanup: drop unused stuff
This commit is contained in:
parent
6cb7a17814
commit
860b76452f
21 changed files with 205 additions and 1613 deletions
|
@ -46,7 +46,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${PROJECT_BINARY_DIR}/bin")
|
|||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${PROJECT_BINARY_DIR}/bin")
|
||||
add_subdirectory( Vulkan )
|
||||
add_subdirectory( rpcs3 )
|
||||
add_subdirectory( rsx_program_decompiler )
|
||||
|
||||
include_directories(3rdparty/hidapi/hidapi)
|
||||
if(APPLE)
|
||||
|
|
|
@ -155,16 +155,13 @@ ${LLVM_INCLUDE_DIRS}
|
|||
"${RPCS3_SRC_DIR}/../Utilities/yaml-cpp/include"
|
||||
"${RPCS3_SRC_DIR}/../asmjit/src/asmjit"
|
||||
"${RPCS3_SRC_DIR}/../3rdparty/GSL/include"
|
||||
"${RPCS3_SRC_DIR}/../rsx_program_decompiler/rsx_decompiler"
|
||||
"${RPCS3_SRC_DIR}/../rsx_program_decompiler/shader_code"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/Vulkan-LoaderAndValidationLayers/include"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/glslang/Public"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/"
|
||||
"${RPCS3_SRC_DIR}/../3rdparty/hidapi/hidapi"
|
||||
# Includes 3rdparty stuff that isn't included yet
|
||||
"${RPCS3_SRC_DIR}/../3rdparty/GL"
|
||||
"${RPCS3_SRC_DIR}/../3rdparty/stblib"
|
||||
"${RPCS3_SRC_DIR}/../rsx_program_decompiler/rsx_decompiler"
|
||||
"${RPCS3_SRC_DIR}/../rsx_program_decompiler/shader_code"
|
||||
"${RPCS3_SRC_DIR}/../3rdparty/cereal/include"
|
||||
)
|
||||
if(WIN32)
|
||||
|
@ -217,20 +214,33 @@ GLOB_RECURSE
|
|||
RPCS3_SRC
|
||||
"${RPCS3_SRC_DIR}/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../Utilities/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../rsx_program_decompiler/rsx_decompiler/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../rsx_program_decompiler/shader_code/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../asmjit/src/asmjit/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/glslang/GenericCodeGen/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/glslang/MachineIndependent/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/glslang/OSDependent/Unix/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/OGLCompilersDLL/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/hlsl/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/SPIRV/*.cpp"
|
||||
)
|
||||
|
||||
if(NOT WIN32)
|
||||
set (EXCLUDE_DIR "/RSX/VK/")
|
||||
foreach (TMP_PATH ${RPCS3_SRC})
|
||||
string (FIND ${TMP_PATH} ${EXCLUDE_DIR} EXCLUDE_DIR_FOUND)
|
||||
if (NOT ${EXCLUDE_DIR_FOUND} EQUAL -1)
|
||||
#File exclusion section
|
||||
|
||||
#Ignore vulkan if not on windows or linux
|
||||
if(NOT WIN32 AND NOT "${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
set (EXCLUDE_FILES "/RSX/VK/")
|
||||
endif()
|
||||
|
||||
#Do not compile the Qt moc files, they are compiled when generating automoc
|
||||
set (EXCLUDE_FILES ${EXLUDE_FILES} "moc_")
|
||||
|
||||
foreach (TMP_PATH ${RPCS3_SRC})
|
||||
foreach (EXCLUDE_PATH ${EXCLUDE_FILES})
|
||||
string (FIND ${TMP_PATH} ${EXCLUDE_PATH} EXCLUDE_FILE_FOUND)
|
||||
if (NOT ${EXCLUDE_FILE_FOUND} EQUAL -1)
|
||||
list (REMOVE_ITEM RPCS3_SRC ${TMP_PATH})
|
||||
endif ()
|
||||
endforeach(TMP_PATH)
|
||||
endif()
|
||||
endforeach(EXCLUDE_PATH)
|
||||
endforeach(TMP_PATH)
|
||||
|
||||
# The Gui folder contains wxWidgets stuff, which we no longer want.
|
||||
foreach (TMP_PATH ${RPCS3_SRC})
|
||||
|
@ -261,10 +271,8 @@ if(WIN32)
|
|||
endif()
|
||||
target_link_libraries(rpcs3 avformat.lib avcodec.lib avutil.lib swresample.lib swscale.lib png16_static ${OPENAL_LIBRARY} ${ADDITIONAL_LIBS})
|
||||
else()
|
||||
|
||||
target_link_libraries(rpcs3 ${OPENAL_LIBRARY} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES} hidapi-hidraw udev)
|
||||
target_link_libraries(rpcs3 -ldl -latomic -lpthread ${ZLIB_LIBRARIES} ${ADDITIONAL_LIBS})
|
||||
|
||||
target_link_libraries(rpcs3 -ldl -latomic -lpthread -lvulkan ${ZLIB_LIBRARIES} ${ADDITIONAL_LIBS})
|
||||
if (USE_SYSTEM_FFMPEG)
|
||||
link_libraries(${FFMPEG_LIBRARY_DIR})
|
||||
target_link_libraries(rpcs3 libavformat.so libavcodec.so libavutil.so libswresample.so libswscale.so)
|
||||
|
@ -281,8 +289,6 @@ if(LLVM_FOUND)
|
|||
target_link_libraries(rpcs3 ${LLVM_LIBS})
|
||||
endif()
|
||||
|
||||
target_link_libraries(rpcs3 rsx_decompiler shader_code)
|
||||
|
||||
set_target_properties(rpcs3 PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${RPCS3_SRC_DIR}/stdafx.h")
|
||||
cotire(rpcs3)
|
||||
|
||||
|
|
|
@ -24,7 +24,8 @@ namespace
|
|||
|
||||
GLGSRender::GLGSRender() : GSRender()
|
||||
{
|
||||
shaders_cache.load(rsx::old_shaders_cache::shader_language::glsl);
|
||||
//TODO
|
||||
//shaders_cache.load(rsx::old_shaders_cache::shader_language::glsl);
|
||||
}
|
||||
|
||||
u32 GLGSRender::enable(u32 condition, u32 cap)
|
||||
|
|
|
@ -27,51 +27,7 @@ namespace rsx
|
|||
{
|
||||
std::function<bool(u32 addr, bool is_writing)> g_access_violation_handler;
|
||||
|
||||
void old_shaders_cache::shaders_cache::load(const std::string &path, shader_language lang)
|
||||
{
|
||||
const std::string lang_name(lang == shader_language::glsl ? "glsl" : "hlsl");
|
||||
|
||||
auto extract_hash = [](const std::string &string)
|
||||
{
|
||||
return std::stoull(string.substr(0, string.find('.')).c_str(), 0, 16);
|
||||
};
|
||||
|
||||
for (const auto& entry : fs::dir(path))
|
||||
{
|
||||
if (entry.name == "." || entry.name == "..")
|
||||
continue;
|
||||
|
||||
u64 hash;
|
||||
|
||||
try
|
||||
{
|
||||
hash = extract_hash(entry.name);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fmt::match(entry.name, "*.fs." + lang_name))
|
||||
{
|
||||
fs::file file{ path + entry.name };
|
||||
decompiled_fragment_shaders.insert(hash, { file.to_string() });
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fmt::match(entry.name, "*.vs." + lang_name))
|
||||
{
|
||||
fs::file file{ path + entry.name };
|
||||
decompiled_vertex_shaders.insert(hash, { file.to_string() });
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void old_shaders_cache::shaders_cache::load(shader_language lang)
|
||||
{
|
||||
load(Emu.GetCachePath(), lang);
|
||||
}
|
||||
//TODO: Restore a working shaders cache
|
||||
|
||||
u32 get_address(u32 offset, u32 location)
|
||||
{
|
||||
|
@ -1046,102 +1002,6 @@ namespace rsx
|
|||
return result;
|
||||
}
|
||||
|
||||
raw_program thread::get_raw_program() const
|
||||
{
|
||||
raw_program result{};
|
||||
|
||||
u32 fp_info = rsx::method_registers.shader_program_address();
|
||||
|
||||
result.state.input_attributes = rsx::method_registers.vertex_attrib_input_mask();
|
||||
result.state.output_attributes = rsx::method_registers.vertex_attrib_output_mask();
|
||||
result.state.ctrl = rsx::method_registers.shader_control();
|
||||
result.state.divider_op = rsx::method_registers.frequency_divider_operation_mask();
|
||||
result.state.alpha_func = (u32)rsx::method_registers.alpha_func();
|
||||
result.state.fog_mode = (u32)rsx::method_registers.fog_equation();
|
||||
result.state.is_int = 0;
|
||||
|
||||
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
||||
{
|
||||
bool is_int = false;
|
||||
|
||||
if (rsx::method_registers.vertex_arrays_info[index].size() > 0)
|
||||
{
|
||||
is_int = is_int_type(rsx::method_registers.vertex_arrays_info[index].type());
|
||||
result.state.frequency[index] = rsx::method_registers.vertex_arrays_info[index].frequency();
|
||||
}
|
||||
else if (rsx::method_registers.register_vertex_info[index].size > 0)
|
||||
{
|
||||
is_int = is_int_type(rsx::method_registers.register_vertex_info[index].type);
|
||||
result.state.frequency[index] = rsx::method_registers.register_vertex_info[index].frequency;
|
||||
result.state.divider_op |= (1 << index);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.state.frequency[index] = 0;
|
||||
}
|
||||
|
||||
if (is_int)
|
||||
{
|
||||
result.state.is_int |= 1 << index;
|
||||
}
|
||||
}
|
||||
|
||||
for (u8 index = 0; index < rsx::limits::fragment_textures_count; ++index)
|
||||
{
|
||||
if (!rsx::method_registers.fragment_textures[index].enabled())
|
||||
{
|
||||
result.state.textures_alpha_kill[index] = 0;
|
||||
result.state.textures_zfunc[index] = 0;
|
||||
result.state.textures[index] = rsx::texture_target::none;
|
||||
continue;
|
||||
}
|
||||
|
||||
result.state.textures_alpha_kill[index] = rsx::method_registers.fragment_textures[index].alpha_kill_enabled() ? 1 : 0;
|
||||
result.state.textures_zfunc[index] = rsx::method_registers.fragment_textures[index].zfunc();
|
||||
|
||||
switch (rsx::method_registers.fragment_textures[index].get_extended_texture_dimension())
|
||||
{
|
||||
case rsx::texture_dimension_extended::texture_dimension_1d: result.state.textures[index] = rsx::texture_target::_1; break;
|
||||
case rsx::texture_dimension_extended::texture_dimension_2d: result.state.textures[index] = rsx::texture_target::_2; break;
|
||||
case rsx::texture_dimension_extended::texture_dimension_3d: result.state.textures[index] = rsx::texture_target::_3; break;
|
||||
case rsx::texture_dimension_extended::texture_dimension_cubemap: result.state.textures[index] = rsx::texture_target::cube; break;
|
||||
|
||||
default:
|
||||
result.state.textures[index] = rsx::texture_target::none;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (u8 index = 0; index < rsx::limits::vertex_textures_count; ++index)
|
||||
{
|
||||
if (!rsx::method_registers.fragment_textures[index].enabled())
|
||||
{
|
||||
result.state.vertex_textures[index] = rsx::texture_target::none;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (rsx::method_registers.fragment_textures[index].get_extended_texture_dimension())
|
||||
{
|
||||
case rsx::texture_dimension_extended::texture_dimension_1d: result.state.vertex_textures[index] = rsx::texture_target::_1; break;
|
||||
case rsx::texture_dimension_extended::texture_dimension_2d: result.state.vertex_textures[index] = rsx::texture_target::_2; break;
|
||||
case rsx::texture_dimension_extended::texture_dimension_3d: result.state.vertex_textures[index] = rsx::texture_target::_3; break;
|
||||
case rsx::texture_dimension_extended::texture_dimension_cubemap: result.state.vertex_textures[index] = rsx::texture_target::cube; break;
|
||||
|
||||
default:
|
||||
result.state.vertex_textures[index] = rsx::texture_target::none;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result.vertex_shader.ucode_ptr = rsx::method_registers.transform_program.data();
|
||||
result.vertex_shader.offset = rsx::method_registers.transform_program_start();
|
||||
|
||||
result.fragment_shader.ucode_ptr = vm::base(rsx::get_address(fp_info & ~0x3, (fp_info & 0x3) - 1));
|
||||
result.fragment_shader.offset = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void thread::reset()
|
||||
{
|
||||
rsx::method_registers.reset();
|
||||
|
|
|
@ -26,18 +26,6 @@ extern u64 get_system_time();
|
|||
extern bool user_asked_for_frame_capture;
|
||||
extern rsx::frame_capture_data frame_debug;
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
namespace old_shaders_cache
|
||||
{
|
||||
enum class shader_language
|
||||
{
|
||||
glsl,
|
||||
hlsl,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
namespace limits
|
||||
|
@ -54,54 +42,6 @@ namespace rsx
|
|||
};
|
||||
}
|
||||
|
||||
namespace old_shaders_cache
|
||||
{
|
||||
struct decompiled_shader
|
||||
{
|
||||
std::string code;
|
||||
};
|
||||
|
||||
struct finalized_shader
|
||||
{
|
||||
u64 ucode_hash;
|
||||
std::string code;
|
||||
};
|
||||
|
||||
template<typename Type, typename KeyType = u64, typename Hasher = std::hash<KeyType>>
|
||||
struct cache
|
||||
{
|
||||
private:
|
||||
std::unordered_map<KeyType, Type, Hasher> m_entries;
|
||||
|
||||
public:
|
||||
const Type* find(u64 key) const
|
||||
{
|
||||
auto found = m_entries.find(key);
|
||||
|
||||
if (found == m_entries.end())
|
||||
return nullptr;
|
||||
|
||||
return &found->second;
|
||||
}
|
||||
|
||||
void insert(KeyType key, const Type &shader)
|
||||
{
|
||||
m_entries.insert({ key, shader });
|
||||
}
|
||||
};
|
||||
|
||||
struct shaders_cache
|
||||
{
|
||||
cache<decompiled_shader> decompiled_fragment_shaders;
|
||||
cache<decompiled_shader> decompiled_vertex_shaders;
|
||||
cache<finalized_shader> finailized_fragment_shaders;
|
||||
cache<finalized_shader> finailized_vertex_shaders;
|
||||
|
||||
void load(const std::string &path, shader_language lang);
|
||||
void load(shader_language lang);
|
||||
};
|
||||
}
|
||||
|
||||
u32 get_vertex_type_size_on_host(vertex_base_type type, u32 size);
|
||||
|
||||
u32 get_address(u32 offset, u32 location);
|
||||
|
@ -172,9 +112,6 @@ namespace rsx
|
|||
std::vector<u32> element_push_buffer;
|
||||
|
||||
public:
|
||||
old_shaders_cache::shaders_cache shaders_cache;
|
||||
rsx::programs_cache programs_cache;
|
||||
|
||||
CellGcmControl* ctrl = nullptr;
|
||||
|
||||
Timer timer_sync;
|
||||
|
@ -356,7 +293,6 @@ namespace rsx
|
|||
|
||||
virtual bool scaled_image_from_memory(blit_src_info& src_info, blit_dst_info& dst_info, bool interpolate){ return false; }
|
||||
|
||||
struct raw_program get_raw_program() const;
|
||||
public:
|
||||
void reset();
|
||||
void init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress);
|
||||
|
|
|
@ -449,10 +449,11 @@ namespace
|
|||
|
||||
VKGSRender::VKGSRender() : GSRender()
|
||||
{
|
||||
shaders_cache.load(rsx::old_shaders_cache::shader_language::glsl);
|
||||
//shaders_cache.load(rsx::old_shaders_cache::shader_language::glsl);
|
||||
|
||||
printf("Starting vulkan renderer\n");
|
||||
u32 instance_handle = m_thread_context.createInstance("RPCS3");
|
||||
|
||||
printf("Instance created, handle=%u\n", instance_handle);
|
||||
if (instance_handle > 0)
|
||||
{
|
||||
m_thread_context.makeCurrentInstance(instance_handle);
|
||||
|
@ -497,6 +498,48 @@ VKGSRender::VKGSRender() : GSRender()
|
|||
{
|
||||
m_swap_chain = m_thread_context.createSwapChain(hInstance, hWnd, gpus[0]);
|
||||
}
|
||||
|
||||
#elif __linux__
|
||||
|
||||
Window window = (Window)m_frame->handle();
|
||||
Display *display = XOpenDisplay(0);
|
||||
|
||||
printf("Entering enumeration logic...\n");
|
||||
|
||||
std::vector<vk::physical_device>& gpus = m_thread_context.enumerateDevices();
|
||||
|
||||
//Actually confirm that the loader found at least one compatible device
|
||||
//This should not happen unless something is wrong with the driver setup on the target system
|
||||
if (gpus.size() == 0)
|
||||
{
|
||||
//We can't throw in Emulator::Load, so we show error and return
|
||||
LOG_FATAL(RSX, "No compatible GPU devices found");
|
||||
m_device = VK_NULL_HANDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Post-enumerate devices, window=%llx, display=0x%p\n", window, display);
|
||||
XFlush(display);
|
||||
|
||||
bool gpu_found = false;
|
||||
std::string adapter_name = g_cfg.video.vk.adapter;
|
||||
for (auto &gpu : gpus)
|
||||
{
|
||||
if (gpu.name() == adapter_name)
|
||||
{
|
||||
m_swap_chain = m_thread_context.createSwapChain(display, window, gpu);
|
||||
gpu_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gpu_found || adapter_name.empty())
|
||||
{
|
||||
m_swap_chain = m_thread_context.createSwapChain(display, window, gpus[0]);
|
||||
}
|
||||
|
||||
printf("Swapchain creation completed\n");
|
||||
m_display_handle = display;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -659,6 +702,11 @@ VKGSRender::~VKGSRender()
|
|||
m_thread_context.close();
|
||||
|
||||
delete m_swap_chain;
|
||||
|
||||
#ifdef __linux__
|
||||
if (m_display_handle)
|
||||
XCloseDisplay(m_display_handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool VKGSRender::on_access_violation(u32 address, bool is_writing)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "VKProgramBuffer.h"
|
||||
#include "../GCM.h"
|
||||
#include "../rsx_utils.h"
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
#pragma comment(lib, "VKstatic.1.lib")
|
||||
|
@ -165,10 +166,14 @@ private:
|
|||
s32 m_last_flushable_cb = -1;
|
||||
|
||||
std::mutex m_flush_queue_mutex;
|
||||
std::atomic<bool> m_flush_commands = false;
|
||||
std::atomic<bool> m_flush_commands = { false };
|
||||
std::atomic<int> m_queued_threads = { 0 };
|
||||
|
||||
std::thread::id rsx_thread;
|
||||
|
||||
#ifdef __linux__
|
||||
Display *m_display_handle = nullptr;
|
||||
#endif
|
||||
|
||||
public:
|
||||
VKGSRender();
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
#include "Emu/System.h"
|
||||
#include "VulkanAPI.h"
|
||||
#include "../GCM.h"
|
||||
|
@ -799,15 +803,9 @@ namespace vk
|
|||
void init_swapchain(u32 width, u32 height)
|
||||
{
|
||||
VkSwapchainKHR old_swapchain = m_vk_swapchain;
|
||||
|
||||
uint32_t num_modes;
|
||||
vk::physical_device& gpu = const_cast<vk::physical_device&>(dev.gpu());
|
||||
CHECK_RESULT(vkGetPhysicalDeviceSurfacePresentModesKHR(gpu, m_surface, &num_modes, NULL));
|
||||
|
||||
std::vector<VkPresentModeKHR> present_mode_descriptors(num_modes);
|
||||
CHECK_RESULT(vkGetPhysicalDeviceSurfacePresentModesKHR(gpu, m_surface, &num_modes, present_mode_descriptors.data()));
|
||||
|
||||
VkSurfaceCapabilitiesKHR surface_descriptors;
|
||||
|
||||
VkSurfaceCapabilitiesKHR surface_descriptors = {};
|
||||
CHECK_RESULT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu, m_surface, &surface_descriptors));
|
||||
|
||||
VkExtent2D swapchainExtent;
|
||||
|
@ -1058,6 +1056,8 @@ namespace vk
|
|||
|
||||
void enable_debugging()
|
||||
{
|
||||
if (!g_cfg.video.debug_output) return;
|
||||
|
||||
PFN_vkDebugReportCallbackEXT callback = vk::dbgFunc;
|
||||
|
||||
createDebugReportCallback = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(m_instance, "vkCreateDebugReportCallbackEXT");
|
||||
|
@ -1089,7 +1089,11 @@ namespace vk
|
|||
const char *requested_extensions[] =
|
||||
{
|
||||
"VK_KHR_surface",
|
||||
#ifdef _WIN32
|
||||
"VK_KHR_win32_surface",
|
||||
#else
|
||||
"VK_KHR_xlib_surface",
|
||||
#endif
|
||||
"VK_EXT_debug_report",
|
||||
};
|
||||
|
||||
|
@ -1166,6 +1170,7 @@ namespace vk
|
|||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
vk::swap_chain* createSwapChain(HINSTANCE hInstance, HWND hWnd, vk::physical_device &dev)
|
||||
{
|
||||
VkWin32SurfaceCreateInfoKHR createInfo = {};
|
||||
|
@ -1175,6 +1180,18 @@ namespace vk
|
|||
|
||||
VkSurfaceKHR surface;
|
||||
CHECK_RESULT(vkCreateWin32SurfaceKHR(m_instance, &createInfo, NULL, &surface));
|
||||
#elif __linux__
|
||||
|
||||
vk::swap_chain* createSwapChain(Display *display, Window window, vk::physical_device &dev)
|
||||
{
|
||||
VkXlibSurfaceCreateInfoKHR createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
|
||||
createInfo.dpy = display;
|
||||
createInfo.window = window;
|
||||
|
||||
VkSurfaceKHR surface;
|
||||
CHECK_RESULT(vkCreateXlibSurfaceKHR(m_instance, &createInfo, nullptr, &surface));
|
||||
#endif
|
||||
|
||||
uint32_t device_queues = dev.get_queue_count();
|
||||
std::vector<VkBool32> supportsPresent(device_queues);
|
||||
|
@ -1251,8 +1268,6 @@ namespace vk
|
|||
|
||||
return new swap_chain(dev, presentQueueNodeIndex, graphicsQueueNodeIndex, format, surface, color_space);
|
||||
}
|
||||
#endif //if _WIN32
|
||||
|
||||
};
|
||||
|
||||
class descriptor_pool
|
||||
|
|
|
@ -205,7 +205,7 @@ namespace vk
|
|||
template<typename T>
|
||||
void do_memory_transfer(void *pixels_dst, const void *pixels_src)
|
||||
{
|
||||
if (sizeof T == 1)
|
||||
if (sizeof(T) == 1)
|
||||
memcpy(pixels_dst, pixels_src, cpu_address_range);
|
||||
else
|
||||
{
|
||||
|
|
|
@ -551,6 +551,6 @@ VKGSRender::upload_vertex_data()
|
|||
{
|
||||
draw_command_visitor visitor(*m_device, m_index_buffer_ring_info, m_attrib_ring_info, m_program,
|
||||
descriptor_sets, m_buffer_view_to_clean,
|
||||
[this](const auto& state, const auto& range) { return get_vertex_buffers(state, range); });
|
||||
[this](const auto& state, const auto& range) { return this->get_vertex_buffers(state, range); });
|
||||
return std::apply_visitor(visitor, get_draw_command(rsx::method_registers));
|
||||
}
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "rsx_cache.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
void shaders_cache::path(const std::string &path_)
|
||||
{
|
||||
m_path = path_;
|
||||
}
|
||||
|
||||
shader_info shaders_cache::get(const program_cache_context &ctxt, raw_shader &raw_shader, const program_state& state)
|
||||
{
|
||||
auto found_entry = m_entries.find(raw_shader);
|
||||
|
||||
shader_info info;
|
||||
entry_t *entry;
|
||||
|
||||
if (found_entry != m_entries.end())
|
||||
{
|
||||
entry = &found_entry->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
//analyze_raw_shader(raw_shader);
|
||||
|
||||
std::string shader_name_base =
|
||||
fmt::format("%lld.%016llx", ++m_index, raw_shader.hash()) +
|
||||
(raw_shader.type == rsx::program_type::fragment ? ".fp" : ".vp");
|
||||
|
||||
fs::file{ m_path + shader_name_base + ".ucode", fs::rewrite }
|
||||
.write(raw_shader.ucode.data(), raw_shader.ucode.size());
|
||||
|
||||
rsx::decompiled_shader decompiled_shader = decompile(raw_shader, ctxt.lang);
|
||||
|
||||
fs::file{ m_path + shader_name_base + (ctxt.lang == rsx::decompile_language::glsl ? ".glsl" : ".hlsl"), fs::rewrite }
|
||||
.write(decompiled_shader.code);
|
||||
|
||||
auto inserted = m_entries.insert({ raw_shader, entry_t{ m_index, decompiled_shader } }).first;
|
||||
inserted->second.decompiled.raw = &inserted->first;
|
||||
entry = &inserted->second;
|
||||
}
|
||||
|
||||
info.decompiled = &entry->decompiled;
|
||||
|
||||
auto found_complete = entry->complete.find(state);
|
||||
|
||||
if (found_complete != entry->complete.end())
|
||||
{
|
||||
info.complete = &found_complete->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
rsx::complete_shader complete_shader = ctxt.complete_shader(entry->decompiled, state);
|
||||
complete_shader.decompiled = info.decompiled;
|
||||
info.complete = &entry->complete.insert({ state, complete_shader }).first->second;
|
||||
info.complete->user_data = nullptr;
|
||||
|
||||
const std::string hash_combination = fmt::format("%lld.%016llx.%016llx", entry->index, raw_shader.hash(), state.hash());
|
||||
|
||||
std::string shader_name =
|
||||
hash_combination +
|
||||
(raw_shader.type == rsx::program_type::fragment ? ".fp" : ".vp") +
|
||||
(ctxt.lang == rsx::decompile_language::glsl ? ".glsl" : ".hlsl");
|
||||
|
||||
fs::file{ m_path + shader_name, fs::rewrite }.write(info.complete->code);
|
||||
fs::file{ m_path + hash_combination + ".state", fs::rewrite }.write(state);
|
||||
}
|
||||
|
||||
if (info.complete->user_data == nullptr)
|
||||
{
|
||||
info.complete->user_data = ctxt.compile_shader(raw_shader.type, info.complete->code);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
void shaders_cache::clear(const program_cache_context& context)
|
||||
{
|
||||
for (auto &entry : m_entries)
|
||||
{
|
||||
for (auto &shader : entry.second.complete)
|
||||
{
|
||||
context.remove_shader(shader.second.user_data);
|
||||
}
|
||||
}
|
||||
|
||||
m_entries.clear();
|
||||
}
|
||||
|
||||
programs_cache::programs_cache()
|
||||
{
|
||||
m_vertex_shaders_cache.path(Emu.GetCachePath());
|
||||
m_fragment_shader_cache.path(Emu.GetCachePath());
|
||||
}
|
||||
|
||||
programs_cache::~programs_cache()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
program_info programs_cache::get(raw_program raw_program_, decompile_language lang)
|
||||
{
|
||||
raw_program_.vertex_shader.type = program_type::vertex;
|
||||
raw_program_.fragment_shader.type = program_type::fragment;
|
||||
|
||||
analyze_raw_shader(raw_program_.vertex_shader);
|
||||
analyze_raw_shader(raw_program_.fragment_shader);
|
||||
|
||||
auto found = m_program_cache.find(raw_program_);
|
||||
|
||||
if (found != m_program_cache.end())
|
||||
{
|
||||
return found->second;
|
||||
}
|
||||
|
||||
program_info result;
|
||||
|
||||
result.vertex_shader = m_vertex_shaders_cache.get(context, raw_program_.vertex_shader, raw_program_.state);
|
||||
result.fragment_shader = m_fragment_shader_cache.get(context, raw_program_.fragment_shader, raw_program_.state);
|
||||
result.program = context.make_program(result.vertex_shader.complete->user_data, result.fragment_shader.complete->user_data);
|
||||
m_program_cache.insert({ raw_program_, result });
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void programs_cache::clear()
|
||||
{
|
||||
for (auto &entry : m_program_cache)
|
||||
{
|
||||
context.remove_program(entry.second.program);
|
||||
}
|
||||
|
||||
m_program_cache.clear();
|
||||
|
||||
m_vertex_shaders_cache.clear(context);
|
||||
m_fragment_shader_cache.clear(context);
|
||||
}
|
||||
}
|
|
@ -1,36 +1,10 @@
|
|||
#pragma once
|
||||
#include <rsx_decompiler.h>
|
||||
#include "Utilities/VirtualMemory.h"
|
||||
#include "Emu/Memory/vm.h"
|
||||
#include "gcm_enums.h"
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
struct shader_info
|
||||
{
|
||||
decompiled_shader *decompiled;
|
||||
complete_shader *complete;
|
||||
};
|
||||
|
||||
struct program_info
|
||||
{
|
||||
shader_info vertex_shader;
|
||||
shader_info fragment_shader;
|
||||
|
||||
void *program;
|
||||
};
|
||||
|
||||
struct program_cache_context
|
||||
{
|
||||
decompile_language lang;
|
||||
|
||||
void*(*compile_shader)(program_type type, const std::string &code);
|
||||
rsx::complete_shader(*complete_shader)(const decompiled_shader &shader, program_state state);
|
||||
void*(*make_program)(const void *vertex_shader, const void *fragment_shader);
|
||||
void(*remove_program)(void *ptr);
|
||||
void(*remove_shader)(void *ptr);
|
||||
};
|
||||
|
||||
struct blit_src_info
|
||||
{
|
||||
blit_engine::transfer_source_format format;
|
||||
|
@ -64,43 +38,6 @@ namespace rsx
|
|||
u32 rsx_address;
|
||||
};
|
||||
|
||||
class shaders_cache
|
||||
{
|
||||
struct entry_t
|
||||
{
|
||||
std::int64_t index;
|
||||
decompiled_shader decompiled;
|
||||
std::unordered_map<program_state, complete_shader, hasher> complete;
|
||||
};
|
||||
|
||||
std::unordered_map<raw_shader, entry_t, hasher> m_entries;
|
||||
std::string m_path;
|
||||
std::int64_t m_index = -1;
|
||||
|
||||
public:
|
||||
void path(const std::string &path_);
|
||||
|
||||
shader_info get(const program_cache_context &ctxt, raw_shader &raw_shader, const program_state& state);
|
||||
void clear(const program_cache_context& context);
|
||||
};
|
||||
|
||||
class programs_cache
|
||||
{
|
||||
std::unordered_map<raw_program, program_info, hasher> m_program_cache;
|
||||
|
||||
shaders_cache m_vertex_shaders_cache;
|
||||
shaders_cache m_fragment_shader_cache;
|
||||
|
||||
public:
|
||||
program_cache_context context;
|
||||
|
||||
programs_cache();
|
||||
~programs_cache();
|
||||
|
||||
program_info get(raw_program raw_program_, decompile_language lang);
|
||||
void clear();
|
||||
};
|
||||
|
||||
class buffered_section
|
||||
{
|
||||
protected:
|
||||
|
|
|
@ -89,9 +89,7 @@ void fmt_class_string<video_renderer>::format(std::string& out, u64 arg)
|
|||
{
|
||||
case video_renderer::null: return "Null";
|
||||
case video_renderer::opengl: return "OpenGL";
|
||||
#ifdef _WIN32
|
||||
case video_renderer::vulkan: return "Vulkan";
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
case video_renderer::dx12: return "D3D12";
|
||||
#endif
|
||||
|
|
|
@ -74,9 +74,7 @@ enum class video_renderer
|
|||
{
|
||||
null,
|
||||
opengl,
|
||||
#ifdef _WIN32
|
||||
vulkan,
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
dx12,
|
||||
#endif
|
||||
|
|
|
@ -13,10 +13,7 @@
|
|||
#include <dxgi1_4.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Emu/RSX/VK/VKHelpers.h"
|
||||
#endif
|
||||
|
||||
#include "SettingsDialog.h"
|
||||
|
||||
#include <set>
|
||||
|
@ -480,7 +477,6 @@ SettingsDialog::SettingsDialog(wxWindow* parent, const std::string& path)
|
|||
cbox_gs_d3d_adapter->Enable(false);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
//TODO: This is very slow. Only init once
|
||||
bool vulkan_supported = false;
|
||||
|
||||
|
@ -514,9 +510,6 @@ SettingsDialog::SettingsDialog(wxWindow* parent, const std::string& path)
|
|||
}
|
||||
|
||||
device_enum_context.close();
|
||||
#else
|
||||
cbox_gs_vk_adapter->Enable(false);
|
||||
#endif
|
||||
|
||||
// Rendering
|
||||
s_round_gs_render->Add(cbox_gs_render, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -37,8 +37,8 @@
|
|||
#ifdef _MSC_VER
|
||||
#include "Emu/RSX/D3D12/D3D12GSRender.h"
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
#include "Emu/RSX/VK/VKGSRender.h"
|
||||
#ifdef _WIN32
|
||||
#include "Emu/Audio/XAudio2/XAudio2Thread.h"
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
|
@ -149,9 +149,7 @@ void rpcs3_app::InitializeCallbacks()
|
|||
{
|
||||
case video_renderer::null: return std::make_unique<gs_frame>("Null", size.first, size.second, RPCS3MainWin->GetAppIcon());
|
||||
case video_renderer::opengl: return std::make_unique<gl_gs_frame>(size.first, size.second, RPCS3MainWin->GetAppIcon());
|
||||
#ifdef _WIN32
|
||||
case video_renderer::vulkan: return std::make_unique<gs_frame>("Vulkan", size.first, size.second, RPCS3MainWin->GetAppIcon());
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
case video_renderer::dx12: return std::make_unique<gs_frame>("DirectX 12", size.first, size.second, RPCS3MainWin->GetAppIcon());
|
||||
#endif
|
||||
|
@ -165,9 +163,7 @@ void rpcs3_app::InitializeCallbacks()
|
|||
{
|
||||
case video_renderer::null: return std::make_shared<NullGSRender>();
|
||||
case video_renderer::opengl: return std::make_shared<GLGSRender>();
|
||||
#ifdef _WIN32
|
||||
case video_renderer::vulkan: return std::make_shared<VKGSRender>();
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
case video_renderer::dx12: return std::make_shared<D3D12GSRender>();
|
||||
#endif
|
||||
|
|
29
rpcs3/rpcs3_automoc.cpp
Normal file
29
rpcs3/rpcs3_automoc.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* This file is autogenerated, do not edit*/
|
||||
#include "moc_basic_keyboard_handler.cpp"
|
||||
#include "moc_basic_mouse_handler.cpp"
|
||||
#include "moc_rpcs3_app.cpp"
|
||||
#include "moc_audio_tab.cpp"
|
||||
#include "moc_auto_pause_settings_dialog.cpp"
|
||||
#include "moc_cg_disasm_window.cpp"
|
||||
#include "moc_core_tab.cpp"
|
||||
#include "moc_debugger_frame.cpp"
|
||||
#include "moc_emu_settings.cpp"
|
||||
#include "moc_game_list_frame.cpp"
|
||||
#include "moc_graphics_tab.cpp"
|
||||
#include "moc_gs_frame.cpp"
|
||||
#include "moc_gui_settings.cpp"
|
||||
#include "moc_gui_tab.cpp"
|
||||
#include "moc_input_tab.cpp"
|
||||
#include "moc_kernel_explorer.cpp"
|
||||
#include "moc_log_frame.cpp"
|
||||
#include "moc_main_window.cpp"
|
||||
#include "moc_memory_string_searcher.cpp"
|
||||
#include "moc_misc_tab.cpp"
|
||||
#include "moc_msg_dialog_frame.cpp"
|
||||
#include "moc_networking_tab.cpp"
|
||||
#include "moc_pad_settings_dialog.cpp"
|
||||
#include "moc_rsx_debugger.cpp"
|
||||
#include "moc_save_data_utility.cpp"
|
||||
#include "moc_settings_dialog.cpp"
|
||||
#include "moc_system_tab.cpp"
|
||||
#include "moc_welcome_dialog.cpp"
|
|
@ -4,6 +4,18 @@
|
|||
#include "Emu/System.h"
|
||||
#include "Utilities/Config.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <Windows.h>
|
||||
#undef GetHwnd
|
||||
#include <d3d12.h>
|
||||
#include <wrl/client.h>
|
||||
#include <dxgi1_4.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__linux__)
|
||||
#include "Emu/RSX/VK/VKHelpers.h"
|
||||
#endif
|
||||
|
||||
extern std::string g_cfg_defaults; //! Default settings grabbed from Utilities/Config.h
|
||||
|
||||
inline std::string sstr(const QString& _in) { return _in.toUtf8().toStdString(); }
|
||||
|
@ -103,6 +115,58 @@ static QStringList getOptions(cfg_location location)
|
|||
return values;
|
||||
}
|
||||
|
||||
Render_Creator::Render_Creator()
|
||||
{
|
||||
// check for dx12 adapters
|
||||
#ifdef _MSC_VER
|
||||
Microsoft::WRL::ComPtr<IDXGIFactory4> dxgi_factory;
|
||||
supportsD3D12 = SUCCEEDED(CreateDXGIFactory(IID_PPV_ARGS(&dxgi_factory)));
|
||||
|
||||
if (supportsD3D12)
|
||||
{
|
||||
supportsD3D12 = false;
|
||||
IDXGIAdapter1* pAdapter = nullptr;
|
||||
|
||||
for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != dxgi_factory->EnumAdapters1(adapterIndex, &pAdapter); ++adapterIndex)
|
||||
{
|
||||
HMODULE D3D12Module = verify("d3d12.dll", LoadLibrary(L"d3d12.dll"));
|
||||
PFN_D3D12_CREATE_DEVICE wrapD3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(D3D12Module, "D3D12CreateDevice");
|
||||
|
||||
if (SUCCEEDED(wrapD3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
|
||||
{
|
||||
//A device with D3D12 support found. Init data
|
||||
supportsD3D12 = true;
|
||||
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
pAdapter->GetDesc(&desc);
|
||||
D3D12Adapters.append(QString::fromWCharArray(desc.Description));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// check for vulkan adapters
|
||||
vk::context device_enum_context;
|
||||
u32 instance_handle = device_enum_context.createInstance("RPCS3", true);
|
||||
|
||||
if (instance_handle > 0)
|
||||
{
|
||||
device_enum_context.makeCurrentInstance(instance_handle);
|
||||
std::vector<vk::physical_device>& gpus = device_enum_context.enumerateDevices();
|
||||
|
||||
if (gpus.size() > 0)
|
||||
{
|
||||
//A device with vulkan support found. Init data
|
||||
supportsVulkan = true;
|
||||
|
||||
for (auto& gpu : gpus)
|
||||
{
|
||||
vulkanAdapters.append(qstr(gpu.name()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emu_settings::emu_settings(const std::string& path) : QObject()
|
||||
{
|
||||
// Create config path if necessary
|
||||
|
|
|
@ -12,18 +12,6 @@
|
|||
#include <QObject>
|
||||
#include <QComboBox>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <Windows.h>
|
||||
#undef GetHwnd
|
||||
#include <d3d12.h>
|
||||
#include <wrl/client.h>
|
||||
#include <dxgi1_4.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Emu/RSX/VK/VKHelpers.h"
|
||||
#endif
|
||||
|
||||
inline QString qstr(const std::string& _in) { return QString::fromUtf8(_in.data(), _in.size()); }
|
||||
|
||||
struct Render_Creator
|
||||
|
@ -36,60 +24,7 @@ struct Render_Creator
|
|||
QString render_D3D12 = QObject::tr("D3D12");
|
||||
QString render_OpenGL = QObject::tr("OpenGL");
|
||||
|
||||
Render_Creator()
|
||||
{
|
||||
// check for dx12 adapters
|
||||
#ifdef _MSC_VER
|
||||
Microsoft::WRL::ComPtr<IDXGIFactory4> dxgi_factory;
|
||||
supportsD3D12 = SUCCEEDED(CreateDXGIFactory(IID_PPV_ARGS(&dxgi_factory)));
|
||||
|
||||
if (supportsD3D12)
|
||||
{
|
||||
supportsD3D12 = false;
|
||||
IDXGIAdapter1* pAdapter = nullptr;
|
||||
|
||||
for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != dxgi_factory->EnumAdapters1(adapterIndex, &pAdapter); ++adapterIndex)
|
||||
{
|
||||
HMODULE D3D12Module = verify("d3d12.dll", LoadLibrary(L"d3d12.dll"));
|
||||
PFN_D3D12_CREATE_DEVICE wrapD3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(D3D12Module, "D3D12CreateDevice");
|
||||
|
||||
if (SUCCEEDED(wrapD3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
|
||||
{
|
||||
//A device with D3D12 support found. Init data
|
||||
supportsD3D12 = true;
|
||||
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
pAdapter->GetDesc(&desc);
|
||||
D3D12Adapters.append(QString::fromWCharArray(desc.Description));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// check for vulkan adapters
|
||||
#ifdef _WIN32
|
||||
vk::context device_enum_context;
|
||||
u32 instance_handle = device_enum_context.createInstance("RPCS3", true);
|
||||
|
||||
if (instance_handle > 0)
|
||||
{
|
||||
device_enum_context.makeCurrentInstance(instance_handle);
|
||||
std::vector<vk::physical_device>& gpus = device_enum_context.enumerateDevices();
|
||||
|
||||
if (gpus.size() > 0)
|
||||
{
|
||||
//A device with vulkan support found. Init data
|
||||
supportsVulkan = true;
|
||||
|
||||
for (auto& gpu : gpus)
|
||||
{
|
||||
vulkanAdapters.append(qstr(gpu.name()));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
Render_Creator();
|
||||
};
|
||||
|
||||
// Node location
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit de3b2056edb91a439d856f1a84817c433ac1293c
|
Loading…
Add table
Reference in a new issue