NV2A : Copied over more OpenXbox stuff

This commit is contained in:
PatrickvL 2018-02-01 17:05:31 +01:00
parent 1bf01df4b7
commit 11b0e080be
4 changed files with 275 additions and 6 deletions

View File

@ -682,6 +682,8 @@ void EmuNV2A_Init()
d->pcrtc.start = 0; d->pcrtc.start = 0;
d->vram_size = (g_bIsChihiro || g_bIsDebug) ? CONTIGUOUS_MEMORY_CHIHIRO_SIZE : CONTIGUOUS_MEMORY_XBOX_SIZE;
d->pramdac.core_clock_coeff = 0x00011c01; /* 189MHz...? */ d->pramdac.core_clock_coeff = 0x00011c01; /* 189MHz...? */
d->pramdac.core_clock_freq = 189000000; d->pramdac.core_clock_freq = 189000000;
d->pramdac.memory_clock_coeff = 0; d->pramdac.memory_clock_coeff = 0;

View File

@ -6,11 +6,8 @@ DEVICE_READ32(PFB)
result = 3; // = NV_PFB_CFG0_PART_4 result = 3; // = NV_PFB_CFG0_PART_4
break; break;
case NV_PFB_CSTATUS: case NV_PFB_CSTATUS:
{ result = d->vram_size;
if (g_bIsChihiro || g_bIsDebug) { result = CONTIGUOUS_MEMORY_CHIHIRO_SIZE; break; } break;
result = CONTIGUOUS_MEMORY_XBOX_SIZE;
}
break;
case NV_PFB_WBC: case NV_PFB_WBC:
result = 0; // = !NV_PFB_WBC_FLUSH /* Flush not pending. */ result = 0; // = !NV_PFB_WBC_FLUSH /* Flush not pending. */
break; break;

View File

@ -1,3 +1,136 @@
static const GLenum pgraph_texture_min_filter_map[] = {
0,
GL_NEAREST,
GL_LINEAR,
GL_NEAREST_MIPMAP_NEAREST,
GL_LINEAR_MIPMAP_NEAREST,
GL_NEAREST_MIPMAP_LINEAR,
GL_LINEAR_MIPMAP_LINEAR,
GL_LINEAR, /* TODO: Convolution filter... */
};
static const GLenum pgraph_texture_mag_filter_map[] = {
0,
GL_NEAREST,
GL_LINEAR,
0,
GL_LINEAR /* TODO: Convolution filter... */
};
static const GLenum pgraph_texture_addr_map[] = {
0,
GL_REPEAT,
GL_MIRRORED_REPEAT,
GL_CLAMP_TO_EDGE,
GL_CLAMP_TO_BORDER,
// GL_CLAMP
};
static const GLenum pgraph_blend_factor_map[] = {
GL_ZERO,
GL_ONE,
GL_SRC_COLOR,
GL_ONE_MINUS_SRC_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA,
GL_DST_COLOR,
GL_ONE_MINUS_DST_COLOR,
GL_SRC_ALPHA_SATURATE,
0,
GL_CONSTANT_COLOR,
GL_ONE_MINUS_CONSTANT_COLOR,
GL_CONSTANT_ALPHA,
GL_ONE_MINUS_CONSTANT_ALPHA,
};
static const GLenum pgraph_blend_equation_map[] = {
GL_FUNC_SUBTRACT,
GL_FUNC_REVERSE_SUBTRACT,
GL_FUNC_ADD,
GL_MIN,
GL_MAX,
GL_FUNC_REVERSE_SUBTRACT,
GL_FUNC_ADD,
};
static const GLenum pgraph_blend_logicop_map[] = {
GL_CLEAR,
GL_AND,
GL_AND_REVERSE,
GL_COPY,
GL_AND_INVERTED,
GL_NOOP,
GL_XOR,
GL_OR,
GL_NOR,
GL_EQUIV,
GL_INVERT,
GL_OR_REVERSE,
GL_COPY_INVERTED,
GL_OR_INVERTED,
GL_NAND,
GL_SET,
};
static const GLenum pgraph_cull_face_map[] = {
0,
GL_FRONT,
GL_BACK,
GL_FRONT_AND_BACK
};
static const GLenum pgraph_depth_func_map[] = {
GL_NEVER,
GL_LESS,
GL_EQUAL,
GL_LEQUAL,
GL_GREATER,
GL_NOTEQUAL,
GL_GEQUAL,
GL_ALWAYS,
};
static const GLenum pgraph_stencil_func_map[] = {
GL_NEVER,
GL_LESS,
GL_EQUAL,
GL_LEQUAL,
GL_GREATER,
GL_NOTEQUAL,
GL_GEQUAL,
GL_ALWAYS,
};
static const GLenum pgraph_stencil_op_map[] = {
0,
GL_KEEP,
GL_ZERO,
GL_REPLACE,
GL_INCR,
GL_DECR,
GL_INVERT,
GL_INCR_WRAP,
GL_DECR_WRAP,
};
typedef struct ColorFormatInfo {
unsigned int bytes_per_pixel;
bool linear;
GLint gl_internal_format;
GLenum gl_format;
GLenum gl_type;
GLenum gl_swizzle_mask[4];
} ColorFormatInfo;
typedef struct SurfaceColorFormatInfo {
unsigned int bytes_per_pixel;
GLint gl_internal_format;
GLenum gl_format;
GLenum gl_type;
} SurfaceColorFormatInfo;
static void pgraph_context_switch(NV2AState *d, unsigned int channel_id); static void pgraph_context_switch(NV2AState *d, unsigned int channel_id);
static void pgraph_set_context_user(NV2AState *d, uint32_t val); static void pgraph_set_context_user(NV2AState *d, uint32_t val);
//static void pgraph_wait_fifo_access(NV2AState *d); //static void pgraph_wait_fifo_access(NV2AState *d);
@ -1078,6 +1211,56 @@ static void pgraph_method_log(unsigned int subchannel, unsigned int graphics_cla
last = method; last = method;
} }
static void pgraph_allocate_inline_buffer_vertices(PGRAPHState *pg,
unsigned int attr)
{
int i;
VertexAttribute *attribute = &pg->vertex_attributes[attr];
if (attribute->inline_buffer || pg->inline_buffer_length == 0) {
return;
}
/* Now upload the previous attribute value */
attribute->inline_buffer = (float*)calloc(1, NV2A_MAX_BATCH_LENGTH
* sizeof(float) * 4);
for (i = 0; i < pg->inline_buffer_length; i++) {
memcpy(&attribute->inline_buffer[i * 4],
attribute->inline_value,
sizeof(float) * 4);
}
}
static void pgraph_finish_inline_buffer_vertex(PGRAPHState *pg)
{
int i;
assert(pg->inline_buffer_length < NV2A_MAX_BATCH_LENGTH);
for (i = 0; i < NV2A_VERTEXSHADER_ATTRIBUTES; i++) {
VertexAttribute *attribute = &pg->vertex_attributes[i];
if (attribute->inline_buffer) {
memcpy(&attribute->inline_buffer[
pg->inline_buffer_length * 4],
attribute->inline_value,
sizeof(float) * 4);
}
}
pg->inline_buffer_length++;
}
static bool pgraph_framebuffer_dirty(PGRAPHState *pg)
{
bool shape_changed = memcmp(&pg->surface_shape, &pg->last_surface_shape,
sizeof(SurfaceShape)) != 0;
if (!shape_changed || (!pg->surface_shape.color_format
&& !pg->surface_shape.zeta_format)) {
return false;
}
return true;
}
static bool pgraph_color_write_enabled(PGRAPHState *pg) static bool pgraph_color_write_enabled(PGRAPHState *pg)
{ {
return pg->regs[NV_PGRAPH_CONTROL_0] & ( return pg->regs[NV_PGRAPH_CONTROL_0] & (
@ -1135,6 +1318,43 @@ static GraphicsObject* lookup_graphics_object(PGRAPHState *s,xbaddr instance_add
return NULL; return NULL;
} }
/* 16 bit to [0.0, F16_MAX = 511.9375] */
static float convert_f16_to_float(uint16_t f16) {
if (f16 == 0x0000) { return 0.0; }
uint32_t i = (f16 << 11) + 0x3C000000;
return *(float*)&i;
}
/* 24 bit to [0.0, F24_MAX] */
static float convert_f24_to_float(uint32_t f24) {
assert(!(f24 >> 24));
f24 &= 0xFFFFFF;
if (f24 == 0x000000) { return 0.0; }
uint32_t i = f24 << 7;
return *(float*)&i;
}
static uint8_t cliptobyte(int x)
{
return (uint8_t)((x < 0) ? 0 : ((x > 255) ? 255 : x));
}
static void convert_yuy2_to_rgb(const uint8_t *line, unsigned int ix,
uint8_t *r, uint8_t *g, uint8_t* b) {
int c, d, e;
c = (int)line[ix * 2] - 16;
if (ix % 2) {
d = (int)line[ix * 2 - 1] - 128;
e = (int)line[ix * 2 + 1] - 128;
} else {
d = (int)line[ix * 2 + 1] - 128;
e = (int)line[ix * 2 + 3] - 128;
}
*r = cliptobyte((298 * c + 409 * e + 128) >> 8);
*g = cliptobyte((298 * c - 100 * d - 208 * e + 128) >> 8);
*b = cliptobyte((298 * c + 516 * d + 128) >> 8);
}
static unsigned int kelvin_map_stencil_op(uint32_t parameter) static unsigned int kelvin_map_stencil_op(uint32_t parameter)
{ {
unsigned int op; unsigned int op;
@ -1206,3 +1426,53 @@ static unsigned int kelvin_map_texgen(uint32_t parameter, unsigned int channel)
return texgen; return texgen;
} }
static uint64_t fnv_hash(const uint8_t *data, size_t len)
{
/* 64 bit Fowler/Noll/Vo FNV-1a hash code */
uint64_t hval = 0xcbf29ce484222325ULL;
const uint8_t *dp = data;
const uint8_t *de = data + len;
while (dp < de) {
hval ^= (uint64_t) *dp++;
hval += (hval << 1) + (hval << 4) + (hval << 5) +
(hval << 7) + (hval << 8) + (hval << 40);
}
return hval;
}
static uint64_t fast_hash(const uint8_t *data, size_t len, unsigned int samples)
{
#ifdef __SSE4_2__
uint64_t h[4] = {len, 0, 0, 0};
assert(samples > 0);
if (len < 8 || len % 8) {
return fnv_hash(data, len);
}
assert(len >= 8 && len % 8 == 0);
const uint64_t *dp = (const uint64_t*)data;
const uint64_t *de = dp + (len / 8);
size_t step = len / 8 / samples;
if (step == 0) step = 1;
while (dp < de - step * 3) {
h[0] = __builtin_ia32_crc32di(h[0], dp[step * 0]);
h[1] = __builtin_ia32_crc32di(h[1], dp[step * 1]);
h[2] = __builtin_ia32_crc32di(h[2], dp[step * 2]);
h[3] = __builtin_ia32_crc32di(h[3], dp[step * 3]);
dp += step * 4;
}
if (dp < de - step * 0)
h[0] = __builtin_ia32_crc32di(h[0], dp[step * 0]);
if (dp < de - step * 1)
h[1] = __builtin_ia32_crc32di(h[1], dp[step * 1]);
if (dp < de - step * 2)
h[2] = __builtin_ia32_crc32di(h[2], dp[step * 2]);
return h[0] + (h[1] << 10) + (h[2] << 21) + (h[3] << 32);
#else
return fnv_hash(data, len);
#endif
}

View File

@ -357,7 +357,7 @@ typedef struct PGRAPHState {
float light_local_position[NV2A_MAX_LIGHTS][3]; float light_local_position[NV2A_MAX_LIGHTS][3];
float light_local_attenuation[NV2A_MAX_LIGHTS][3]; float light_local_attenuation[NV2A_MAX_LIGHTS][3];
//VertexAttribute vertex_attributes[NV2A_VERTEXSHADER_ATTRIBUTES]; VertexAttribute vertex_attributes[NV2A_VERTEXSHADER_ATTRIBUTES];
unsigned int inline_array_length; unsigned int inline_array_length;
uint32_t inline_array[NV2A_MAX_BATCH_LENGTH]; uint32_t inline_array[NV2A_MAX_BATCH_LENGTH];