From 17ad59094f6b7ca80daf887d38c2c216ab2894dc Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Mon, 5 Jul 2021 23:16:00 +0300 Subject: [PATCH 1/2] win_opengl: Add logging --- src/win/win_opengl.c | 33 +++++++++++++++++++--------- src/win/win_opengl_glslp.c | 44 +++++++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/src/win/win_opengl.c b/src/win/win_opengl.c index 387c24c67..9d44fc47e 100644 --- a/src/win/win_opengl.c +++ b/src/win/win_opengl.c @@ -451,14 +451,10 @@ static void opengl_fail() _endthread(); } -/* static void __stdcall opengl_debugmsg_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) { - OutputDebugStringA("OpenGL: "); - OutputDebugStringA(message); - OutputDebugStringA("\n"); + pclog("OpenGL: %s\n", message); } -*/ /** * @brief Main OpenGL thread proc. @@ -478,13 +474,19 @@ static void opengl_main(void* param) SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); - //SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG | SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); + + if (GLAD_GL_ARB_debug_output) + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG | SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); + else + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); window = SDL_CreateWindow("86Box OpenGL Renderer", 0, 0, resize_info.width, resize_info.height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS); if (window == NULL) + { + pclog("OpenGL: failed to create OpenGL window.\n"); opengl_fail(); + } /* Keep track of certain parameters, only changed in this thread to avoid race conditions */ int fullscreen = resize_info.fullscreen, video_width = INIT_WIDTH, video_height = INIT_HEIGHT, @@ -495,7 +497,10 @@ static void opengl_main(void* param) SDL_GetWindowWMInfo(window, &wmi); if (wmi.subsystem != SDL_SYSWM_WINDOWS) + { + pclog("OpenGL: subsystem is not SDL_SYSWM_WINDOWS.\n"); opengl_fail(); + } window_hwnd = wmi.info.win.window; @@ -507,29 +512,37 @@ static void opengl_main(void* param) SDL_GLContext context = SDL_GL_CreateContext(window); if (context == NULL) + { + pclog("OpenGL: failed to create OpenGL context.\n"); opengl_fail(); + } SDL_GL_SetSwapInterval(options.vsync); if (!gladLoadGLLoader(SDL_GL_GetProcAddress)) { + pclog("OpenGL: failed to set OpenGL loader.\n"); SDL_GL_DeleteContext(context); opengl_fail(); } - - /* + if (GLAD_GL_ARB_debug_output) { glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_PERFORMANCE_ARB, GL_DONT_CARE, 0, 0, GL_FALSE); glDebugMessageCallbackARB(opengl_debugmsg_callback, NULL); } - */ + + pclog("OpenGL vendor: %s\n", glGetString(GL_VENDOR)); + pclog("OpenGL renderer: %s\n", glGetString(GL_RENDERER)); + pclog("OpenGL version: %s\n", glGetString(GL_VERSION)); + pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); gl_identifiers gl = { 0 }; if (!initialize_glcontext(&gl)) { + pclog("OpenGL: failed to initialize.\n"); finalize_glcontext(&gl); SDL_GL_DeleteContext(context); opengl_fail(); diff --git a/src/win/win_opengl_glslp.c b/src/win/win_opengl_glslp.c index fc1d296e5..0dff03be9 100644 --- a/src/win/win_opengl_glslp.c +++ b/src/win/win_opengl_glslp.c @@ -63,6 +63,16 @@ void main() {\n\ color = texture(texsampler, tex);\n\ }\n"; +/** + * @brief OpenGL shader program build targets +*/ +typedef enum +{ + OPENGL_BUILD_TARGET_VERTEX, + OPENGL_BUILD_TARGET_FRAGMENT, + OPENGL_BUILD_TARGET_LINK +} opengl_build_target_t; + /** * @brief Reads a whole file into a null terminated string. * @param Path Path to the file relative to executable path. @@ -98,11 +108,11 @@ static char* read_file_to_string(const char* path) return NULL; } -static int check_status(GLuint id, int is_shader) +static int check_status(GLuint id, opengl_build_target_t build_target, const char* shader_path) { GLint status = GL_FALSE; - if (is_shader) + if (build_target != OPENGL_BUILD_TARGET_LINK) glGetShaderiv(id, GL_COMPILE_STATUS, &status); else glGetProgramiv(id, GL_LINK_STATUS, &status); @@ -111,19 +121,37 @@ static int check_status(GLuint id, int is_shader) { int info_log_length; - if (is_shader) + if (build_target != OPENGL_BUILD_TARGET_LINK) glGetShaderiv(id, GL_INFO_LOG_LENGTH, &info_log_length); else glGetProgramiv(id, GL_INFO_LOG_LENGTH, &info_log_length); GLchar* info_log_text = (GLchar*)malloc(sizeof(GLchar) * info_log_length); - if (is_shader) + if (build_target != OPENGL_BUILD_TARGET_LINK) glGetShaderInfoLog(id, info_log_length, NULL, info_log_text); else glGetProgramInfoLog(id, info_log_length, NULL, info_log_text); - /* TODO: error logging */ + const char* reason = NULL; + + switch (build_target) + { + case OPENGL_BUILD_TARGET_VERTEX: + reason = "compiling vertex shader"; + break; + case OPENGL_BUILD_TARGET_FRAGMENT: + reason = "compiling fragment shader"; + break; + case OPENGL_BUILD_TARGET_LINK: + reason = "linking shader program"; + break; + } + + /* Shader compilation log can be lengthy, mark begin and end */ + const char* line = "--------------------"; + + pclog("OpenGL: Error when %s in %s:\n%sBEGIN%s\n%s\n%s END %s\n", reason, shader_path, line, line, info_log_text, line, line); free(info_log_text); @@ -153,11 +181,11 @@ GLuint load_custom_shaders(const char* path) glShaderSource(vertex_id, 2, vertex_sources, NULL); glCompileShader(vertex_id); - success *= check_status(vertex_id, 1); + success *= check_status(vertex_id, OPENGL_BUILD_TARGET_VERTEX, path); glShaderSource(fragment_id, 2, fragment_sources, NULL); glCompileShader(fragment_id); - success *= check_status(fragment_id, 1); + success *= check_status(fragment_id, OPENGL_BUILD_TARGET_FRAGMENT, path); free(shader); @@ -170,7 +198,7 @@ GLuint load_custom_shaders(const char* path) glAttachShader(prog_id, vertex_id); glAttachShader(prog_id, fragment_id); glLinkProgram(prog_id); - check_status(prog_id, 0); + check_status(prog_id, OPENGL_BUILD_TARGET_LINK, path); glDetachShader(prog_id, vertex_id); glDetachShader(prog_id, fragment_id); From 6fdb91d4726a0890cd591e2ee733e520f1f81b72 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 6 Jul 2021 18:32:41 +0200 Subject: [PATCH 2/2] Implemented the Command/ROP register in the Dword/Long side of the write routing. Fixes main rendering under Win9x using the DirectX/Win98 TGUI9440/96xx drivers. Implemented clipping in the SRC CPU flag of BitBLT in the TGUI9440/96xx, fixes more rendering problems. --- src/video/vid_tgui9440.c | 146 +++++++++++++++++++++++++++------------ 1 file changed, 102 insertions(+), 44 deletions(-) diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 169ac8582..556bb1f22 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -123,7 +123,7 @@ typedef struct tgui_t uint16_t ger22; int16_t err, top, left, bottom, right; - int x, y; + int x, y, dx, dy; uint32_t src, dst, src_old, dst_old; int pat_x, pat_y; int use_src; @@ -650,9 +650,10 @@ void tgui_recalctimings(svga_t *svga) case 8: svga->render = svga_render_8bpp_highres; if (tgui->type >= TGUI_9680) { - if (svga->dispend == 512) { + if (svga->dispend == 512) svga->hdisp = 1280; - } + else if (svga->dispend == 1200) + svga->hdisp = 1600; } break; case 15: @@ -1222,9 +1223,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } if (count == -1) - { tgui->accel.x = tgui->accel.y = 0; - } if (tgui->accel.flags & TGUI_SOLIDFILL) { for (y = 0; y < 8; y++) @@ -1274,7 +1273,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) pattern_data = tgui->accel.pattern_32; } } - + switch (tgui->accel.command) { case TGUI_BITBLT: @@ -1287,6 +1286,22 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.pat_x = tgui->accel.dst_x; tgui->accel.pat_y = tgui->accel.dst_y; + + tgui->accel.dx = tgui->accel.dst_x & 0xfff; + tgui->accel.dy = tgui->accel.dst_y & 0xfff; + + tgui->accel.left = tgui->accel.src_x_clip & 0xfff; + tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; + tgui->accel.top = tgui->accel.src_y_clip & 0xfff; + tgui->accel.bottom = tgui->accel.dst_y_clip & 0xfff; + + if (tgui->accel.bpp == 1) { + tgui->accel.left >>= 1; + tgui->accel.right >>= 1; + } else if (tgui->accel.bpp == 3) { + tgui->accel.left >>= 2; + tgui->accel.right >>= 2; + } } switch (tgui->accel.flags & (TGUI_SRCMONO|TGUI_SRCDISP)) @@ -1301,39 +1316,43 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) count >>= 3; while (count) { - if (tgui->accel.bpp == 0) { - src_dat = cpu_dat >> 24; - cpu_dat <<= 8; - count--; - } else if (tgui->accel.bpp == 1) { - src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00); - cpu_dat <<= 16; - count -= 2; - } else { - src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0x0000ff00) | ((cpu_dat << 8) & 0x00ff0000); - cpu_dat <<= 16; - count -= 4; - } - - READ(tgui->accel.dst, dst_dat); + if ((tgui->type == TGUI_9440) || (tgui->type >= TGUI_9680 && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && + tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) { + if (tgui->accel.bpp == 0) { + src_dat = cpu_dat >> 24; + cpu_dat <<= 8; + } else if (tgui->accel.bpp == 1) { + src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00); + cpu_dat <<= 16; + count--; + } else { + src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0x0000ff00) | ((cpu_dat << 8) & 0x00ff0000); + cpu_dat <<= 16; + count -= 3; + } + + READ(tgui->accel.dst, dst_dat); - pat_dat = pattern_data[((tgui->accel.pat_y & 7)*8) + (tgui->accel.pat_x & 7)]; + pat_dat = pattern_data[((tgui->accel.pat_y & 7)*8) + (tgui->accel.pat_x & 7)]; + + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; + + if ((((tgui->accel.flags & (TGUI_PATMONO|TGUI_TRANSENA)) == (TGUI_TRANSENA|TGUI_PATMONO)) && (pat_dat != trans_col)) || !(tgui->accel.flags & TGUI_PATMONO) || + ((tgui->accel.flags & (TGUI_PATMONO|TGUI_TRANSENA)) == TGUI_PATMONO)) { + MIX(); - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - - if ((((tgui->accel.flags & (TGUI_PATMONO|TGUI_TRANSENA)) == (TGUI_TRANSENA|TGUI_PATMONO)) && (pat_dat != trans_col)) || !(tgui->accel.flags & TGUI_PATMONO) || - ((tgui->accel.flags & (TGUI_PATMONO|TGUI_TRANSENA)) == TGUI_PATMONO)) { - MIX(); - - WRITE(tgui->accel.dst, out); + WRITE(tgui->accel.dst, out); + } } tgui->accel.src += xdir; tgui->accel.dst += xdir; tgui->accel.pat_x += xdir; + if (tgui->type >= TGUI_9680) + tgui->accel.dx += xdir; tgui->accel.x++; if (tgui->accel.x > tgui->accel.size_x) { @@ -1341,6 +1360,11 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.pat_x = tgui->accel.dst_x; tgui->accel.pat_y += ydir; + + if (tgui->type >= TGUI_9680) { + tgui->accel.dx = tgui->accel.dst_x & 0xfff; + tgui->accel.dy += ydir; + } tgui->accel.src_old += (ydir * tgui->accel.pitch); tgui->accel.dst_old += (ydir * tgui->accel.pitch); @@ -1358,6 +1382,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) if (tgui->accel.use_src) return; } + count--; } break; @@ -1425,12 +1450,12 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) READ(tgui->accel.dst, dst_dat); pat_dat = pattern_data[((tgui->accel.pat_y & 7)*8) + (tgui->accel.pat_x & 7)]; - + if (tgui->accel.bpp == 0) pat_dat &= 0xff; else if (tgui->accel.bpp == 1) pat_dat &= 0xffff; - + if (!(tgui->accel.flags & TGUI_TRANSENA) || (src_dat != trans_col)) { MIX(); @@ -1479,7 +1504,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) READ(tgui->accel.dst, dst_dat); pat_dat = pattern_data[((tgui->accel.pat_y & 7)*8) + (tgui->accel.pat_x & 7)]; - + if (tgui->accel.bpp == 0) pat_dat &= 0xff; else if (tgui->accel.bpp == 1) @@ -1545,7 +1570,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.right >>= 1; } else if (tgui->accel.bpp == 3) { tgui->accel.left >>= 2; - tgui->accel.right >>= 2; + tgui->accel.right >>= 2; } err = tgui->accel.size_x + tgui->accel.src_y; @@ -1867,19 +1892,31 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *p) static void tgui_accel_out_w(uint16_t addr, uint16_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; - tgui_accel_out(addr, val, tgui); - tgui_accel_out(addr + 1, val >> 8, tgui); + tgui_t *tgui = (tgui_t *)p; + tgui_accel_out(addr, val, tgui); + tgui_accel_out(addr + 1, val >> 8, tgui); } static void tgui_accel_out_l(uint16_t addr, uint32_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; + tgui_t *tgui = (tgui_t *)p; + + switch (addr) { + case 0x2124: /*Long version of Command and ROP together*/ + tgui->accel.command = val & 0xff; + tgui->accel.rop = val >> 24; + tgui->accel.use_src = (tgui->accel.rop & 0x33) ^ ((tgui->accel.rop >> 2) & 0x33); + tgui_accel_command(-1, 0, tgui); + break; + + default: tgui_accel_out(addr, val, tgui); tgui_accel_out(addr + 1, val >> 8, tgui); tgui_accel_out(addr + 2, val >> 16, tgui); tgui_accel_out(addr + 3, val >> 24, tgui); + break; + } } static uint8_t @@ -2318,7 +2355,8 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p) static void tgui_accel_write_w(uint32_t addr, uint16_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; + tgui_t *tgui = (tgui_t *)p; + tgui_accel_write(addr, val, tgui); tgui_accel_write(addr + 1, val >> 8, tgui); } @@ -2326,9 +2364,29 @@ tgui_accel_write_w(uint32_t addr, uint16_t val, void *p) static void tgui_accel_write_l(uint32_t addr, uint32_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; - tgui_accel_write_w(addr, val, tgui); - tgui_accel_write_w(addr + 2, val >> 16, tgui); + tgui_t *tgui = (tgui_t *)p; + svga_t *svga = &tgui->svga; + + switch (addr & 0xff) { + case 0x24: /*Long version of Command and ROP together*/ + if ((svga->crtc[0x36] & 0x03) == 0x02) { + if ((addr & ~0xff) != 0xbff00) + return; + } else if ((svga->crtc[0x36] & 0x03) == 0x01) { + if ((addr & ~0xff) != 0xb7f00) + return; + } + tgui->accel.command = val & 0xff; + tgui->accel.rop = val >> 24; + tgui->accel.use_src = ((val >> 24) & 0x33) ^ (((val >> 24) >> 2) & 0x33); + tgui_accel_command(-1, 0, tgui); + break; + + default: + tgui_accel_write_w(addr, val, tgui); + tgui_accel_write_w(addr + 2, val >> 16, tgui); + break; + } } static uint8_t