mirror of https://github.com/xemu-project/xemu.git
clean up vsh program loading
This commit is contained in:
parent
21e55dc3c0
commit
9c534afa34
|
@ -262,8 +262,12 @@
|
|||
# define NV_PGRAPH_CSV0_D_MODE 0xC0000000
|
||||
# define NV_PGRAPH_CSV0_D_RANGE_MODE (1 << 18)
|
||||
#define NV_PGRAPH_CSV0_C 0x00000FB8
|
||||
# define NV_PGRAPH_CSV0_C_CHEOPS_PROGRAM_START 0x0000FF00
|
||||
#define NV_PGRAPH_CSV1_B 0x00000FBC
|
||||
#define NV_PGRAPH_CSV1_A 0x00000FC0
|
||||
#define NV_PGRAPH_CHEOPS_OFFSET 0x00000FC4
|
||||
# define NV_PGRAPH_CHEOPS_OFFSET_PROG_LD_PTR 0x000000FF
|
||||
# define NV_PGRAPH_CHEOPS_OFFSET_CONST_LD_PTR 0x0000FF00
|
||||
#define NV_PGRAPH_CLEARRECTX 0x00001864
|
||||
# define NV_PGRAPH_CLEARRECTX_XMIN 0x00000FFF
|
||||
# define NV_PGRAPH_CLEARRECTX_XMAX 0x0FFF0000
|
||||
|
@ -334,6 +338,7 @@
|
|||
#define NV_PGRAPH_ZCLIPMAX 0x00001ABC
|
||||
#define NV_PGRAPH_ZCLIPMIN 0x00001A90
|
||||
|
||||
|
||||
#define NV_PCRTC_INTR_0 0x00000100
|
||||
# define NV_PCRTC_INTR_0_VBLANK (1 << 0)
|
||||
#define NV_PCRTC_INTR_EN_0 0x00000140
|
||||
|
@ -819,7 +824,7 @@ typedef struct VertexAttribute {
|
|||
|
||||
typedef struct VertexShaderConstant {
|
||||
bool dirty;
|
||||
uint32 data[4];
|
||||
uint32_t data[4];
|
||||
} VertexShaderConstant;
|
||||
|
||||
typedef struct ShaderState {
|
||||
|
@ -839,7 +844,7 @@ typedef struct ShaderState {
|
|||
bool fixed_function;
|
||||
|
||||
bool vertex_program;
|
||||
uint32_t program_data[NV2A_MAX_TRANSFORM_PROGRAM_LENGTH];
|
||||
uint32_t program_data[NV2A_MAX_TRANSFORM_PROGRAM_LENGTH][VSH_TOKEN_SIZE];
|
||||
int program_length;
|
||||
} ShaderState;
|
||||
|
||||
|
@ -963,11 +968,8 @@ typedef struct PGRAPHState {
|
|||
|
||||
bool enable_vertex_program_write;
|
||||
|
||||
unsigned int program_start;
|
||||
unsigned int program_load;
|
||||
uint32_t program_data[NV2A_MAX_TRANSFORM_PROGRAM_LENGTH];
|
||||
uint32_t program_data[NV2A_MAX_TRANSFORM_PROGRAM_LENGTH][VSH_TOKEN_SIZE];
|
||||
|
||||
unsigned int constant_load_slot;
|
||||
VertexShaderConstant constants[NV2A_VERTEXSHADER_CONSTANTS];
|
||||
|
||||
VertexAttribute vertex_attributes[NV2A_VERTEXSHADER_ATTRIBUTES];
|
||||
|
@ -1648,7 +1650,7 @@ static GLuint generate_shaders(ShaderState state)
|
|||
|
||||
} else if (state.vertex_program) {
|
||||
vertex_shader_code = vsh_translate(VSH_VERSION_XVS,
|
||||
state.program_data,
|
||||
(uint32_t*)state.program_data,
|
||||
state.program_length);
|
||||
vertex_shader_code_str = qstring_get_str(vertex_shader_code);
|
||||
}
|
||||
|
@ -1781,6 +1783,9 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
|
|||
bool fixed_function = GET_MASK(pg->regs[NV_PGRAPH_CSV0_D],
|
||||
NV_PGRAPH_CSV0_D_MODE) == 0;
|
||||
|
||||
int program_start = GET_MASK(pg->regs[NV_PGRAPH_CSV0_C],
|
||||
NV_PGRAPH_CSV0_C_CHEOPS_PROGRAM_START);
|
||||
|
||||
if (pg->shaders_dirty) {
|
||||
ShaderState state = {
|
||||
/* register combier stuff */
|
||||
|
@ -1802,14 +1807,14 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
|
|||
|
||||
if (vertex_program) {
|
||||
// copy in vertex program tokens
|
||||
for (i = pg->program_start;
|
||||
for (i = program_start;
|
||||
i < NV2A_MAX_TRANSFORM_PROGRAM_LENGTH;
|
||||
i += VSH_TOKEN_SIZE) {
|
||||
uint32_t *cur_token = pg->program_data + i;
|
||||
memcpy(state.program_data + state.program_length,
|
||||
i++) {
|
||||
uint32_t *cur_token = (uint32_t*)&pg->program_data[i];
|
||||
memcpy(&state.program_data[state.program_length],
|
||||
cur_token,
|
||||
VSH_TOKEN_SIZE * sizeof(uint32_t));
|
||||
state.program_length += VSH_TOKEN_SIZE;
|
||||
state.program_length++;
|
||||
|
||||
if (vsh_get_field(cur_token, FLD_FINAL)) {
|
||||
break;
|
||||
|
@ -2212,8 +2217,6 @@ static void pgraph_method(NV2AState *d,
|
|||
GraphicsObject *object;
|
||||
|
||||
unsigned int slot;
|
||||
VertexAttribute *vertex_attribute;
|
||||
VertexShaderConstant *constant;
|
||||
|
||||
PGRAPHState *pg = &d->pgraph;
|
||||
|
||||
|
@ -2549,27 +2552,44 @@ static void pgraph_method(NV2AState *d,
|
|||
break;
|
||||
|
||||
case NV097_SET_TRANSFORM_PROGRAM ...
|
||||
NV097_SET_TRANSFORM_PROGRAM + 0x7c:
|
||||
NV097_SET_TRANSFORM_PROGRAM + 0x7c: {
|
||||
|
||||
// slot = (class_method - NV097_SET_TRANSFORM_PROGRAM) / 4;
|
||||
slot = (class_method - NV097_SET_TRANSFORM_PROGRAM) / 4;
|
||||
|
||||
assert(pg->program_load < NV2A_MAX_TRANSFORM_PROGRAM_LENGTH);
|
||||
pg->program_data[pg->program_load++] = parameter;
|
||||
int program_load = GET_MASK(pg->regs[NV_PGRAPH_CHEOPS_OFFSET],
|
||||
NV_PGRAPH_CHEOPS_OFFSET_PROG_LD_PTR);
|
||||
|
||||
assert(program_load < NV2A_MAX_TRANSFORM_PROGRAM_LENGTH);
|
||||
pg->program_data[program_load][slot%4] = parameter;
|
||||
pg->shaders_dirty = true;
|
||||
|
||||
if (slot % 4 == 3) {
|
||||
SET_MASK(pg->regs[NV_PGRAPH_CHEOPS_OFFSET],
|
||||
NV_PGRAPH_CHEOPS_OFFSET_PROG_LD_PTR, program_load+1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NV097_SET_TRANSFORM_CONSTANT ...
|
||||
NV097_SET_TRANSFORM_CONSTANT + 0x7c:
|
||||
NV097_SET_TRANSFORM_CONSTANT + 0x7c: {
|
||||
|
||||
// slot = (class_method - NV097_SET_TRANSFORM_CONSTANT) / 4;
|
||||
slot = (class_method - NV097_SET_TRANSFORM_CONSTANT) / 4;
|
||||
|
||||
assert((pg->constant_load_slot/4) < NV2A_VERTEXSHADER_CONSTANTS);
|
||||
constant = &pg->constants[pg->constant_load_slot/4];
|
||||
constant->data[pg->constant_load_slot%4] = parameter;
|
||||
int const_load = GET_MASK(pg->regs[NV_PGRAPH_CHEOPS_OFFSET],
|
||||
NV_PGRAPH_CHEOPS_OFFSET_CONST_LD_PTR);
|
||||
|
||||
assert(const_load < NV2A_VERTEXSHADER_CONSTANTS);
|
||||
VertexShaderConstant *constant = &pg->constants[const_load];
|
||||
constant->data[slot%4] = parameter;
|
||||
constant->dirty = true;
|
||||
|
||||
pg->constant_load_slot++;
|
||||
if (slot % 4 == 3) {
|
||||
SET_MASK(pg->regs[NV_PGRAPH_CHEOPS_OFFSET],
|
||||
NV_PGRAPH_CHEOPS_OFFSET_CONST_LD_PTR, const_load+1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NV097_SET_VERTEX4F ...
|
||||
NV097_SET_VERTEX4F + 12: {
|
||||
|
@ -2591,10 +2611,10 @@ static void pgraph_method(NV2AState *d,
|
|||
}
|
||||
|
||||
case NV097_SET_VERTEX_DATA_ARRAY_FORMAT ...
|
||||
NV097_SET_VERTEX_DATA_ARRAY_FORMAT + 0x3c:
|
||||
NV097_SET_VERTEX_DATA_ARRAY_FORMAT + 0x3c: {
|
||||
|
||||
slot = (class_method - NV097_SET_VERTEX_DATA_ARRAY_FORMAT) / 4;
|
||||
vertex_attribute = &pg->vertex_attributes[slot];
|
||||
VertexAttribute *vertex_attribute = &pg->vertex_attributes[slot];
|
||||
|
||||
vertex_attribute->format =
|
||||
GET_MASK(parameter, NV097_SET_VERTEX_DATA_ARRAY_FORMAT_TYPE);
|
||||
|
@ -2662,6 +2682,8 @@ static void pgraph_method(NV2AState *d,
|
|||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NV097_SET_VERTEX_DATA_ARRAY_OFFSET ...
|
||||
NV097_SET_VERTEX_DATA_ARRAY_OFFSET + 0x3c:
|
||||
|
||||
|
@ -2963,16 +2985,19 @@ static void pgraph_method(NV2AState *d,
|
|||
break;
|
||||
case NV097_SET_TRANSFORM_PROGRAM_LOAD:
|
||||
assert(parameter < NV2A_MAX_TRANSFORM_PROGRAM_LENGTH);
|
||||
pg->program_load = parameter * VSH_TOKEN_SIZE;
|
||||
SET_MASK(pg->regs[NV_PGRAPH_CHEOPS_OFFSET],
|
||||
NV_PGRAPH_CHEOPS_OFFSET_PROG_LD_PTR, parameter);
|
||||
break;
|
||||
case NV097_SET_TRANSFORM_PROGRAM_START:
|
||||
assert(parameter < NV2A_MAX_TRANSFORM_PROGRAM_LENGTH);
|
||||
pg->program_start = parameter * VSH_TOKEN_SIZE;
|
||||
SET_MASK(pg->regs[NV_PGRAPH_CSV0_C],
|
||||
NV_PGRAPH_CSV0_C_CHEOPS_PROGRAM_START, parameter);
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
case NV097_SET_TRANSFORM_CONSTANT_LOAD:
|
||||
assert(parameter < NV2A_VERTEXSHADER_CONSTANTS);
|
||||
pg->constant_load_slot = parameter * 4;
|
||||
SET_MASK(pg->regs[NV_PGRAPH_CHEOPS_OFFSET],
|
||||
NV_PGRAPH_CHEOPS_OFFSET_CONST_LD_PTR, parameter);
|
||||
NV2A_DPRINTF("load to %d\n", parameter);
|
||||
break;
|
||||
|
||||
|
|
|
@ -259,7 +259,7 @@ static const char* out_reg_name[] = {
|
|||
|
||||
|
||||
// Retrieves a number of bits in the instruction token
|
||||
static int vsh_get_from_token(uint32_t *shader_token,
|
||||
static int vsh_get_from_token(const uint32_t *shader_token,
|
||||
uint8_t subtoken,
|
||||
uint8_t start_bit,
|
||||
uint8_t bit_length)
|
||||
|
@ -267,7 +267,7 @@ static int vsh_get_from_token(uint32_t *shader_token,
|
|||
return (shader_token[subtoken] >> start_bit) & ~(0xFFFFFFFF << bit_length);
|
||||
}
|
||||
|
||||
uint8_t vsh_get_field(uint32_t *shader_token, VshFieldName field_name)
|
||||
uint8_t vsh_get_field(const uint32_t *shader_token, VshFieldName field_name)
|
||||
{
|
||||
|
||||
return (uint8_t)(vsh_get_from_token(shader_token,
|
||||
|
@ -287,7 +287,7 @@ static int16_t convert_c_register(const int16_t c_reg)
|
|||
|
||||
|
||||
|
||||
static QString* decode_swizzle(uint32_t *shader_token,
|
||||
static QString* decode_swizzle(const uint32_t *shader_token,
|
||||
VshFieldName swizzle_field)
|
||||
{
|
||||
const char* swizzle_str = "xyzw";
|
||||
|
@ -325,7 +325,7 @@ static QString* decode_swizzle(uint32_t *shader_token,
|
|||
}
|
||||
}
|
||||
|
||||
static QString* decode_opcode_input(uint32_t *shader_token,
|
||||
static QString* decode_opcode_input(const uint32_t *shader_token,
|
||||
VshParameterType param,
|
||||
VshFieldName neg_field,
|
||||
int reg_num)
|
||||
|
@ -378,7 +378,7 @@ static QString* decode_opcode_input(uint32_t *shader_token,
|
|||
}
|
||||
|
||||
|
||||
static QString* decode_opcode(uint32_t *shader_token,
|
||||
static QString* decode_opcode(const uint32_t *shader_token,
|
||||
VshOutputMux out_mux,
|
||||
uint32_t mask,
|
||||
const char* opcode,
|
||||
|
@ -447,7 +447,7 @@ static QString* decode_opcode(uint32_t *shader_token,
|
|||
}
|
||||
|
||||
|
||||
static QString* decode_token(uint32_t *shader_token)
|
||||
static QString* decode_token(const uint32_t *shader_token)
|
||||
{
|
||||
QString *ret;
|
||||
|
||||
|
@ -741,17 +741,16 @@ static const char* vsh_header =
|
|||
"}\n";
|
||||
|
||||
QString* vsh_translate(uint16_t version,
|
||||
uint32_t *tokens, unsigned int tokens_length)
|
||||
const uint32_t *tokens,
|
||||
unsigned int length)
|
||||
{
|
||||
QString *body = qstring_from_str("\n");
|
||||
QString *header = qstring_from_str(vsh_header);
|
||||
|
||||
|
||||
bool has_final = false;
|
||||
uint32_t *cur_token = tokens;
|
||||
unsigned int slot;
|
||||
while (cur_token-tokens < tokens_length) {
|
||||
slot = (cur_token-tokens) / VSH_TOKEN_SIZE;
|
||||
for (int slot=0; slot<length; slot++) {
|
||||
const uint32_t* cur_token = &tokens[slot * VSH_TOKEN_SIZE];
|
||||
QString *token_str = decode_token(cur_token);
|
||||
qstring_append_fmt(body,
|
||||
" /* Slot %d: 0x%08X 0x%08X 0x%08X 0x%08X */",
|
||||
|
@ -766,7 +765,6 @@ QString* vsh_translate(uint16_t version,
|
|||
has_final = true;
|
||||
break;
|
||||
}
|
||||
cur_token += VSH_TOKEN_SIZE;
|
||||
}
|
||||
assert(has_final);
|
||||
|
||||
|
|
|
@ -82,10 +82,11 @@ typedef enum {
|
|||
FLD_FINAL
|
||||
} VshFieldName;
|
||||
|
||||
uint8_t vsh_get_field(uint32_t *shader_token, VshFieldName field_name);
|
||||
uint8_t vsh_get_field(const uint32_t *shader_token, VshFieldName field_name);
|
||||
|
||||
QString* vsh_translate(uint16_t version,
|
||||
uint32_t *tokens, unsigned int tokens_length);
|
||||
const uint32_t *tokens,
|
||||
unsigned int length);
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue