Skip to content

Commit 252640b

Browse files
committed
Finished Vulkan initialization
1 parent 4584fed commit 252640b

14 files changed

Lines changed: 766 additions & 23 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
uses: humbletim/setup-vulkan-sdk@v1.2.1
6666
with:
6767
vulkan-query-version: '1.4.341.0'
68-
vulkan-components: Vulkan-Headers, Vulkan-Loader
68+
vulkan-components: Vulkan-Headers, Vulkan-Loader, Glslang, SPIRV-Tools
6969
vulkan-use-cache: true
7070
- name: Generate CMake Files
7171
# NOTES:

CMakeLists.txt

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ if(${WINDEPLOYQT_EXECUTABLE} STREQUAL "")
2323
endif()
2424
endif()
2525

26-
find_package(Vulkan REQUIRED)
26+
find_package(Vulkan REQUIRED COMPONENTS glslang)
2727

2828
find_package(Git)
2929
if(Git_FOUND)
@@ -44,10 +44,6 @@ set(CMAKE_AUTOMOC ON)
4444
set(CMAKE_AUTORCC ON)
4545
set(CMAKE_AUTOUIC ON)
4646

47-
option(LIB86CPU_BUILD_SHARED_LIB "Build shared libraries" OFF)
48-
option(LIB86CPU_XBOX_BUILD "Building Xbox version" ON)
49-
add_subdirectory("import/lib86cpu")
50-
5147
if(CMAKE_GENERATOR MATCHES "Visual Studio")
5248
set(GENERATOR_IS_VS TRUE)
5349
elseif(CMAKE_GENERATOR MATCHES "Unix Makefiles")
@@ -62,6 +58,43 @@ else()
6258
message(FATAL_ERROR "Unsupported compiler")
6359
endif()
6460

61+
set(SHADER_DIR "${CMAKE_CURRENT_SOURCE_DIR}/shaders")
62+
file(GLOB_RECURSE SHADERS CONFIGURE_DEPENDS
63+
${SHADER_DIR}/*.comp
64+
)
65+
66+
if(${GENERATOR_IS_VS})
67+
set(SPIRV_BIN "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/shaders")
68+
else()
69+
set(SPIRV_BIN "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/shaders")
70+
endif()
71+
72+
function(compile_shader shader)
73+
get_filename_component(FILE_NAME ${shader} NAME)
74+
set(SPIRV_OUTPUT "${SPIRV_BIN}/${FILE_NAME}.spv")
75+
76+
add_custom_command(
77+
OUTPUT ${SPIRV_OUTPUT}
78+
COMMAND glslang --target-env vulkan1.1 ${shader} -o ${SPIRV_OUTPUT}
79+
COMMENT "Compiling ${shader} to SPIR-V"
80+
DEPENDS ${shader}
81+
VERBATIM
82+
)
83+
84+
list(APPEND SPIRV_SHADERS ${SPIRV_OUTPUT})
85+
set(SPIRV_SHADERS ${SPIRV_SHADERS} PARENT_SCOPE)
86+
endfunction()
87+
88+
foreach(SHADER ${SHADERS})
89+
compile_shader(${SHADER})
90+
endforeach()
91+
92+
add_custom_target(Shaders ALL DEPENDS ${SPIRV_SHADERS})
93+
94+
option(LIB86CPU_BUILD_SHARED_LIB "Build shared libraries" OFF)
95+
option(LIB86CPU_XBOX_BUILD "Building Xbox version" ON)
96+
add_subdirectory("import/lib86cpu")
97+
6598
if(${GENERATOR_IS_UMAKE})
6699
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug")
67100
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release")
@@ -80,6 +113,7 @@ include_directories(
80113
${NXBX_ROOT_DIR}/src/qt
81114
${NXBX_ROOT_DIR}/src/nxbx/fs
82115
${NXBX_ROOT_DIR}/src/nxbx/hw
116+
${NXBX_ROOT_DIR}/src/nxbx/hw/video/renderer
83117
${Vulkan_INCLUDE_DIRS}
84118
)
85119

@@ -134,6 +168,8 @@ set(HEADERS
134168
"${NXBX_ROOT_DIR}/src/nxbx/hw/video/gpu/pvga.hpp"
135169
"${NXBX_ROOT_DIR}/src/nxbx/hw/video/gpu/pvideo.hpp"
136170
"${NXBX_ROOT_DIR}/src/nxbx/hw/video/gpu/puser.hpp"
171+
"${NXBX_ROOT_DIR}/src/nxbx/hw/video/renderer/graphics_api.hpp"
172+
"${NXBX_ROOT_DIR}/src/nxbx/hw/video/renderer/vk/init.hpp"
137173
)
138174

139175
set(SOURCES
@@ -180,12 +216,14 @@ set(SOURCES
180216
"${NXBX_ROOT_DIR}/src/nxbx/hw/video/gpu/pvga.cpp"
181217
"${NXBX_ROOT_DIR}/src/nxbx/hw/video/gpu/pvideo.cpp"
182218
"${NXBX_ROOT_DIR}/src/nxbx/hw/video/gpu/puser.cpp"
219+
"${NXBX_ROOT_DIR}/src/nxbx/hw/video/renderer/vk/init.cpp"
183220
)
184221

185222
source_group(TREE ${NXBX_ROOT_DIR} PREFIX header FILES ${HEADERS})
186223
source_group(TREE ${NXBX_ROOT_DIR} PREFIX source FILES ${SOURCES})
187224

188225
add_executable(nxbx ${HEADERS} ${SOURCES})
226+
add_dependencies(nxbx Shaders)
189227
target_link_libraries(nxbx
190228
PRIVATE cpu
191229
PRIVATE Qt6::Core

shaders/pb_pusher.comp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#version 450
2+
3+
void main()
4+
{
5+
// pb pusher compute shader not implemented yet
6+
}

src/common/host.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct init_info_t {
3434
std::string keys_path;
3535
disas_syntax syntax;
3636
uint32_t use_dbg;
37+
uint32_t vkdbg;
3738
console_t console_type;
3839
input_t input_type;
3940
int32_t sync_part;
@@ -43,6 +44,8 @@ struct boot_params {
4344
disas_syntax syntax;
4445
uint32_t use_dbg;
4546
console_t console_type;
47+
std::string nxbx_dir;
48+
uint32_t vkdbg;
4649
};
4750

4851
namespace Host

src/common/logger.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#define module_enabled() check_if_enabled<log_module::MODULE_NAME>()
2323
#define mod_lv2str(lv, mod, msg) mod_lv_to_string<log_lv::lv, log_module::mod>(msg)
2424
#define lv2str(lv, msg) mod_lv_to_string<log_lv::lv, log_module::MODULE_NAME>(msg)
25+
#define highestlv2str(msg) mod_lv_to_string<log_lv::highest, log_module::MODULE_NAME>(msg)
2526

2627
#define NUM_OF_LOG_MODULES32 std::to_underlying(log_module::max) / 32 + 1
2728

@@ -68,6 +69,7 @@ enum class log_module : int32_t
6869
adm1032,
6970
conexant,
7071
usb0,
72+
vulkan,
7173
max,
7274
};
7375

@@ -100,7 +102,8 @@ inline constexpr std::array module_to_str =
100102
"SMC -> ",
101103
"ADM -> ",
102104
"CONEXANT -> ",
103-
"USB0 -> "
105+
"USB0 -> ",
106+
"VULKAN -> "
104107
};
105108
static_assert(module_to_str.size() == (uint32_t)(log_module::max));
106109

src/nxbx/console.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "console.hpp"
55
#include "io.hpp"
66
#include "clock.hpp"
7+
#include "cpu.hpp"
8+
#include "vk/init.hpp"
79
#include <functional>
810

911

@@ -30,12 +32,24 @@ console::console(const boot_params &params)
3032
m_machine.deinit();
3133
return;
3234
}
35+
// We only support Vulkan for now
36+
try {
37+
m_renderer = new Vulkan;
38+
dynamic_cast<Vulkan *>(m_renderer)->setValidationLayers(params.vkdbg);
39+
m_renderer->init(params.nxbx_dir, m_machine.getCpu()->getRamPtr(), m_machine.getCpu()->getRamsize());
40+
}
41+
catch (std::runtime_error e) {
42+
logger(e.what());
43+
return;
44+
}
3345
io::init(m_machine.get86cpu());
3446
m_state = console_state::initialized;
3547
}
3648

3749
void console::deinit()
3850
{
51+
m_renderer->deinit();
52+
delete m_renderer;
3953
io::stop();
4054
m_machine.deinit();
4155
m_state = console_state::shut_down;

src/nxbx/console.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "machine.hpp"
88
#include "smc.hpp"
99
#include "host.hpp"
10+
#include "graphics_api.hpp"
1011
#include <atomic>
1112
#include <thread>
1213

@@ -45,6 +46,7 @@ class console {
4546
std::atomic<console_state> m_state;
4647
boot_params m_params;
4748
std::jthread m_cpu_thr;
49+
GraphicsAPI *m_renderer;
4850
};
4951

5052
extern console* g_console;

src/nxbx/hw/cpu.cpp

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,14 @@ class cpu::Impl
3737
uint64_t checkPeriodicEvents(uint64_t now);
3838
cpu_t *get86cpu() { return m_lc86cpu; }
3939
uint32_t getRamsize() { return m_ramsize; }
40+
uint8_t *getRamPtr() { return m_ram; }
4041

4142
private:
4243
void updateIo(bool is_update);
4344
uint64_t checkPeriodicEvents();
4445
static void cpu_logger(log_level lv, const unsigned count, const char *msg, ...);
4546

47+
uint8_t *m_ram;
4648
uint32_t m_ramsize;
4749
bool m_is_dbg_present;
4850
// connected devices
@@ -142,7 +144,8 @@ void cpu::Impl::init(const boot_params &params, machine *machine)
142144
}
143145

144146
// Init lib86cpu
145-
if (!LC86_SUCCESS(cpu_new(m_ramsize, m_lc86cpu))) {
147+
// The ram pointer must have a proper alignment to be imported in Vulkan. Here, we are using the same value used in parallel-rdp
148+
if (!LC86_SUCCESS(cpu_new(m_ramsize, m_lc86cpu, { nullptr, nullptr }, 64 * 1024))) {
146149
throw std::runtime_error(lv2str(highest, "Failed to create cpu instance"));
147150
}
148151

@@ -166,13 +169,13 @@ void cpu::Impl::init(const boot_params &params, machine *machine)
166169
updateIo(false);
167170

168171
// Load kernel exe into ram
169-
uint8_t *ram = get_ram_ptr(m_lc86cpu);
172+
m_ram = get_ram_ptr(m_lc86cpu);
170173
uint32_t ImageAddress = peHeader->OptionalHeader.ImageBase - CONTIGUOUS_MEMORY_BASE; // =0x10000
171-
std::memcpy(&ram[ImageAddress], dosHeader, peHeader->OptionalHeader.SizeOfHeaders);
174+
std::memcpy(&m_ram[ImageAddress], dosHeader, peHeader->OptionalHeader.SizeOfHeaders);
172175

173176
PIMAGE_SECTION_HEADER sections = reinterpret_cast<PIMAGE_SECTION_HEADER>(reinterpret_cast<uint8_t *>(peHeader) + sizeof(IMAGE_NT_HEADERS32));
174177
for (uint16_t i = 0; i < peHeader->FileHeader.NumberOfSections; ++i) {
175-
uint8_t *dest = &ram[ImageAddress + sections[i].VirtualAddress];
178+
uint8_t *dest = &m_ram[ImageAddress + sections[i].VirtualAddress];
176179
std::memcpy(dest, reinterpret_cast<uint8_t *>(dosHeader) + sections[i].PointerToRawData, sections[i].SizeOfRawData);
177180
if (sections[i].SizeOfRawData < sections[i].Misc.VirtualSize) {
178181
std::memset(dest + sections[i].SizeOfRawData, 0, sections[i].Misc.VirtualSize - sections[i].SizeOfRawData);
@@ -182,17 +185,17 @@ void cpu::Impl::init(const boot_params &params, machine *machine)
182185
// Make sure that we run the latest version of the kernel
183186
// NOTE: this must happen after the kernel has been loaded in the guest virtual memory, because the export table is given with guest relative virtual addresses
184187
bool KernelVersionFound = false;
185-
PIMAGE_EXPORT_DIRECTORY ImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(&ram[ImageAddress + peHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress]);
188+
PIMAGE_EXPORT_DIRECTORY ImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(&m_ram[ImageAddress + peHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress]);
186189
uint32_t NumOfNames = ImageExportDirectory->NumberOfNames;
187-
uint32_t *ExportAddressTable = (uint32_t *)(&ram[ImageAddress + ImageExportDirectory->AddressOfFunctions]);
188-
uint16_t *NameOrdinalsPointer = (uint16_t *)(&ram[ImageAddress + ImageExportDirectory->AddressOfNameOrdinals]);
189-
uint32_t *ExportNamePointerTable = (uint32_t *)(&ram[ImageAddress + ImageExportDirectory->AddressOfNames]);
190+
uint32_t *ExportAddressTable = (uint32_t *)(&m_ram[ImageAddress + ImageExportDirectory->AddressOfFunctions]);
191+
uint16_t *NameOrdinalsPointer = (uint16_t *)(&m_ram[ImageAddress + ImageExportDirectory->AddressOfNameOrdinals]);
192+
uint32_t *ExportNamePointerTable = (uint32_t *)(&m_ram[ImageAddress + ImageExportDirectory->AddressOfNames]);
190193

191194
for (uint32_t i = 0; i < NumOfNames; i++) {
192-
char *ExportName = (char *)(&ram[ImageAddress + ExportNamePointerTable[i]]);
195+
char *ExportName = (char *)(&m_ram[ImageAddress + ExportNamePointerTable[i]]);
193196
if (std::strcmp("NboxkrnlVersion", ExportName) == 0) {
194-
uint32_t *NboxkrnlVersionAddress = (uint32_t *)(&ram[ImageAddress + ExportAddressTable[NameOrdinalsPointer[i]]]);
195-
std::string FoundNboxkrnlVersion((const char *)&ram[(*NboxkrnlVersionAddress) - CONTIGUOUS_MEMORY_BASE]);
197+
uint32_t *NboxkrnlVersionAddress = (uint32_t *)(&m_ram[ImageAddress + ExportAddressTable[NameOrdinalsPointer[i]]]);
198+
std::string FoundNboxkrnlVersion((const char *)&m_ram[(*NboxkrnlVersionAddress) - CONTIGUOUS_MEMORY_BASE]);
196199
std::string ExpectedNboxkrnlVersion(_NBOXKRNL_HEAD_REF);
197200
auto pos = ExpectedNboxkrnlVersion.find_first_of('\t');
198201
if (pos != std::string::npos) {
@@ -457,6 +460,11 @@ uint32_t cpu::getRamsize()
457460
return m_impl->getRamsize();
458461
}
459462

463+
uint8_t *cpu::getRamPtr()
464+
{
465+
return m_impl->getRamPtr();
466+
}
467+
460468
uint64_t cpu::checkPeriodicEvents(uint64_t now)
461469
{
462470
return m_impl->checkPeriodicEvents(now);

src/nxbx/hw/cpu.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class cpu
2727
uint64_t checkPeriodicEvents(uint64_t now);
2828
cpu_t *get86cpu();
2929
uint32_t getRamsize();
30+
uint8_t *getRamPtr();
3031

3132
private:
3233
class Impl;

0 commit comments

Comments
 (0)