Update opengl.hpp, start with ELFs

This commit is contained in:
wheremyfoodat 2022-09-15 14:59:44 +03:00
parent 1a8d563041
commit 51689af51f
8 changed files with 469 additions and 392 deletions

View file

@ -30,6 +30,7 @@ set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/third_party/boost")
set(Boost_NO_SYSTEM_PATHS ON) set(Boost_NO_SYSTEM_PATHS ON)
add_library(boost INTERFACE) add_library(boost INTERFACE)
target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR}) target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR})
add_compile_definitions(NOMINMAX)
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "x86-64") if(CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "x86-64")
set(DYNARMIC_TESTS OFF) set(DYNARMIC_TESTS OFF)
@ -42,7 +43,7 @@ else()
message(FATAL_ERROR "THIS IS NOT x64 WAIT FOR THE KVM IMPLEMENTATION") message(FATAL_ERROR "THIS IS NOT x64 WAIT FOR THE KVM IMPLEMENTATION")
endif() endif()
set(SOURCE_FILES src/main.cpp src/emulator.cpp src/core/CPU/cpu_dynarmic.cpp src/core/memory.cpp) set(SOURCE_FILES src/main.cpp src/emulator.cpp src/core/CPU/cpu_dynarmic.cpp src/core/memory.cpp src/core/elf.cpp)
set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/opengl.hpp include/termcolor.hpp set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/opengl.hpp include/termcolor.hpp
include/cpu.hpp include/cpu_dynarmic.hpp include/memory.hpp include/cpu.hpp include/cpu_dynarmic.hpp include/memory.hpp
) )

View file

@ -1,5 +1,7 @@
#pragma once #pragma once
#define NOMINMAX // Windows why
#include <filesystem>
#include "cpu.hpp" #include "cpu.hpp"
#include "helpers.hpp" #include "helpers.hpp"
#include "opengl.hpp" #include "opengl.hpp"
@ -25,4 +27,6 @@ public:
void reset(); void reset();
void run(); void run();
void runFrame(); void runFrame();
bool loadELF(std::filesystem::path& path);
}; };

View file

@ -1,4 +1,6 @@
#pragma once #pragma once
#include <filesystem>
#include <optional>
#include <vector> #include <vector>
#include "helpers.hpp" #include "helpers.hpp"
@ -15,4 +17,6 @@ public:
Memory(); Memory();
void* getReadPointer(u32 address); void* getReadPointer(u32 address);
void* getWritePointer(u32 address); void* getWritePointer(u32 address);
std::optional<u32> loadELF(std::filesystem::path& path);
}; };

View file

@ -60,19 +60,26 @@ struct VertexArray {
void setAttributeFloat(GLuint index, GLint size, GLsizei stride, const void* offset, bool normalized = false) { void setAttributeFloat(GLuint index, GLint size, GLsizei stride, const void* offset, bool normalized = false) {
if constexpr (std::is_same<T, GLfloat>()) { if constexpr (std::is_same<T, GLfloat>()) {
glVertexAttribPointer(index, size, GL_FLOAT, normalized, stride, offset); glVertexAttribPointer(index, size, GL_FLOAT, normalized, stride, offset);
} else if constexpr (std::is_same<T, GLbyte>()) { }
else if constexpr (std::is_same<T, GLbyte>()) {
glVertexAttribPointer(index, size, GL_BYTE, normalized, stride, offset); glVertexAttribPointer(index, size, GL_BYTE, normalized, stride, offset);
} else if constexpr (std::is_same<T, GLubyte>()) { }
else if constexpr (std::is_same<T, GLubyte>()) {
glVertexAttribPointer(index, size, GL_UNSIGNED_BYTE, normalized, stride, offset); glVertexAttribPointer(index, size, GL_UNSIGNED_BYTE, normalized, stride, offset);
} else if constexpr (std::is_same<T, GLshort>()) { }
else if constexpr (std::is_same<T, GLshort>()) {
glVertexAttribPointer(index, size, GL_SHORT, normalized, stride, offset); glVertexAttribPointer(index, size, GL_SHORT, normalized, stride, offset);
} else if constexpr (std::is_same<T, GLushort>()) { }
else if constexpr (std::is_same<T, GLushort>()) {
glVertexAttribPointer(index, size, GL_UNSIGNED_SHORT, normalized, stride, offset); glVertexAttribPointer(index, size, GL_UNSIGNED_SHORT, normalized, stride, offset);
} else if constexpr (std::is_same<T, GLint>()) { }
else if constexpr (std::is_same<T, GLint>()) {
glVertexAttribPointer(index, size, GL_INT, normalized, stride, offset); glVertexAttribPointer(index, size, GL_INT, normalized, stride, offset);
} else if constexpr (std::is_same<T, GLuint>()) { }
else if constexpr (std::is_same<T, GLuint>()) {
glVertexAttribPointer(index, size, GL_UNSIGNED_INT, normalized, stride, offset); glVertexAttribPointer(index, size, GL_UNSIGNED_INT, normalized, stride, offset);
} else { }
else {
static_assert(AlwaysFalse<T>, "Unimplemented type for OpenGL::setAttributeFloat"); static_assert(AlwaysFalse<T>, "Unimplemented type for OpenGL::setAttributeFloat");
} }
} }
@ -81,17 +88,23 @@ struct VertexArray {
void setAttributeInt(GLuint index, GLint size, GLsizei stride, const void* offset) { void setAttributeInt(GLuint index, GLint size, GLsizei stride, const void* offset) {
if constexpr (std::is_same<T, GLbyte>()) { if constexpr (std::is_same<T, GLbyte>()) {
glVertexAttribIPointer(index, size, GL_BYTE, stride, offset); glVertexAttribIPointer(index, size, GL_BYTE, stride, offset);
} else if constexpr (std::is_same<T, GLubyte>()) { }
else if constexpr (std::is_same<T, GLubyte>()) {
glVertexAttribIPointer(index, size, GL_UNSIGNED_BYTE, stride, offset); glVertexAttribIPointer(index, size, GL_UNSIGNED_BYTE, stride, offset);
} else if constexpr (std::is_same<T, GLshort>()) { }
else if constexpr (std::is_same<T, GLshort>()) {
glVertexAttribIPointer(index, size, GL_SHORT, stride, offset); glVertexAttribIPointer(index, size, GL_SHORT, stride, offset);
} else if constexpr (std::is_same<T, GLushort>()) { }
else if constexpr (std::is_same<T, GLushort>()) {
glVertexAttribIPointer(index, size, GL_UNSIGNED_SHORT, stride, offset); glVertexAttribIPointer(index, size, GL_UNSIGNED_SHORT, stride, offset);
} else if constexpr (std::is_same<T, GLint>()) { }
else if constexpr (std::is_same<T, GLint>()) {
glVertexAttribIPointer(index, size, GL_INT, stride, offset); glVertexAttribIPointer(index, size, GL_INT, stride, offset);
} else if constexpr (std::is_same<T, GLuint>()) { }
else if constexpr (std::is_same<T, GLuint>()) {
glVertexAttribIPointer(index, size, GL_UNSIGNED_INT, stride, offset); glVertexAttribIPointer(index, size, GL_UNSIGNED_INT, stride, offset);
} else { }
else {
static_assert(AlwaysFalse<T>, "Unimplemented type for OpenGL::setAttributeInt"); static_assert(AlwaysFalse<T>, "Unimplemented type for OpenGL::setAttributeInt");
} }
} }
@ -142,7 +155,8 @@ struct Texture {
} }
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalFormat, width, height, GL_TRUE); glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalFormat, width, height, GL_TRUE);
} else { }
else {
glTexStorage2D(binding, 1, internalFormat, width, height); glTexStorage2D(binding, 1, internalFormat, width, height);
} }
} }
@ -228,7 +242,7 @@ struct Shader {
GLint success; GLint success;
glGetShaderiv(m_handle, GL_COMPILE_STATUS, &success); glGetShaderiv(m_handle, GL_COMPILE_STATUS, &success);
if (!success) { if (success == GL_FALSE) {
char buf[4096]; char buf[4096];
glGetShaderInfoLog(m_handle, 4096, nullptr, buf); glGetShaderInfoLog(m_handle, 4096, nullptr, buf);
fprintf(stderr, "Failed to compile shader\nError: %s\n", buf); fprintf(stderr, "Failed to compile shader\nError: %s\n", buf);
@ -274,6 +288,10 @@ struct Program {
void use() { glUseProgram(m_handle); } void use() { glUseProgram(m_handle); }
}; };
static void dispatchCompute(GLuint groupsX = 1, GLuint groupsY = 1, GLuint groupsZ = 1) {
glDispatchCompute(groupsX, groupsY, groupsZ);
}
struct VertexBuffer { struct VertexBuffer {
GLuint m_handle = 0; GLuint m_handle = 0;
@ -316,20 +334,30 @@ struct VertexBuffer {
static void setClearColor(float val) { glClearColor(val, val, val, val); } static void setClearColor(float val) { glClearColor(val, val, val, val); }
static void setClearColor(float r, float g, float b, float a) { glClearColor(r, g, b, a); } static void setClearColor(float r, float g, float b, float a) { glClearColor(r, g, b, a); }
static void setClearDepth(float depth) { glClearDepthf(depth); } static void setClearDepth(float depth) { glClearDepthf(depth); }
static void setClearStencil(GLint stencil) { glClearStencil(stencil); }
static void clearColor() { glClear(GL_COLOR_BUFFER_BIT); } static void clearColor() { glClear(GL_COLOR_BUFFER_BIT); }
static void clearDepth() { glClear(GL_DEPTH_BUFFER_BIT); } static void clearDepth() { glClear(GL_DEPTH_BUFFER_BIT); }
static void clearStencil() { glClear(GL_STENCIL_BUFFER_BIT); }
static void clearColorAndDepth() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } static void clearColorAndDepth() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); }
static void clearColorAndStencil() { glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); }
static void clearDepthAndStencil() { glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); }
static void clearAll() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); }
static void setViewport(GLsizei width, GLsizei height) { glViewport(0, 0, width, height); } static void setViewport(GLsizei width, GLsizei height) { glViewport(0, 0, width, height); }
static void setViewport(GLsizei x, GLsizei y, GLsizei width, GLsizei height) { glViewport(x, y, width, height); } static void setViewport(GLsizei x, GLsizei y, GLsizei width, GLsizei height) { glViewport(x, y, width, height); }
static void setScissor(GLsizei width, GLsizei height) { glScissor(0, 0, width, height); } static void setScissor(GLsizei width, GLsizei height) { glScissor(0, 0, width, height); }
static void setScissor(GLsizei x, GLsizei y, GLsizei width, GLsizei height) { glScissor(x, y, width, height); } static void setScissor(GLsizei x, GLsizei y, GLsizei width, GLsizei height) { glScissor(x, y, width, height); }
static void setStencilMask(GLuint mask) { glStencilMask(mask); }
static void bindScreenFramebuffer() { glBindFramebuffer(GL_FRAMEBUFFER, 0); } static void bindScreenFramebuffer() { glBindFramebuffer(GL_FRAMEBUFFER, 0); }
static void enableScissor() { glEnable(GL_SCISSOR_TEST); } static void enableScissor() { glEnable(GL_SCISSOR_TEST); }
static void disableScissor() { glDisable(GL_SCISSOR_TEST); } static void disableScissor() { glDisable(GL_SCISSOR_TEST); }
static void enableBlend() { glEnable(GL_BLEND); } static void enableBlend() { glEnable(GL_BLEND); }
static void disableBlend() { glDisable(GL_BLEND); } static void disableBlend() { glDisable(GL_BLEND); }
static void enableDepth() { glEnable(GL_DEPTH_TEST); }
static void disableDepth() { glDisable(GL_DEPTH_TEST); }
static void enableStencil() { glEnable(GL_STENCIL_TEST); }
static void disableStencil() { glDisable(GL_STENCIL_TEST); }
enum Primitives { enum Primitives {
Triangle = GL_TRIANGLES, Triangle = GL_TRIANGLES,
@ -361,13 +389,17 @@ T get(GLenum query) {
T ret{}; T ret{};
if constexpr (std::is_same<T, GLint>()) { if constexpr (std::is_same<T, GLint>()) {
glGetIntegerv(query, &ret); glGetIntegerv(query, &ret);
} else if constexpr (std::is_same<T, GLfloat>()) { }
else if constexpr (std::is_same<T, GLfloat>()) {
glGetFloatv(query, &ret); glGetFloatv(query, &ret);
} else if constexpr (std::is_same<T, GLdouble>()) { }
else if constexpr (std::is_same<T, GLdouble>()) {
glGetDoublev(query, &ret); glGetDoublev(query, &ret);
} else if constexpr (std::is_same<T, GLboolean>()) { }
else if constexpr (std::is_same<T, GLboolean>()) {
glGetBooleanv(query, &ret); glGetBooleanv(query, &ret);
} else { }
else {
static_assert(AlwaysFalse<T>, "Invalid type for OpenGL::get"); static_assert(AlwaysFalse<T>, "Invalid type for OpenGL::get");
} }

View file

@ -9,7 +9,7 @@ CPU::CPU(Memory& mem) : mem(mem) {
// Write some code to memory. // Write some code to memory.
env.MemoryWrite16(0, 0x0088); // lsls r0, r1, #2 env.MemoryWrite16(0, 0x0088); // lsls r0, r1, #2
env.MemoryWrite16(2, 0x3045); // adds r0, #69 env.MemoryWrite16(2, 0x3045); // adds r0, #69
env.MemoryWrite16(4, 0xdf45); // swi #69 env.MemoryWrite16(4, 0x3845); // subs r0, #69
env.MemoryWrite16(6, 0xE7FE); // b +#0 (infinite loop) env.MemoryWrite16(6, 0xE7FE); // b +#0 (infinite loop)
// Setup registers. // Setup registers.

24
src/core/elf.cpp Normal file
View file

@ -0,0 +1,24 @@
#include "memory.hpp"
#include "elfio/elfio.hpp"
using namespace ELFIO;
std::optional<u32> Memory::loadELF(std::filesystem::path& path) {
elfio reader;
if (!reader.load(path.string())) {
printf("Woops failed to load ELF\n");
return std::nullopt;
}
auto seg_num = reader.segments.size();
printf("Number of segments: %d\n", seg_num);
for (int i = 0; i < seg_num; ++i) {
const auto pseg = reader.segments[i];
std::cout << " [" << i << "] 0x" << std::hex << pseg->get_flags()
<< "\t0x" << pseg->get_virtual_address() << "\t0x"
<< pseg->get_file_size() << "\t0x" << pseg->get_memory_size()
<< std::endl;
}
return static_cast<u32>(reader.get_entry());
}

View file

@ -35,3 +35,11 @@ void Emulator::runFrame() {
step(); step();
} }
} }
bool Emulator::loadELF(std::filesystem::path& path) {
std::optional<u32> entrypoint = memory.loadELF(path);
if (!entrypoint.has_value())
return false;
Helpers::panic("Entrypoint: %08X\n", entrypoint.value());
}

View file

@ -7,5 +7,9 @@ int main (int argc, char *argv[]) {
Helpers::panic("Failed to initialize OpenGL"); Helpers::panic("Failed to initialize OpenGL");
} }
auto elfPath = std::filesystem::current_path() / (argc > 1 ? argv[1] : "simple_tri.elf");
if (emu.loadELF(elfPath)) {
Helpers::panic("Failed to load ELF file: %s", elfPath.c_str());
}
emu.run(); emu.run();
} }