Merge pull request #1533 from 86Box/master

Bring the branch up to par with master.
This commit is contained in:
Miran Grča
2021-07-06 19:30:03 +02:00
committed by GitHub
3 changed files with 161 additions and 62 deletions

View File

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

View File

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

View File

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