From dd3025062382162196db7dba1ed9a9f32e26d335 Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Mon, 30 Oct 2023 22:41:05 -0400 Subject: [PATCH] Hooked up RT64 draw callbacks, fixed incorrect iobuf for reading ROM --- CMakeLists.txt | 26 ++++++++++ include/rt64_layer.h | 2 + shaders/InterfacePS.hlsl | 6 +++ shaders/InterfaceVS.hlsl | 10 ++++ src/recomp.cpp | 6 +-- src/rt64_layer.cpp | 2 + src/ui.cpp | 102 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 149 insertions(+), 5 deletions(-) create mode 100644 shaders/InterfacePS.hlsl create mode 100644 shaders/InterfaceVS.hlsl create mode 100644 src/ui.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c2c008..e54e60e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,7 @@ set (SOURCES ${CMAKE_SOURCE_DIR}/src/sp.cpp ${CMAKE_SOURCE_DIR}/src/vi.cpp ${CMAKE_SOURCE_DIR}/src/main/main.cpp + ${CMAKE_SOURCE_DIR}/src/ui.cpp ${CMAKE_SOURCE_DIR}/rsp/aspMain.cpp ${CMAKE_SOURCE_DIR}/rsp/njpgdspMain.cpp @@ -73,6 +74,10 @@ target_include_directories(MMRecomp PRIVATE ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/thirdparty ${CMAKE_SOURCE_DIR}/../mupen_rt64/mupen64plus-win32-deps/SDL2-2.26.3/include + ${CMAKE_SOURCE_DIR}/../mupen_rt64/mupen64plus-video-rt64/src + ${CMAKE_SOURCE_DIR}/../mupen_rt64/mupen64plus-video-rt64/src/rhi + ${CMAKE_SOURCE_DIR}/../mupen_rt64/mupen64plus-video-rt64/src/render + ${CMAKE_BINARY_DIR}/shaders ) target_compile_options(MMRecomp PRIVATE @@ -91,6 +96,27 @@ target_link_libraries(MMRecomp PRIVATE rt64 ) +# TODO fix the RT64 CMake script so that this doesn't need to be duplicated here +# For DXC +set (DXC_COMMON_OPTS "-I${PROJECT_SOURCE_DIR}/src") +set (DXC_DXIL_OPTS "-Wno-ignored-attributes") +set (DXC_SPV_OPTS "-spirv" "-fspv-target-env=vulkan1.0" "-fvk-use-dx-layout") +set (DXC_PS_OPTS "${DXC_COMMON_OPTS}" "-E" "PSMain" "-T ps_6_0" "-D DYNAMIC_RENDER_PARAMS") +set (DXC_VS_OPTS "${DXC_COMMON_OPTS}" "-E" "VSMain" "-T vs_6_0" "-D DYNAMIC_RENDER_PARAMS" "-fvk-invert-y") +set (DXC_CS_OPTS "${DXC_COMMON_OPTS}" "-E" "CSMain" "-T cs_6_0") +set (DXC_GS_OPTS "${DXC_COMMON_OPTS}" "-E" "GSMain" "-T gs_6_0") +set (DXC_RT_OPTS "${DXC_COMMON_OPTS}" "-D" "RT_SHADER" "-T" "lib_6_3" "-fspv-target-env=vulkan1.1spirv1.4" "-fspv-extension=SPV_KHR_ray_tracing" "-fspv-extension=SPV_EXT_descriptor_indexing") + +if (${WIN32}) + set (DXC "${PROJECT_SOURCE_DIR}/../mupen_rt64/mupen64plus-video-rt64/src/contrib/dxc/bin/x64/dxc.exe") + add_compile_definitions(NOMINMAX) +else() + set (DXC "LD_LIBRARY_PATH=${PROJECT_SOURCE_DIR}/../mupen_rt64/mupen64plus-video-rt64/src/contrib/dxc/lib/x64" "${PROJECT_SOURCE_DIR}/src/contrib/dxc/bin/x64/dxc") +endif() + +build_vertex_shader(MMRecomp "shaders/InterfaceVS.hlsl" "shaders/InterfaceVS.hlsl") +build_pixel_shader (MMRecomp "shaders/InterfacePS.hlsl" "shaders/InterfacePS.hlsl") + target_sources(MMRecomp PRIVATE ${SOURCES}) set_property(TARGET MMRecomp PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}") diff --git a/include/rt64_layer.h b/include/rt64_layer.h index 666969c..ae17119 100644 --- a/include/rt64_layer.h +++ b/include/rt64_layer.h @@ -77,5 +77,7 @@ DLLIMPORT void ProcessDList(void); DLLIMPORT void UpdateScreen(void); DLLIMPORT void ChangeWindow(void); +void set_rt64_hooks(); + #endif diff --git a/shaders/InterfacePS.hlsl b/shaders/InterfacePS.hlsl new file mode 100644 index 0000000..00fcc3f --- /dev/null +++ b/shaders/InterfacePS.hlsl @@ -0,0 +1,6 @@ +void PSMain( + out float4 resultColor : SV_TARGET +) +{ + resultColor = float4(1,0,0,1); +} diff --git a/shaders/InterfaceVS.hlsl b/shaders/InterfaceVS.hlsl new file mode 100644 index 0000000..44e19b3 --- /dev/null +++ b/shaders/InterfaceVS.hlsl @@ -0,0 +1,10 @@ +void VSMain( + in uint vert_id : SV_VertexID, + out float4 pos : SV_Position +) +{ + const float2 translation = 0.1f; + const float2 size = 0.1f; + float2 extent = float2(vert_id & 1 ? 1.0f : 0.0f, vert_id & 2 ? 1.0f : 0.0f); + pos = float4(extent * size + translation, 1.0f, 1.0f); +} diff --git a/src/recomp.cpp b/src/recomp.cpp index b3c1a5b..bddebb2 100644 --- a/src/recomp.cpp +++ b/src/recomp.cpp @@ -127,7 +127,7 @@ EXPORT extern "C" void init() { std::ifstream rom_file{ get_rom_name(), std::ios::binary }; size_t iobuf_size = 0x100000; - std::unique_ptr iobuf = std::make_unique(iobuf_size); + std::unique_ptr iobuf = std::make_unique(iobuf_size); rom_file.rdbuf()->pubsetbuf(iobuf.get(), iobuf_size); if (!rom_file) { @@ -142,10 +142,6 @@ EXPORT extern "C" void init() { rom = std::make_unique(rom_size); rom_file.read(reinterpret_cast(rom.get()), rom_size); - - // TODO remove this - // Modify the name in the rom header so RT64 doesn't find it - rom[0x2F] = 'O'; } // Initialize the overlays diff --git a/src/rt64_layer.cpp b/src/rt64_layer.cpp index 53aa4d4..672ee41 100644 --- a/src/rt64_layer.cpp +++ b/src/rt64_layer.cpp @@ -4,6 +4,7 @@ #include "../portultra/multilibultra.hpp" #include "rt64_layer.h" +#include "rt64_render_hooks.h" static uint8_t DMEM[0x1000]; static uint8_t IMEM[0x1000]; @@ -45,6 +46,7 @@ void dummy_check_interrupts() { } void RT64Init(uint8_t* rom, uint8_t* rdram, Multilibultra::WindowHandle window_handle) { + set_rt64_hooks(); // Dynamic loading //auto RT64 = LoadLibrary("RT64.dll"); //if (RT64 == 0) { diff --git a/src/ui.cpp b/src/ui.cpp new file mode 100644 index 0000000..b1b1da0 --- /dev/null +++ b/src/ui.cpp @@ -0,0 +1,102 @@ +#include "rt64_layer.h" +#include "rt64_render_hooks.h" +#include "rt64_render_interface_builders.h" + +#include "InterfaceVS.hlsl.spirv.h" +#include "InterfacePS.hlsl.spirv.h" + +#ifdef _WIN32 +# include "InterfaceVS.hlsl.dxil.h" +# include "InterfacePS.hlsl.dxil.h" +#endif + +#ifdef _WIN32 +# define GET_SHADER_BLOB(name, format) \ + ((format) == RT64::RenderShaderFormat::SPIRV ? name##BlobSPIRV : \ + (format) == RT64::RenderShaderFormat::DXIL ? name##BlobDXIL : nullptr) +# define GET_SHADER_SIZE(name, format) \ + ((format) == RT64::RenderShaderFormat::SPIRV ? std::size(name##BlobSPIRV) : \ + (format) == RT64::RenderShaderFormat::DXIL ? std::size(name##BlobDXIL) : 0) +#else +# define GET_SHADER_BLOB(name, format) \ + ((format) == RT64::RenderShaderFormat::SPIRV ? std::size(name##BlobSPIRV) : nullptr) +# define GET_SHADER_SIZE(name, format) \ + ((format) == RT64::RenderShaderFormat::SPIRV ? std::size(name##BlobSPIRV) : 0) +#endif + +struct { + struct { + std::unique_ptr layout; + std::unique_ptr vertex_shader; + std::unique_ptr pixel_shader; + std::unique_ptr pipeline; + std::unique_ptr index_buffer; + RT64::RenderIndexBufferView index_buffer_view; + } Interface; +} UIContext; + +void init_hook(RT64::RenderInterface* interface, RT64::RenderDevice* device) { + printf("RT64 hook init\n"); + + RT64::RenderPipelineLayoutBuilder layout_builder{}; + layout_builder.begin(); + + layout_builder.end(); + UIContext.Interface.layout = layout_builder.create(device); + + RT64::RenderShaderFormat shaderFormat = interface->getCapabilities().shaderFormat; + + UIContext.Interface.vertex_shader = device->createShader(GET_SHADER_BLOB(InterfaceVS, shaderFormat), GET_SHADER_SIZE(InterfaceVS, shaderFormat), "VSMain", shaderFormat); + UIContext.Interface.pixel_shader = device->createShader(GET_SHADER_BLOB(InterfacePS, shaderFormat), GET_SHADER_SIZE(InterfacePS, shaderFormat), "PSMain", shaderFormat); + + RT64::RenderGraphicsPipelineDesc pipeline_desc{}; + + pipeline_desc.renderTargetBlend[0] = RT64::RenderBlendDesc::Copy(); + pipeline_desc.renderTargetFormat[0] = RT64::RenderFormat::B8G8R8A8_UNORM; // TODO: Use whatever format the swap chain was created with.; + pipeline_desc.renderTargetCount = 1; + pipeline_desc.cullMode = RT64::RenderCullMode::NONE; + pipeline_desc.depthClipEnabled = false; + pipeline_desc.depthEnabled = false; + pipeline_desc.depthWriteEnabled = false; + pipeline_desc.depthTargetFormat = RT64::RenderFormat::D32_FLOAT; + pipeline_desc.inputSlots = nullptr; + pipeline_desc.inputSlotsCount = 0; + pipeline_desc.inputElements = nullptr; + pipeline_desc.inputElementsCount = 0; + pipeline_desc.pipelineLayout = UIContext.Interface.layout.get(); + pipeline_desc.primitiveTopology = RT64::RenderPrimitiveTopology::TRIANGLE_LIST; + pipeline_desc.vertexShader = UIContext.Interface.vertex_shader.get(); + pipeline_desc.pixelShader = UIContext.Interface.pixel_shader.get(); + + UIContext.Interface.pipeline = device->createGraphicsPipeline(pipeline_desc); + + + static const uint32_t indices[] = {0, 1, 2, 1, 3, 2}; + UIContext.Interface.index_buffer = device->createBuffer(RT64::RenderBufferDesc::IndexBuffer(sizeof(indices), RT64::RenderHeapType::UPLOAD)); + + { + void* bufferData = UIContext.Interface.index_buffer->map(); + memcpy(bufferData, indices, sizeof(indices)); + UIContext.Interface.index_buffer->unmap(); + } + + UIContext.Interface.index_buffer_view = RT64::RenderIndexBufferView(UIContext.Interface.index_buffer.get(), sizeof(indices), RT64::RenderFormat::R32_UINT); +} + +void draw_hook(RT64::RenderCommandList* command_list, RT64::RenderTexture* swap_chain_texture) { + printf("RT64 hook draw\n"); + + command_list->barriers(RT64::RenderTextureBarrier::Transition(swap_chain_texture, RT64::RenderTextureState::RENDER_TARGET)); + command_list->setGraphicsPipelineLayout(UIContext.Interface.layout.get()); + command_list->setPipeline(UIContext.Interface.pipeline.get()); + command_list->setIndexBuffer(&UIContext.Interface.index_buffer_view); + command_list->drawIndexedInstanced(6, 1, 0, 0, 0); +} + +void deinit_hook() { + +} + +void set_rt64_hooks() { + RT64::SetRenderHooks(init_hook, draw_hook, deinit_hook); +}