From 7802178db74ceee306094886099510ae4faa909d Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Fri, 17 Jul 2015 03:00:42 +0200 Subject: [PATCH 1/6] Finish vertex with generic attributes too --- hw/xbox/nv2a.c | 61 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/hw/xbox/nv2a.c b/hw/xbox/nv2a.c index 9801128543..480e89067f 100644 --- a/hw/xbox/nv2a.c +++ b/hw/xbox/nv2a.c @@ -3858,6 +3858,36 @@ static unsigned int kelvin_map_texgen(uint32_t parameter, unsigned int channel) return texgen; } +static void finish_inline_vertex(PGRAPHState *pg) +{ + int i; + + assert(pg->inline_buffer_length < NV2A_MAX_BATCH_LENGTH); + + InlineVertexBufferEntry *entry = + &pg->inline_buffer[pg->inline_buffer_length]; + + memcpy(entry->position, + pg->vertex_attributes[NV2A_VERTEX_ATTR_POSITION].inline_value, + sizeof(float) * 4); + + memcpy(entry->weight, + pg->vertex_attributes[NV2A_VERTEX_ATTR_WEIGHT].inline_value, + sizeof(float) * 4); + + memcpy(entry->diffuse, + pg->vertex_attributes[NV2A_VERTEX_ATTR_DIFFUSE].inline_value, + sizeof(float) * 4); + + for (i = 0; i < NV2A_MAX_TEXTURES; i++) { + memcpy(entry->tex_coord[i], + pg->vertex_attributes[NV2A_VERTEX_ATTR_TEXTURE0+i].inline_value, + sizeof(float)*4); + } + + pg->inline_buffer_length++; +} + static void pgraph_method(NV2AState *d, unsigned int subchannel, unsigned int method, @@ -4566,28 +4596,10 @@ static void pgraph_method(NV2AState *d, case NV097_SET_VERTEX4F ... NV097_SET_VERTEX4F + 12: { - slot = (class_method - NV097_SET_VERTEX4F) / 4; - - assert(pg->inline_buffer_length < NV2A_MAX_BATCH_LENGTH); - - InlineVertexBufferEntry *entry = - &pg->inline_buffer[pg->inline_buffer_length]; - - entry->position[slot] = *(float*)¶meter; + pg->vertex_attributes[NV2A_VERTEX_ATTR_POSITION].inline_value[slot] = *(float*)¶meter; if (slot == 3) { - memcpy(entry->diffuse, - pg->vertex_attributes[NV2A_VERTEX_ATTR_DIFFUSE].inline_value, - sizeof(float)*4); - - for (i=0; itex_coord[i], - pg->vertex_attributes[NV2A_VERTEX_ATTR_TEXTURE0+i] - .inline_value, - sizeof(float)*4); - } - - pg->inline_buffer_length++; + finish_inline_vertex(pg); } break; } @@ -5018,6 +5030,9 @@ static void pgraph_method(NV2AState *d, pg->vertex_attributes[slot].inline_value[part] = *(float*)¶meter; pg->vertex_attributes[slot].inline_value[2] = 0.0; pg->vertex_attributes[slot].inline_value[3] = 1.0; + if ((slot == 0) && (part == 1)) { + finish_inline_vertex(pg); + } break; } @@ -5027,6 +5042,9 @@ static void pgraph_method(NV2AState *d, unsigned int part = ((class_method - NV097_SET_VERTEX_DATA4F_M) % 16) / 4; pg->vertex_attributes[slot].inline_value[part] = *(float*)¶meter; + if ((slot == 0) && (part == 3)) { + finish_inline_vertex(pg); + } break; } @@ -5041,6 +5059,9 @@ static void pgraph_method(NV2AState *d, ((parameter >> 16) & 0xFF) / 255.0; pg->vertex_attributes[slot].inline_value[3] = ((parameter >> 24) & 0xFF) / 255.0; + if (slot == 0) { + finish_inline_vertex(pg); + } break; case NV097_SET_SEMAPHORE_OFFSET: From 34ba061b603926c07bcba0c4d9d848629e1d393b Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Fri, 17 Jul 2015 03:57:42 +0200 Subject: [PATCH 2/6] Better and complete buffering for the inline-buffers --- hw/xbox/nv2a.c | 176 ++++++++++++++++++++++++------------------------- 1 file changed, 85 insertions(+), 91 deletions(-) diff --git a/hw/xbox/nv2a.c b/hw/xbox/nv2a.c index 480e89067f..10400de12f 100644 --- a/hw/xbox/nv2a.c +++ b/hw/xbox/nv2a.c @@ -1309,11 +1309,14 @@ typedef struct VertexAttribute { unsigned int converted_size; unsigned int converted_count; + float *inline_buffer_buffer; + GLint gl_count; GLenum gl_type; GLboolean gl_normalize; GLuint gl_converted_buffer; + GLuint gl_inline_buffer_buffer; } VertexAttribute; typedef struct VertexShaderConstant { @@ -1403,13 +1406,6 @@ typedef struct TextureBinding { unsigned int refcnt; } TextureBinding; -typedef struct InlineVertexBufferEntry { - float position[4]; - float weight[4]; - float diffuse[4]; - float tex_coord[NV2A_MAX_TEXTURES][4]; -} InlineVertexBufferEntry; - typedef struct KelvinState { hwaddr dma_notifies; hwaddr dma_state; @@ -1537,8 +1533,6 @@ typedef struct PGRAPHState { uint32_t inline_elements[NV2A_MAX_BATCH_LENGTH]; unsigned int inline_buffer_length; - InlineVertexBufferEntry inline_buffer[NV2A_MAX_BATCH_LENGTH]; - GLuint gl_inline_buffer_buffer; GLuint gl_element_buffer; GLuint gl_memory_buffer; @@ -3759,9 +3753,9 @@ static void pgraph_init(NV2AState *d) for (i=0; ivertex_attributes[i].gl_converted_buffer); + glGenBuffers(1, &pg->vertex_attributes[i].gl_inline_buffer_buffer); } glGenBuffers(1, &pg->gl_inline_array_buffer); - glGenBuffers(1, &pg->gl_inline_buffer_buffer); glGenBuffers(1, &pg->gl_element_buffer); glGenBuffers(1, &pg->gl_memory_buffer); @@ -3858,31 +3852,39 @@ static unsigned int kelvin_map_texgen(uint32_t parameter, unsigned int channel) return texgen; } -static void finish_inline_vertex(PGRAPHState *pg) +static void allocate_inline_buffer_vertices(PGRAPHState *pg, unsigned int attr) +{ + int i; + VertexAttribute *attribute = &pg->vertex_attributes[attr]; + + if (attribute->inline_buffer_buffer || pg->inline_buffer_length == 0) { + return; + } + + /* Now upload the previous attribute value */ + attribute->inline_buffer_buffer = g_malloc(NV2A_MAX_BATCH_LENGTH + * sizeof(float) * 4); + for (i = 0; i < pg->inline_buffer_length; i++) { + memcpy(&attribute->inline_buffer_buffer[i * 4], + attribute->inline_value, + sizeof(float) * 4); + } +} + +static void finish_inline_buffer_vertex(PGRAPHState *pg) { int i; assert(pg->inline_buffer_length < NV2A_MAX_BATCH_LENGTH); - InlineVertexBufferEntry *entry = - &pg->inline_buffer[pg->inline_buffer_length]; - - memcpy(entry->position, - pg->vertex_attributes[NV2A_VERTEX_ATTR_POSITION].inline_value, - sizeof(float) * 4); - - memcpy(entry->weight, - pg->vertex_attributes[NV2A_VERTEX_ATTR_WEIGHT].inline_value, - sizeof(float) * 4); - - memcpy(entry->diffuse, - pg->vertex_attributes[NV2A_VERTEX_ATTR_DIFFUSE].inline_value, - sizeof(float) * 4); - - for (i = 0; i < NV2A_MAX_TEXTURES; i++) { - memcpy(entry->tex_coord[i], - pg->vertex_attributes[NV2A_VERTEX_ATTR_TEXTURE0+i].inline_value, - sizeof(float)*4); + for (i = 0; i < NV2A_VERTEXSHADER_ATTRIBUTES; i++) { + VertexAttribute *attribute = &pg->vertex_attributes[i]; + if (attribute->inline_buffer_buffer) { + memcpy(&attribute->inline_buffer_buffer[ + pg->inline_buffer_length * 4], + attribute->inline_value, + sizeof(float) * 4); + } } pg->inline_buffer_length++; @@ -4597,9 +4599,12 @@ static void pgraph_method(NV2AState *d, case NV097_SET_VERTEX4F ... NV097_SET_VERTEX4F + 12: { slot = (class_method - NV097_SET_VERTEX4F) / 4; - pg->vertex_attributes[NV2A_VERTEX_ATTR_POSITION].inline_value[slot] = *(float*)¶meter; + VertexAttribute *attribute = + &pg->vertex_attributes[NV2A_VERTEX_ATTR_POSITION]; + allocate_inline_buffer_vertices(pg, NV2A_VERTEX_ATTR_POSITION); + attribute->inline_value[slot] = *(float*)¶meter; if (slot == 3) { - finish_inline_vertex(pg); + finish_inline_buffer_vertex(pg); } break; } @@ -4717,48 +4722,31 @@ static void pgraph_method(NV2AState *d, if (parameter == NV097_SET_BEGIN_END_OP_END) { if (pg->inline_buffer_length) { - // pgraph_bind_vertex_attributes(...) + for (i = 0; i < NV2A_VERTEXSHADER_ATTRIBUTES; i++) { + VertexAttribute *attribute = &pg->vertex_attributes[i]; - glBindBuffer(GL_ARRAY_BUFFER, pg->gl_inline_buffer_buffer); - glBufferData(GL_ARRAY_BUFFER, - pg->inline_buffer_length - * sizeof(InlineVertexBufferEntry), - pg->inline_buffer, - GL_DYNAMIC_DRAW); + if (attribute->inline_buffer_buffer) { - glVertexAttribPointer(NV2A_VERTEX_ATTR_POSITION, - 4, - GL_FLOAT, - GL_FALSE, - sizeof(InlineVertexBufferEntry), - (void*)offsetof(InlineVertexBufferEntry, position)); - glEnableVertexAttribArray(NV2A_VERTEX_ATTR_POSITION); + glBindBuffer(GL_ARRAY_BUFFER, + attribute->gl_inline_buffer_buffer); + glBufferData(GL_ARRAY_BUFFER, + pg->inline_buffer_length + * sizeof(float) * 4, + attribute->inline_buffer_buffer, + GL_DYNAMIC_DRAW); - glVertexAttribPointer(NV2A_VERTEX_ATTR_WEIGHT, - 4, - GL_FLOAT, - GL_FALSE, - sizeof(InlineVertexBufferEntry), - (void*)offsetof(InlineVertexBufferEntry, weight)); - glEnableVertexAttribArray(NV2A_VERTEX_ATTR_WEIGHT); + /* Clear buffer for next batch */ + g_free(attribute->inline_buffer_buffer); + attribute->inline_buffer_buffer = NULL; - glVertexAttribPointer(NV2A_VERTEX_ATTR_DIFFUSE, - 4, - GL_FLOAT, - GL_FALSE, - sizeof(InlineVertexBufferEntry), - (void*)offsetof(InlineVertexBufferEntry, diffuse)); - glEnableVertexAttribArray(NV2A_VERTEX_ATTR_DIFFUSE); + glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(i); + } else { + glDisableVertexAttribArray(i); + + glVertexAttrib4fv(i, attribute->inline_value); + } - for (i=0; igl_primitive_mode, @@ -4899,6 +4887,7 @@ static void pgraph_method(NV2AState *d, pg->inline_elements_length = 0; pg->inline_array_length = 0; pg->inline_buffer_length = 0; + } pgraph_set_surface_dirty(pg, true, depth_test || stencil_test); @@ -5024,45 +5013,50 @@ static void pgraph_method(NV2AState *d, case NV097_SET_VERTEX_DATA2F_M ... NV097_SET_VERTEX_DATA2F_M + 0x7c: { - slot = (class_method - NV097_SET_VERTEX_DATA2F_M) / 8; - unsigned int part = - ((class_method - NV097_SET_VERTEX_DATA2F_M) % 8) / 4; - pg->vertex_attributes[slot].inline_value[part] = *(float*)¶meter; - pg->vertex_attributes[slot].inline_value[2] = 0.0; - pg->vertex_attributes[slot].inline_value[3] = 1.0; + slot = (class_method - NV097_SET_VERTEX_DATA2F_M) / 4; + unsigned int part = slot % 2; + slot /= 2; + VertexAttribute *attribute = &pg->vertex_attributes[slot]; + allocate_inline_buffer_vertices(pg, slot); + attribute->inline_value[part] = *(float*)¶meter; + /* FIXME: Should these really be set to 0.0 and 1.0 ? Conditions? */ + attribute->inline_value[2] = 0.0; + attribute->inline_value[3] = 1.0; if ((slot == 0) && (part == 1)) { - finish_inline_vertex(pg); + finish_inline_buffer_vertex(pg); } break; } case NV097_SET_VERTEX_DATA4F_M ... NV097_SET_VERTEX_DATA4F_M + 0xfc: { - slot = (class_method - NV097_SET_VERTEX_DATA4F_M) / 16; - unsigned int part = - ((class_method - NV097_SET_VERTEX_DATA4F_M) % 16) / 4; - pg->vertex_attributes[slot].inline_value[part] = *(float*)¶meter; + slot = (class_method - NV097_SET_VERTEX_DATA4F_M) / 4; + unsigned int part = slot % 4; + slot /= 4; + VertexAttribute *attribute = &pg->vertex_attributes[slot]; + allocate_inline_buffer_vertices(pg, slot); + attribute->inline_value[part] = *(float*)¶meter; if ((slot == 0) && (part == 3)) { - finish_inline_vertex(pg); + finish_inline_buffer_vertex(pg); } break; } case NV097_SET_VERTEX_DATA4UB ... - NV097_SET_VERTEX_DATA4UB + 0x3c: + NV097_SET_VERTEX_DATA4UB + 0x3c: { slot = (class_method - NV097_SET_VERTEX_DATA4UB) / 4; - pg->vertex_attributes[slot].inline_value[0] = - (parameter & 0xFF) / 255.0; - pg->vertex_attributes[slot].inline_value[1] = - ((parameter >> 8) & 0xFF) / 255.0; - pg->vertex_attributes[slot].inline_value[2] = - ((parameter >> 16) & 0xFF) / 255.0; - pg->vertex_attributes[slot].inline_value[3] = - ((parameter >> 24) & 0xFF) / 255.0; + VertexAttribute *attribute = &pg->vertex_attributes[slot]; + allocate_inline_buffer_vertices(pg, slot); + attribute->inline_value[0] = (parameter & 0xFF) / 255.0; + attribute->inline_value[1] = ((parameter >> 8) & 0xFF) / 255.0; + attribute->inline_value[2] = ((parameter >> 16) & 0xFF) / 255.0; + attribute->inline_value[3] = ((parameter >> 24) & 0xFF) / 255.0; if (slot == 0) { - finish_inline_vertex(pg); + finish_inline_buffer_vertex(pg); + assert(false); /* FIXME: Untested */ } break; + } case NV097_SET_SEMAPHORE_OFFSET: kelvin->semaphore_offset = parameter; From e5cf290041f659729fa4b7b49bad314bc4cbb349 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Fri, 17 Jul 2015 15:30:45 +0200 Subject: [PATCH 3/6] Added short inline-buffers (Untested but asserted) --- hw/xbox/nv2a.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/hw/xbox/nv2a.c b/hw/xbox/nv2a.c index 10400de12f..3d32005082 100644 --- a/hw/xbox/nv2a.c +++ b/hw/xbox/nv2a.c @@ -918,7 +918,9 @@ static void gl_debug_label(GLenum target, GLuint name, const char *fmt, ...) # define NV097_INLINE_ARRAY 0x00971818 # define NV097_SET_VERTEX_DATA2F_M 0x00971880 # define NV097_SET_VERTEX_DATA4F_M 0x00971A00 +# define NV097_SET_VERTEX_DATA2S 0x00971900 # define NV097_SET_VERTEX_DATA4UB 0x00971940 +# define NV097_SET_VERTEX_DATA4S_M 0x00971980 # define NV097_SET_TEXTURE_OFFSET 0x00971B00 # define NV097_SET_TEXTURE_FORMAT 0x00971B04 # define NV097_SET_TEXTURE_FORMAT_CONTEXT_DMA 0x00000003 @@ -5027,7 +5029,6 @@ static void pgraph_method(NV2AState *d, } break; } - case NV097_SET_VERTEX_DATA4F_M ... NV097_SET_VERTEX_DATA4F_M + 0xfc: { slot = (class_method - NV097_SET_VERTEX_DATA4F_M) / 4; @@ -5041,7 +5042,27 @@ static void pgraph_method(NV2AState *d, } break; } - + case NV097_SET_VERTEX_DATA2S ... + NV097_SET_VERTEX_DATA2S + 0x3c: { + slot = (class_method - NV097_SET_VERTEX_DATA2S) / 4; + assert(false); /* FIXME: Untested! */ + VertexAttribute *attribute = &pg->vertex_attributes[slot]; + allocate_inline_buffer_vertices(pg, slot); + /* FIXME: Is mapping to [-1,+1] correct? */ + parameter ^= 0x80008000; + attribute->inline_value[0] = ((parameter & 0xFFFF) + / 65535.0f - 0.5f) * 2.0f; + attribute->inline_value[1] = ((parameter >> 16) + / 65535.0f - 0.5f) * 2.0f; + /* FIXME: Should these really be set to 0.0 and 1.0 ? Conditions? */ + attribute->inline_value[2] = 0.0; + attribute->inline_value[3] = 1.0; + if (slot == 0) { + finish_inline_buffer_vertex(pg); + assert(false); /* FIXME: Untested */ + } + break; + } case NV097_SET_VERTEX_DATA4UB ... NV097_SET_VERTEX_DATA4UB + 0x3c: { slot = (class_method - NV097_SET_VERTEX_DATA4UB) / 4; @@ -5057,6 +5078,26 @@ static void pgraph_method(NV2AState *d, } break; } + case NV097_SET_VERTEX_DATA4S_M ... + NV097_SET_VERTEX_DATA4S_M + 0x7c: { + slot = (class_method - NV097_SET_VERTEX_DATA4S_M) / 4; + unsigned int part = slot % 2; + slot /= 2; + assert(false); /* FIXME: Untested! */ + VertexAttribute *attribute = &pg->vertex_attributes[slot]; + allocate_inline_buffer_vertices(pg, slot); + /* FIXME: Is mapping to [-1,+1] correct? */ + parameter ^= 0x80008000; + attribute->inline_value[part * 2 + 0] = ((parameter & 0xFFFF) + / 65535.0f - 0.5f) * 2.0f; + attribute->inline_value[part * 2 + 1] = ((parameter >> 16) + / 65535.0f - 0.5f) * 2.0f; + if ((slot == 0) && (part == 1)) { + finish_inline_buffer_vertex(pg); + assert(false); /* FIXME: Untested */ + } + break; + } case NV097_SET_SEMAPHORE_OFFSET: kelvin->semaphore_offset = parameter; From 3bce85c694f513d47fa24ff7458a802523f5c694 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Tue, 21 Jul 2015 11:55:23 +0200 Subject: [PATCH 4/6] Prefix functions with pgraph_ --- hw/xbox/nv2a.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/hw/xbox/nv2a.c b/hw/xbox/nv2a.c index 3d32005082..809b0881cc 100644 --- a/hw/xbox/nv2a.c +++ b/hw/xbox/nv2a.c @@ -3854,7 +3854,8 @@ static unsigned int kelvin_map_texgen(uint32_t parameter, unsigned int channel) return texgen; } -static void allocate_inline_buffer_vertices(PGRAPHState *pg, unsigned int attr) +static void pgraph_allocate_inline_buffer_vertices(PGRAPHState *pg, + unsigned int attr) { int i; VertexAttribute *attribute = &pg->vertex_attributes[attr]; @@ -3873,7 +3874,7 @@ static void allocate_inline_buffer_vertices(PGRAPHState *pg, unsigned int attr) } } -static void finish_inline_buffer_vertex(PGRAPHState *pg) +static void pgraph_finish_inline_buffer_vertex(PGRAPHState *pg) { int i; @@ -4603,10 +4604,10 @@ static void pgraph_method(NV2AState *d, slot = (class_method - NV097_SET_VERTEX4F) / 4; VertexAttribute *attribute = &pg->vertex_attributes[NV2A_VERTEX_ATTR_POSITION]; - allocate_inline_buffer_vertices(pg, NV2A_VERTEX_ATTR_POSITION); + pgraph_allocate_inline_buffer_vertices(pg, NV2A_VERTEX_ATTR_POSITION); attribute->inline_value[slot] = *(float*)¶meter; if (slot == 3) { - finish_inline_buffer_vertex(pg); + pgraph_finish_inline_buffer_vertex(pg); } break; } @@ -5019,13 +5020,13 @@ static void pgraph_method(NV2AState *d, unsigned int part = slot % 2; slot /= 2; VertexAttribute *attribute = &pg->vertex_attributes[slot]; - allocate_inline_buffer_vertices(pg, slot); + pgraph_allocate_inline_buffer_vertices(pg, slot); attribute->inline_value[part] = *(float*)¶meter; /* FIXME: Should these really be set to 0.0 and 1.0 ? Conditions? */ attribute->inline_value[2] = 0.0; attribute->inline_value[3] = 1.0; if ((slot == 0) && (part == 1)) { - finish_inline_buffer_vertex(pg); + pgraph_finish_inline_buffer_vertex(pg); } break; } @@ -5035,10 +5036,10 @@ static void pgraph_method(NV2AState *d, unsigned int part = slot % 4; slot /= 4; VertexAttribute *attribute = &pg->vertex_attributes[slot]; - allocate_inline_buffer_vertices(pg, slot); + pgraph_allocate_inline_buffer_vertices(pg, slot); attribute->inline_value[part] = *(float*)¶meter; if ((slot == 0) && (part == 3)) { - finish_inline_buffer_vertex(pg); + pgraph_finish_inline_buffer_vertex(pg); } break; } @@ -5047,7 +5048,7 @@ static void pgraph_method(NV2AState *d, slot = (class_method - NV097_SET_VERTEX_DATA2S) / 4; assert(false); /* FIXME: Untested! */ VertexAttribute *attribute = &pg->vertex_attributes[slot]; - allocate_inline_buffer_vertices(pg, slot); + pgraph_allocate_inline_buffer_vertices(pg, slot); /* FIXME: Is mapping to [-1,+1] correct? */ parameter ^= 0x80008000; attribute->inline_value[0] = ((parameter & 0xFFFF) @@ -5058,7 +5059,7 @@ static void pgraph_method(NV2AState *d, attribute->inline_value[2] = 0.0; attribute->inline_value[3] = 1.0; if (slot == 0) { - finish_inline_buffer_vertex(pg); + pgraph_finish_inline_buffer_vertex(pg); assert(false); /* FIXME: Untested */ } break; @@ -5067,13 +5068,13 @@ static void pgraph_method(NV2AState *d, NV097_SET_VERTEX_DATA4UB + 0x3c: { slot = (class_method - NV097_SET_VERTEX_DATA4UB) / 4; VertexAttribute *attribute = &pg->vertex_attributes[slot]; - allocate_inline_buffer_vertices(pg, slot); + pgraph_allocate_inline_buffer_vertices(pg, slot); attribute->inline_value[0] = (parameter & 0xFF) / 255.0; attribute->inline_value[1] = ((parameter >> 8) & 0xFF) / 255.0; attribute->inline_value[2] = ((parameter >> 16) & 0xFF) / 255.0; attribute->inline_value[3] = ((parameter >> 24) & 0xFF) / 255.0; if (slot == 0) { - finish_inline_buffer_vertex(pg); + pgraph_finish_inline_buffer_vertex(pg); assert(false); /* FIXME: Untested */ } break; @@ -5085,7 +5086,7 @@ static void pgraph_method(NV2AState *d, slot /= 2; assert(false); /* FIXME: Untested! */ VertexAttribute *attribute = &pg->vertex_attributes[slot]; - allocate_inline_buffer_vertices(pg, slot); + pgraph_allocate_inline_buffer_vertices(pg, slot); /* FIXME: Is mapping to [-1,+1] correct? */ parameter ^= 0x80008000; attribute->inline_value[part * 2 + 0] = ((parameter & 0xFFFF) @@ -5093,7 +5094,7 @@ static void pgraph_method(NV2AState *d, attribute->inline_value[part * 2 + 1] = ((parameter >> 16) / 65535.0f - 0.5f) * 2.0f; if ((slot == 0) && (part == 1)) { - finish_inline_buffer_vertex(pg); + pgraph_finish_inline_buffer_vertex(pg); assert(false); /* FIXME: Untested */ } break; From e3dfc2e713ccf5f814d34f36551bf94e267f3a20 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Tue, 21 Jul 2015 11:55:37 +0200 Subject: [PATCH 5/6] Rename inline_buffer_buffer to inline_buffer --- hw/xbox/nv2a.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/hw/xbox/nv2a.c b/hw/xbox/nv2a.c index 809b0881cc..574580368f 100644 --- a/hw/xbox/nv2a.c +++ b/hw/xbox/nv2a.c @@ -1311,14 +1311,14 @@ typedef struct VertexAttribute { unsigned int converted_size; unsigned int converted_count; - float *inline_buffer_buffer; + float *inline_buffer; GLint gl_count; GLenum gl_type; GLboolean gl_normalize; GLuint gl_converted_buffer; - GLuint gl_inline_buffer_buffer; + GLuint gl_inline_buffer; } VertexAttribute; typedef struct VertexShaderConstant { @@ -3755,7 +3755,7 @@ static void pgraph_init(NV2AState *d) for (i=0; ivertex_attributes[i].gl_converted_buffer); - glGenBuffers(1, &pg->vertex_attributes[i].gl_inline_buffer_buffer); + glGenBuffers(1, &pg->vertex_attributes[i].gl_inline_buffer); } glGenBuffers(1, &pg->gl_inline_array_buffer); glGenBuffers(1, &pg->gl_element_buffer); @@ -3860,15 +3860,15 @@ static void pgraph_allocate_inline_buffer_vertices(PGRAPHState *pg, int i; VertexAttribute *attribute = &pg->vertex_attributes[attr]; - if (attribute->inline_buffer_buffer || pg->inline_buffer_length == 0) { + if (attribute->inline_buffer || pg->inline_buffer_length == 0) { return; } /* Now upload the previous attribute value */ - attribute->inline_buffer_buffer = g_malloc(NV2A_MAX_BATCH_LENGTH + attribute->inline_buffer = g_malloc(NV2A_MAX_BATCH_LENGTH * sizeof(float) * 4); for (i = 0; i < pg->inline_buffer_length; i++) { - memcpy(&attribute->inline_buffer_buffer[i * 4], + memcpy(&attribute->inline_buffer[i * 4], attribute->inline_value, sizeof(float) * 4); } @@ -3882,8 +3882,8 @@ static void pgraph_finish_inline_buffer_vertex(PGRAPHState *pg) for (i = 0; i < NV2A_VERTEXSHADER_ATTRIBUTES; i++) { VertexAttribute *attribute = &pg->vertex_attributes[i]; - if (attribute->inline_buffer_buffer) { - memcpy(&attribute->inline_buffer_buffer[ + if (attribute->inline_buffer) { + memcpy(&attribute->inline_buffer[ pg->inline_buffer_length * 4], attribute->inline_value, sizeof(float) * 4); @@ -4728,19 +4728,19 @@ static void pgraph_method(NV2AState *d, for (i = 0; i < NV2A_VERTEXSHADER_ATTRIBUTES; i++) { VertexAttribute *attribute = &pg->vertex_attributes[i]; - if (attribute->inline_buffer_buffer) { + if (attribute->inline_buffer) { glBindBuffer(GL_ARRAY_BUFFER, - attribute->gl_inline_buffer_buffer); + attribute->gl_inline_buffer); glBufferData(GL_ARRAY_BUFFER, pg->inline_buffer_length * sizeof(float) * 4, - attribute->inline_buffer_buffer, + attribute->inline_buffer, GL_DYNAMIC_DRAW); /* Clear buffer for next batch */ - g_free(attribute->inline_buffer_buffer); - attribute->inline_buffer_buffer = NULL; + g_free(attribute->inline_buffer); + attribute->inline_buffer = NULL; glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(i); From d93ef1a731e97700f54af426b8c6e7ff1dd8dad8 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Tue, 21 Jul 2015 12:01:37 +0200 Subject: [PATCH 6/6] Better short mapping code --- hw/xbox/nv2a.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/hw/xbox/nv2a.c b/hw/xbox/nv2a.c index 574580368f..ead152d594 100644 --- a/hw/xbox/nv2a.c +++ b/hw/xbox/nv2a.c @@ -5050,11 +5050,10 @@ static void pgraph_method(NV2AState *d, VertexAttribute *attribute = &pg->vertex_attributes[slot]; pgraph_allocate_inline_buffer_vertices(pg, slot); /* FIXME: Is mapping to [-1,+1] correct? */ - parameter ^= 0x80008000; - attribute->inline_value[0] = ((parameter & 0xFFFF) - / 65535.0f - 0.5f) * 2.0f; - attribute->inline_value[1] = ((parameter >> 16) - / 65535.0f - 0.5f) * 2.0f; + attribute->inline_value[0] = ((int16_t)(parameter & 0xFFFF) * 2.0 + 1) + / 65535.0; + attribute->inline_value[1] = ((int16_t)(parameter >> 16) * 2.0 + 1) + / 65535.0; /* FIXME: Should these really be set to 0.0 and 1.0 ? Conditions? */ attribute->inline_value[2] = 0.0; attribute->inline_value[3] = 1.0; @@ -5088,11 +5087,10 @@ static void pgraph_method(NV2AState *d, VertexAttribute *attribute = &pg->vertex_attributes[slot]; pgraph_allocate_inline_buffer_vertices(pg, slot); /* FIXME: Is mapping to [-1,+1] correct? */ - parameter ^= 0x80008000; - attribute->inline_value[part * 2 + 0] = ((parameter & 0xFFFF) - / 65535.0f - 0.5f) * 2.0f; - attribute->inline_value[part * 2 + 1] = ((parameter >> 16) - / 65535.0f - 0.5f) * 2.0f; + attribute->inline_value[part * 2 + 0] = ((int16_t)(parameter & 0xFFFF) + * 2.0 + 1) / 65535.0; + attribute->inline_value[part * 2 + 1] = ((int16_t)(parameter >> 16) + * 2.0 + 1) / 65535.0; if ((slot == 0) && (part == 1)) { pgraph_finish_inline_buffer_vertex(pg); assert(false); /* FIXME: Untested */