diff --git a/src/comet.c b/src/comet.c index b24d330..c676417 100755 --- a/src/comet.c +++ b/src/comet.c @@ -1,7 +1,7 @@ // ╭───────╮ // │ comet │ the Aphelion ISA reference emulator ☄️ // ╰───────╯ -// by kaylatheegg, spsandwichman +// by spsandwichman & kaylatheegg // using aphelion v0.4 @@ -120,7 +120,7 @@ int main(int argc, char *argv[]) { } //create gpu thread - pthread_create(&comet.gpu_thread_id, NULL, GPU_thread, NULL); + pthread_create(&comet.gpu_thread_id, NULL, gpu_thread, NULL); if (comet.flag_cycle_limit == 0) while (comet.cpu.running) { // if (gpu_is_drawing) sched_yield(); diff --git a/src/gpu/gpu.c b/src/gpu/gpu.c index c79fd37..c944fb4 100755 --- a/src/gpu/gpu.c +++ b/src/gpu/gpu.c @@ -3,56 +3,59 @@ #include "../comet.h" #include "../mmu.h" -GPU gpu; - -void init_GPU() { - gpu.frame = malloc(SCREEN_WIDTH*SCREEN_HEIGHT*sizeof(pixel)); - memset(gpu.frame, 0, SCREEN_WIDTH*SCREEN_HEIGHT*sizeof(pixel)); - - SDL_Init( SDL_INIT_VIDEO ); - gpu.window = SDL_CreateWindow("comet", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL); - gpu.renderer = SDL_CreateRenderer(gpu.window, -1, SDL_RENDERER_ACCELERATED); - SDL_Surface* icon = IMG_Load("src/img/comet_icon.bmp"); - SDL_SetWindowIcon(gpu.window, icon); - gl_init(); -} - -void *GPU_thread(void* argvp) { - - init_GPU(); - - SDL_Event e; - - while (true) { - if ( SDL_PollEvent(&e) ) { - switch (e.type) { - case SDL_QUIT: - comet.cpu.running = false; - break; - case SDL_TEXTINPUT: - printf("TEXT: %s\n", e.text.text); - TODO("text input"); - - default: - // printf("EVENT\n"); - break; - } - } - - if (comet.cpu.running == false) { - break; - } - - - if (gpu.is_drawing) { - GPU_draw(); - gpu.is_drawing = false; - } - - sched_yield(); - } - - comet.cpu.running = false; +SDL_Window* gpu_window; +SDL_Renderer* gpu_renderer; +SDL_GLContext* gpu_gl_context; + +// kayla's goofy ass opengl code +// i tried to modify it and it broke +// so now im not allowed to touch it + +#define SCREEN_WIDTH 800 +#define SCREEN_HEIGHT 600 + +bool gpu_is_drawing = false; +u64 gpu_framebuf = 0; + +void *gpu_thread(void* argvp) { + gpu_init(); + + int running = 1; + + SDL_Event e; + + while (running) { + if ( SDL_PollEvent(&e) ) { + switch (e.type) { + case SDL_QUIT: + comet.cpu.running = false; + break; + case SDL_TEXTINPUT: + printf("TEXT: %s\n", e.text.text); + TODO("text input"); + + default: + // printf("EVENT\n"); + break; + } + } + + if (comet.cpu.running == false) { + break; + } + + + if (gpu_is_drawing) { + sched_setscheduler(0, SCHED_FIFO, &(struct sched_param){.sched_priority = sched_get_priority_max(SCHED_FIFO)}); // lmfao + gpu_draw(); + gpu_is_drawing = false; + sched_setscheduler(0, SCHED_OTHER, &(struct sched_param){.sched_priority = sched_get_priority_max(SCHED_OTHER)}); + } + + sched_yield(); + } + + comet.cpu.running = false; } int gpu_vao; @@ -62,166 +65,173 @@ int gpu_texture; int gpu_program; void gl_init() { - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); - - gpu.gl_ctx = SDL_GL_CreateContext(gpu.window); - - if (gpu.gl_ctx == NULL) { - printf("FUCK!: %s\n", SDL_GetError()); - } - - SDL_GL_MakeCurrent(gpu.window, gpu.gl_ctx); - - GLenum err = glewInit(); - if (err != GLEW_OK) { - printf("GLEW initialisation failure, error: %s\n", glewGetErrorString(err)); - exit(-1); - } - - glEnable(GL_TEXTURE_2D); - - //create gpu shader - - char* vertex_shader[] = { - "#version 330 core\n", - "in vec2 position;\n", - "in vec2 texcoord;\n", - "out vec2 Texcoord;\n", - "void main() {\n", - " gl_Position = vec4(position, 0.0, 1.0);\n", - " Texcoord = texcoord;\n", - "}\n"}; - - char* fragment_shader[] = { - "#version 330 core\n", - "in vec2 Texcoord;\n", - "out vec4 FragColor;\n", - "uniform sampler2D tex;\n", - "void main() \n{", - " FragColor = texture(tex, Texcoord);\n", - "}\n" - }; - - - GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertexShaderID, 8, (const GLchar**)vertex_shader, NULL); - glCompileShader(vertexShaderID); - - int success; - char infoLog[512]; - glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &success); - if (success != GL_TRUE) { - glGetShaderInfoLog(vertexShaderID, 512, NULL, infoLog); - *(strchr(infoLog, '\n')) = ' '; //removes the newline opengl shoves in - printf("VS failure: %s\n", infoLog); - exit(-1); - } - - GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragmentShaderID, 7, (const GLchar**)fragment_shader, NULL); - glCompileShader(fragmentShaderID); - - glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &success); - if (success != GL_TRUE) { - glGetShaderInfoLog(fragmentShaderID, 512, NULL, infoLog); - *(strchr(infoLog, '\n')) = ' '; //removes the newline opengl shoves in - printf("FS failure: %s\n", infoLog); - exit(-1); - } - - gpu_program = glCreateProgram(); - glAttachShader(gpu_program, vertexShaderID); - glAttachShader(gpu_program, fragmentShaderID); - glLinkProgram(gpu_program); - - - glViewport(0,0, SCREEN_WIDTH, SCREEN_HEIGHT); - - glGenTextures(1, &gpu_texture); - glBindTexture(GL_TEXTURE_2D, gpu_texture); - - glGenVertexArrays(1, &gpu_vao); - glBindVertexArray(gpu_vao); - - glGenBuffers(1, &gpu_vbo); - glBindBuffer(GL_ARRAY_BUFFER, gpu_vbo); - - glGenBuffers(1, &gpu_ebo); - - GLint posAttrib = glGetAttribLocation(gpu_program, "position"); - glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0); - glEnableVertexAttribArray(posAttrib); - - GLint texAttrib = glGetAttribLocation(gpu_program, "texcoord"); - glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), (void*)(2*sizeof(float))); //here - glEnableVertexAttribArray(texAttrib); - - glClearColor(0.f, 0.f, 0.f, 1.0f); - SDL_GL_SetSwapInterval(0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + + gpu_gl_context = SDL_GL_CreateContext(gpu_window); + + if (gpu_gl_context == NULL) { + printf("FUCK!: %s\n", SDL_GetError()); + } + + SDL_GL_MakeCurrent(gpu_window, gpu_gl_context); + + GLenum err = glewInit(); + if (err != GLEW_OK) { + printf("GLEW initialisation failure, error: %s\n", glewGetErrorString(err)); + exit(-1); + } + + glEnable(GL_TEXTURE_2D); + + //create gpu shader + + char* vertex_shader[] = { + "#version 330 core\n", + "in vec2 position;\n", + "in vec2 texcoord;\n", + "out vec2 Texcoord;\n", + "void main() {\n", + " gl_Position = vec4(position, 0.0, 1.0);\n", + " Texcoord = texcoord;\n", + "}\n"}; + + char* fragment_shader[] = { + "#version 330 core\n", + "in vec2 Texcoord;\n", + "out vec4 FragColor;\n", + "uniform sampler2D tex;\n", + "void main() \n{", + " FragColor = texture(tex, Texcoord);\n", + "}\n" + }; + + + GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShaderID, 8, (const GLchar**)vertex_shader, NULL); + glCompileShader(vertexShaderID); + + int success; + char infoLog[512]; + glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &success); + if (success != GL_TRUE) { + glGetShaderInfoLog(vertexShaderID, 512, NULL, infoLog); + *(strchr(infoLog, '\n')) = ' '; //removes the newline opengl shoves in + printf("VS failure: %s\n", infoLog); + exit(-1); + } + + GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShaderID, 7, (const GLchar**)fragment_shader, NULL); + glCompileShader(fragmentShaderID); + + glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &success); + if (success != GL_TRUE) { + glGetShaderInfoLog(fragmentShaderID, 512, NULL, infoLog); + *(strchr(infoLog, '\n')) = ' '; //removes the newline opengl shoves in + printf("FS failure: %s\n", infoLog); + exit(-1); + } + + + gpu_program = glCreateProgram(); + glAttachShader(gpu_program, vertexShaderID); + glAttachShader(gpu_program, fragmentShaderID); + glLinkProgram(gpu_program); + + + glViewport(0,0, SCREEN_WIDTH, SCREEN_HEIGHT); + + glGenTextures(1, &gpu_texture); + glBindTexture(GL_TEXTURE_2D, gpu_texture); + + glGenVertexArrays(1, &gpu_vao); + glBindVertexArray(gpu_vao); + + glGenBuffers(1, &gpu_vbo); + glBindBuffer(GL_ARRAY_BUFFER, gpu_vbo); + + glGenBuffers(1, &gpu_ebo); + + GLint posAttrib = glGetAttribLocation(gpu_program, "position"); + glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0); + glEnableVertexAttribArray(posAttrib); + + GLint texAttrib = glGetAttribLocation(gpu_program, "texcoord"); + glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), (void*)(2*sizeof(float))); //here + glEnableVertexAttribArray(texAttrib); + + glClearColor(0.f, 0.f, 0.f, 1.0f); + SDL_GL_SetSwapInterval(0); } void GPU_receive(u64 data) { - // while (comet.gpu.is_drawing) { - // sched_yield(); - // } - - gpu.framebuf_addr = data; - memcpy(gpu.frame, (void*)(comet.mmu.memory + gpu.framebuf_addr), SCREEN_WIDTH*SCREEN_HEIGHT*3); - memset(gpu.frame, 0xEF, 100); + gpu_framebuf = data; + gpu_is_drawing = true; - gpu.is_drawing = true; + // (running on the CPU thread) force the GPU thread to run + sched_yield(); } -const float gpu_surface_vertices[16] = { - -1.0f, 1.0f, 0.0f, 0.0f, - 1.0f, 1.0f, 1.0f, 0.0f, - -1.0f, -1.0f, 0.0f, 1.0f, - 1.0f, -1.0f, 1.0f, 1.0f -}; -const int gpu_surface_elements[6] = { - 0, 1, 2, - 1, 3, 2 -}; -void GPU_draw() { +void gpu_draw() { - int screen_buff_word; - float dot_width = 1; //(float)SCREEN_WIDTH / (float)(80 * 8); - float dot_height = 1; //(float)SCREEN_HEIGHT / (float)(50 * 16); + int screen_buff_word; + float dot_width = 1; //(float)SCREEN_WIDTH / (float)(80 * 8); + float dot_height = 1; //(float)SCREEN_HEIGHT / (float)(50 * 16); - //stream texture data to gpu + //stream texture data to gpu - /* - 0--1 - | /| - |/ | - 2--3 - */ + float vertices[16] = { + -1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 0.0f, + -1.0f, -1.0f, 0.0f, 1.0f, + 1.0f, -1.0f, 1.0f, 1.0f + }; + int elements[6] = { + 0, 1, 2, + 1, 3, 2 + }; - SDL_GL_SwapWindow(gpu.window); - glClear(GL_COLOR_BUFFER_BIT); + /* + 0--1 + | /| + |/ | + 2--3 + */ - glUseProgram(gpu_program); + SDL_GL_SwapWindow(gpu_window); + glClear(GL_COLOR_BUFFER_BIT); - glBindTexture(GL_TEXTURE_2D, gpu_texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, SCREEN_WIDTH, SCREEN_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, gpu.frame); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glUseProgram(gpu_program); + glBindTexture(GL_TEXTURE_2D, gpu_texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, SCREEN_WIDTH, SCREEN_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, ((u8*)comet.mmu.memory + gpu_framebuf)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glBindVertexArray(gpu_vao); - glBindBuffer(GL_ARRAY_BUFFER, gpu_vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(gpu_surface_vertices), gpu_surface_vertices, GL_DYNAMIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gpu_ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(gpu_surface_elements), gpu_surface_elements, GL_DYNAMIC_DRAW); - - glDrawElements(GL_TRIANGLES, sizeof(gpu_surface_elements)/sizeof(gpu_surface_elements[0]), GL_UNSIGNED_INT, 0); + glBindVertexArray(gpu_vao); + glBindBuffer(GL_ARRAY_BUFFER, gpu_vbo); + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), vertices, GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gpu_ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(int), elements, GL_DYNAMIC_DRAW); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + + return; +} - return; +void gpu_init() { + SDL_Init( SDL_INIT_VIDEO ); + gpu_window = SDL_CreateWindow("comet", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL); + gpu_renderer = SDL_CreateRenderer(gpu_window, -1, SDL_RENDERER_ACCELERATED); + SDL_Surface* icon = IMG_Load("src/img/comet_icon.bmp"); + SDL_SetWindowIcon(gpu_window, icon); + gl_init(); } \ No newline at end of file diff --git a/src/gpu/gpu.h b/src/gpu/gpu.h index 572417e..63cad63 100755 --- a/src/gpu/gpu.h +++ b/src/gpu/gpu.h @@ -2,7 +2,6 @@ #define GPU_H #include "../orbit.h" -#include #ifdef _WIN32 #define SDL_MAIN_HANDLED @@ -14,28 +13,20 @@ #include #include -#define SCREEN_WIDTH 800 -#define SCREEN_HEIGHT 600 +extern bool gpu_is_drawing; +extern u64 gpu_framebuf; -typedef struct { - u8 r; - u8 g; - u8 b; -} pixel; +typedef union { + u32 colour; + struct { + u8 b; + u8 g; + u8 r; + }; +} RGB; -typedef struct GPU_s { - SDL_Window* window; - SDL_Renderer* renderer; - SDL_GLContext* gl_ctx; +void *gpu_thread(void* argvp); - u64 framebuf_addr; - pixel* frame; - bool is_drawing; -} GPU; - -void *GPU_thread(void* argvp); - -void gl_init(); -void init_GPU(); -void GPU_draw(); +void gpu_init(); +void gpu_draw(); void GPU_receive(u64 data); \ No newline at end of file diff --git a/test/displaytest.aphel b/test/displaytest.aphel index 9c3cd67..f4f752e 100755 --- a/test/displaytest.aphel +++ b/test/displaytest.aphel @@ -5,16 +5,16 @@ include "test/display.aphel" align 4 main: - li ra, 10 + li ra, 0 call rk, display.update - li ra, display.framebuffer - lw ra, ra + .loop: + + call rk, display.update - .loop: add rz, rz, rz sub rz, rz, rz umul rz, rz, rz