Hooked up RT64 draw callbacks, fixed incorrect iobuf for reading ROM

This commit is contained in:
Mr-Wiseguy 2023-10-30 22:41:05 -04:00
parent b457b3d19a
commit dd30250623
7 changed files with 149 additions and 5 deletions

View File

@ -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}")

View File

@ -77,5 +77,7 @@ DLLIMPORT void ProcessDList(void);
DLLIMPORT void UpdateScreen(void);
DLLIMPORT void ChangeWindow(void);
void set_rt64_hooks();
#endif

6
shaders/InterfacePS.hlsl Normal file
View File

@ -0,0 +1,6 @@
void PSMain(
out float4 resultColor : SV_TARGET
)
{
resultColor = float4(1,0,0,1);
}

10
shaders/InterfaceVS.hlsl Normal file
View File

@ -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);
}

View File

@ -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<char> iobuf = std::make_unique<char>(iobuf_size);
std::unique_ptr<char[]> iobuf = std::make_unique<char[]>(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<uint8_t[]>(rom_size);
rom_file.read(reinterpret_cast<char*>(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

View File

@ -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) {

102
src/ui.cpp Normal file
View File

@ -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<RT64::RenderPipelineLayout> layout;
std::unique_ptr<RT64::RenderShader> vertex_shader;
std::unique_ptr<RT64::RenderShader> pixel_shader;
std::unique_ptr<RT64::RenderPipeline> pipeline;
std::unique_ptr<RT64::RenderBuffer> 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);
}