Merge branch 'xbox' of github.com:espes/xqemu into xbox

This commit is contained in:
espes 2015-08-11 15:04:13 -07:00
commit 85484e52cf
7 changed files with 234 additions and 189 deletions

View File

@ -2,7 +2,7 @@ obj-y += xbox.o chihiro.o
obj-y += xbox_pci.o acpi_xbox.o
obj-y += amd_smbus.o smbus_xbox_smc.o smbus_cx25871.o smbus_adm1032.o
obj-y += nvnet.o
obj-y += nv2a.o nv2a_vsh.o nv2a_psh.o nv2a_shaders.o
obj-y += nv2a.o nv2a_vsh.o nv2a_psh.o nv2a_shaders.o nv2a_debug.o
obj-y += swizzle.o g-lru-cache.o
obj-y += mcpx_apu.o mcpx_aci.o
obj-y += lpc47m157.o

View File

@ -34,87 +34,10 @@
#include "hw/xbox/swizzle.h"
#include "hw/xbox/u_format_r11g11b10f.h"
#include "hw/xbox/nv2a_shaders.h"
#include "hw/xbox/nv2a_debug.h"
#include "hw/xbox/nv2a.h"
// #define DEBUG_NV2A
#ifdef DEBUG_NV2A
# define NV2A_DPRINTF(format, ...) printf("nv2a: " format, ## __VA_ARGS__)
#else
# define NV2A_DPRINTF(format, ...) do { } while (0)
#endif
// #define DEBUG_NV2A_GL
#ifdef DEBUG_NV2A_GL
static void gl_debug_message(bool cc, const char *fmt, ...)
{
size_t n;
char buffer[1024];
va_list ap;
va_start(ap, fmt);
n = vsnprintf(buffer, sizeof(buffer), fmt, ap);
assert(n <= sizeof(buffer));
va_end(ap);
glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER,
0, GL_DEBUG_SEVERITY_NOTIFICATION, n, buffer);
if (cc) {
fwrite(buffer, sizeof(char), n, stdout);
fputc('\n', stdout);
}
}
static void gl_debug_group_begin(const char *fmt, ...)
{
size_t n;
char buffer[1024];
va_list ap;
va_start(ap, fmt);
n = vsnprintf(buffer, sizeof(buffer), fmt, ap);
assert(n <= sizeof(buffer));
va_end(ap);
/* Check for errors before entering group */
assert(glGetError() == GL_NO_ERROR);
glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, n, buffer);
}
static void gl_debug_group_end(void)
{
/* Check for errors when leaving group */
assert(glGetError() == GL_NO_ERROR);
glPopDebugGroup();
}
static void gl_debug_label(GLenum target, GLuint name, const char *fmt, ...)
{
size_t n;
char buffer[1024];
va_list ap;
va_start(ap, fmt);
n = vsnprintf(buffer, sizeof(buffer), fmt, ap);
assert(n <= sizeof(buffer));
va_end(ap);
glObjectLabel(target, name, n, buffer);
}
# define NV2A_GL_DPRINTF(cc, format, ...) \
gl_debug_message(cc, "nv2a: " format, ## __VA_ARGS__)
# define NV2A_GL_DGROUP_BEGIN(format, ...) \
gl_debug_group_begin("nv2a: " format, ## __VA_ARGS__)
# define NV2A_GL_DGROUP_END() \
gl_debug_group_end()
# define NV2A_GL_DLABEL(target, name, format, ...) \
gl_debug_label(target, name, "nv2a: { " format " }", ## __VA_ARGS__)
#else
# define NV2A_GL_DPRINTF(cc, format, ...) do { } while (0)
# define NV2A_GL_DGROUP_BEGIN(format, ...) do { } while (0)
# define NV2A_GL_DGROUP_END() do { } while (0)
# define NV2A_GL_DLABEL(target, name, format, ...) do { } while (0)
#endif
#define USE_TEXTURE_CACHE
#define NV_NUM_BLOCKS 21
@ -1269,6 +1192,24 @@ static const SurfaceColorFormatInfo kelvin_surface_color_format_map[] = {
{4, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV},
};
#define NV2A_VERTEX_ATTR_POSITION 0
#define NV2A_VERTEX_ATTR_WEIGHT 1
#define NV2A_VERTEX_ATTR_NORMAL 2
#define NV2A_VERTEX_ATTR_DIFFUSE 3
#define NV2A_VERTEX_ATTR_SPECULAR 4
#define NV2A_VERTEX_ATTR_FOG 5
#define NV2A_VERTEX_ATTR_POINT_SIZE 6
#define NV2A_VERTEX_ATTR_BACK_DIFFUSE 7
#define NV2A_VERTEX_ATTR_BACK_SPECULAR 8
#define NV2A_VERTEX_ATTR_TEXTURE0 9
#define NV2A_VERTEX_ATTR_TEXTURE1 10
#define NV2A_VERTEX_ATTR_TEXTURE2 11
#define NV2A_VERTEX_ATTR_TEXTURE3 12
#define NV2A_VERTEX_ATTR_RESERVED1 13
#define NV2A_VERTEX_ATTR_RESERVED2 14
#define NV2A_VERTEX_ATTR_RESERVED3 15
#define NV2A_CRYSTAL_FREQ 13500000
#define NV2A_NUM_CHANNELS 32
#define NV2A_NUM_SUBCHANNELS 8
@ -4864,7 +4805,7 @@ static void pgraph_method(NV2AState *d,
pg->draw_arrays_max_count = MAX(pg->draw_arrays_max_count, start + count);
assert(pg->draw_arrays_length < sizeof(pg->gl_draw_arrays_start) / sizeof(pg->gl_draw_arrays_start[0]));
assert(pg->draw_arrays_length < ARRAYSIZE(pg->gl_draw_arrays_start));
/* Attempt to connect primitives */
if (pg->draw_arrays_length > 0) {

View File

@ -22,4 +22,4 @@
void nv2a_init(PCIBus *bus, int devfn, MemoryRegion *ram);
#endif
#endif

81
hw/xbox/nv2a_debug.c Normal file
View File

@ -0,0 +1,81 @@
/*
* QEMU Geforce NV2A debug helpers
*
* Copyright (c) 2015 Jannik Vogel
* Copyright (c) 2012 espes
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 or
* (at your option) version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "hw/xbox/nv2a_debug.h"
#ifdef DEBUG_NV2A_GL
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
void gl_debug_message(bool cc, const char *fmt, ...)
{
size_t n;
char buffer[1024];
va_list ap;
va_start(ap, fmt);
n = vsnprintf(buffer, sizeof(buffer), fmt, ap);
assert(n <= sizeof(buffer));
va_end(ap);
glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER,
0, GL_DEBUG_SEVERITY_NOTIFICATION, n, buffer);
if (cc) {
fwrite(buffer, sizeof(char), n, stdout);
fputc('\n', stdout);
}
}
void gl_debug_group_begin(const char *fmt, ...)
{
size_t n;
char buffer[1024];
va_list ap;
va_start(ap, fmt);
n = vsnprintf(buffer, sizeof(buffer), fmt, ap);
assert(n <= sizeof(buffer));
va_end(ap);
/* Check for errors before entering group */
assert(glGetError() == GL_NO_ERROR);
glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, n, buffer);
}
void gl_debug_group_end(void)
{
/* Check for errors when leaving group */
assert(glGetError() == GL_NO_ERROR);
glPopDebugGroup();
}
void gl_debug_label(GLenum target, GLuint name, const char *fmt, ...)
{
size_t n;
char buffer[1024];
va_list ap;
va_start(ap, fmt);
n = vsnprintf(buffer, sizeof(buffer), fmt, ap);
assert(n <= sizeof(buffer));
va_end(ap);
glObjectLabel(target, name, n, buffer);
}
#endif

58
hw/xbox/nv2a_debug.h Normal file
View File

@ -0,0 +1,58 @@
/*
* QEMU Geforce NV2A debug helpers
*
* Copyright (c) 2015 Jannik Vogel
* Copyright (c) 2012 espes
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 or
* (at your option) version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HW_NV2A_DEBUG_H
#define HW_NV2A_DEBUG_H
// #define DEBUG_NV2A
#ifdef DEBUG_NV2A
# define NV2A_DPRINTF(format, ...) printf("nv2a: " format, ## __VA_ARGS__)
#else
# define NV2A_DPRINTF(format, ...) do { } while (0)
#endif
// #define DEBUG_NV2A_GL
#ifdef DEBUG_NV2A_GL
#include <stdbool.h>
#include "gl/gloffscreen.h"
void gl_debug_message(bool cc, const char *fmt, ...);
void gl_debug_group_begin(const char *fmt, ...);
void gl_debug_group_end(void);
void gl_debug_label(GLenum target, GLuint name, const char *fmt, ...);
# define NV2A_GL_DPRINTF(cc, format, ...) \
gl_debug_message(cc, "nv2a: " format, ## __VA_ARGS__)
# define NV2A_GL_DGROUP_BEGIN(format, ...) \
gl_debug_group_begin("nv2a: " format, ## __VA_ARGS__)
# define NV2A_GL_DGROUP_END() \
gl_debug_group_end()
# define NV2A_GL_DLABEL(target, name, format, ...) \
gl_debug_label(target, name, "nv2a: { " format " }", ## __VA_ARGS__)
#else
# define NV2A_GL_DPRINTF(cc, format, ...) do { } while (0)
# define NV2A_GL_DGROUP_BEGIN(format, ...) do { } while (0)
# define NV2A_GL_DGROUP_END() do { } while (0)
# define NV2A_GL_DLABEL(target, name, format, ...) do { } while (0)
#endif
#endif

View File

@ -19,16 +19,10 @@
*/
#include "qemu-common.h"
#include "hw/xbox/nv2a_debug.h"
#include "hw/xbox/nv2a_shaders_common.h"
#include "hw/xbox/nv2a_shaders.h"
// #define NV2A_DEBUG
#ifdef NV2A_DEBUG
# define NV2A_DPRINTF(format, ...) printf("nv2a: " format, ## __VA_ARGS__)
#else
# define NV2A_DPRINTF(format, ...) do { } while (0)
#endif
static void generate_geometry_shader_pass_vertex(QString* s, const char* v)
{
qstring_append_fmt(s, " gl_Position = gl_in[%s].gl_Position;\n", v);
@ -90,24 +84,34 @@ static QString* generate_fixed_function(const ShaderState state,
qstring_append(s,
"#version 330\n"
"\n"
"in vec4 position;\n"
"in vec4 weight;\n"
"in vec3 normal;\n"
"in vec4 diffuse;\n"
"in vec4 specular;\n"
"in float fogCoord;\n"
"in vec4 backDiffuse;\n"
"in vec4 backSpecular;\n"
"in vec4 texture0;\n"
"in vec4 texture1;\n"
"in vec4 texture2;\n"
"in vec4 texture3;\n"
"#define position v0\n"
"#define weight v1\n"
"#define normal v2.xyz\n"
"#define diffuse v3\n"
"#define specular v4\n"
"#define fogCoord v5.x\n"
"#define pointSize v6\n"
"#define backDiffuse v7\n"
"#define backSpecular v8\n"
"#define texture0 v9\n"
"#define texture1 v10\n"
"#define texture2 v11\n"
"#define texture3 v12\n"
"#define reserved1 v13\n"
"#define reserved2 v14\n"
"#define reserved3 v15\n"
"\n");
qstring_append(s, STRUCT_VERTEX_DATA);
for(i = 0; i < 16; i++) {
qstring_append_fmt(s, "in vec4 v%d;\n", i);
}
qstring_append(s, "\n"
STRUCT_VERTEX_DATA);
qstring_append_fmt(s, "noperspective out VertexData %c_vtx;\n", out_prefix);
qstring_append_fmt(s, "#define vtx %c_vtx", out_prefix);
qstring_append(s,
"\n"
/* FIXME: Add these uniforms using code when they are used */
@ -280,10 +284,42 @@ static QString* generate_fixed_function(const ShaderState state,
return s;
}
static GLuint create_gl_shader(GLenum gl_shader_type,
const char *code,
const char *name)
{
GLint compiled = 0;
NV2A_GL_DGROUP_BEGIN("Creating new %s", name);
GLuint shader = glCreateShader(gl_shader_type);
glShaderSource(shader, 1, &code, 0);
glCompileShader(shader);
/* Check it compiled */
compiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLchar* log;
GLint log_length;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
log = g_malloc(log_length * sizeof(GLchar));
glGetShaderInfoLog(shader, log_length, NULL, log);
fprintf(stderr, "nv2a: %s compilation failed: %s\n", name, log);
g_free(log);
NV2A_GL_DGROUP_END();
abort();
}
NV2A_GL_DGROUP_END();
return shader;
}
ShaderBinding* generate_shaders(const ShaderState state)
{
int i, j;
GLint compiled = 0;
bool with_geom = state.primitive_mode == PRIM_TYPE_QUADS;
char vtx_prefix = with_geom ? 'v' : 'g';
@ -308,56 +344,24 @@ ShaderBinding* generate_shaders(const ShaderState state)
if (vertex_shader_code) {
const char* vertex_shader_code_str = qstring_get_str(vertex_shader_code);
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
GLuint vertex_shader = create_gl_shader(GL_VERTEX_SHADER,
vertex_shader_code_str,
"vertex shader");
glAttachShader(program, vertex_shader);
glShaderSource(vertex_shader, 1, &vertex_shader_code_str, 0);
glCompileShader(vertex_shader);
NV2A_DPRINTF("bind new vertex shader, code:\n%s\n", vertex_shader_code_str);
/* Check it compiled */
compiled = 0;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLchar log[1024];
glGetShaderInfoLog(vertex_shader, 1024, NULL, log);
fprintf(stderr, "nv2a: vertex shader compilation failed: %s\n", log);
abort();
}
QDECREF(vertex_shader_code);
}
if (state.fixed_function) {
/* bind fixed function vertex attributes */
glBindAttribLocation(program, NV2A_VERTEX_ATTR_POSITION, "position");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_WEIGHT, "weight");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_DIFFUSE, "diffuse");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_SPECULAR, "specular");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_FOG, "fog");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_BACK_DIFFUSE, "backDiffuse");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_BACK_SPECULAR, "backSpecular");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE0, "texture0");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE1, "texture1");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE2, "texture2");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE3, "texture3");
} else if (state.vertex_program) {
/* Bind attributes for transform program*/
char tmp[8];
for(i = 0; i < 16; i++) {
snprintf(tmp, sizeof(tmp), "v%d", i);
glBindAttribLocation(program, i, tmp);
}
} else {
assert(false);
/* Bind attributes for vertices */
char tmp[8];
for(i = 0; i < 16; i++) {
snprintf(tmp, sizeof(tmp), "v%d", i);
glBindAttribLocation(program, i, tmp);
}
/* generate a fragment shader from register combiners */
GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glAttachShader(program, fragment_shader);
QString *fragment_shader_code = psh_translate(state.combiner_control,
state.shader_stage_program,
@ -374,46 +378,24 @@ ShaderBinding* generate_shaders(const ShaderState state)
const char *fragment_shader_code_str = qstring_get_str(fragment_shader_code);
NV2A_DPRINTF("bind new fragment shader, code:\n%s\n", fragment_shader_code_str);
glShaderSource(fragment_shader, 1, &fragment_shader_code_str, 0);
glCompileShader(fragment_shader);
/* Check it compiled */
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLchar log[1024];
glGetShaderInfoLog(fragment_shader, 1024, NULL, log);
fprintf(stderr, "nv2a: fragment shader compilation failed: %s\n", log);
abort();
}
GLuint fragment_shader = create_gl_shader(GL_FRAGMENT_SHADER,
fragment_shader_code_str,
"fragment shader");
glAttachShader(program, fragment_shader);
QDECREF(fragment_shader_code);
if (with_geom) {
GLuint geometry_shader = glCreateShader(GL_GEOMETRY_SHADER);
glAttachShader(program, geometry_shader);
QString* geometry_shader_code =
generate_geometry_shader(state.primitive_mode);
const char* geometry_shader_code_str =
qstring_get_str(geometry_shader_code);
NV2A_DPRINTF("bind geometry shader, code:\n%s\n", geometry_shader_code_str);
glShaderSource(geometry_shader, 1, &geometry_shader_code_str, 0);
glCompileShader(geometry_shader);
/* Check it compiled */
compiled = 0;
glGetShaderiv(geometry_shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLchar log[2048];
glGetShaderInfoLog(geometry_shader, 2048, NULL, log);
fprintf(stderr, "nv2a: geometry shader compilation failed: %s\n", log);
abort();
}
GLuint geometry_shader = create_gl_shader(GL_GEOMETRY_SHADER,
geometry_shader_code_str,
"geometry shader");
glAttachShader(program, geometry_shader);
QDECREF(geometry_shader_code);
}

View File

@ -27,23 +27,6 @@
#include "nv2a_vsh.h"
#include "nv2a_psh.h"
#define NV2A_VERTEX_ATTR_POSITION 0
#define NV2A_VERTEX_ATTR_WEIGHT 1
#define NV2A_VERTEX_ATTR_NORMAL 2
#define NV2A_VERTEX_ATTR_DIFFUSE 3
#define NV2A_VERTEX_ATTR_SPECULAR 4
#define NV2A_VERTEX_ATTR_FOG 5
#define NV2A_VERTEX_ATTR_POINT_SIZE 6
#define NV2A_VERTEX_ATTR_BACK_DIFFUSE 7
#define NV2A_VERTEX_ATTR_BACK_SPECULAR 8
#define NV2A_VERTEX_ATTR_TEXTURE0 9
#define NV2A_VERTEX_ATTR_TEXTURE1 10
#define NV2A_VERTEX_ATTR_TEXTURE2 11
#define NV2A_VERTEX_ATTR_TEXTURE3 12
#define NV2A_VERTEX_ATTR_RESERVED1 13
#define NV2A_VERTEX_ATTR_RESERVED2 14
#define NV2A_VERTEX_ATTR_RESERVED3 15
#define NV2A_MAX_TRANSFORM_PROGRAM_LENGTH 136
#define NV2A_VERTEXSHADER_CONSTANTS 192