clean up vsh program loading

This commit is contained in:
espes 2015-04-21 01:59:24 -07:00
parent 21e55dc3c0
commit 9c534afa34
3 changed files with 67 additions and 43 deletions

View File

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

View File

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

View File

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