r600: enable caching of vertex programs

This commit is contained in:
Andre Maasikas 2009-09-11 10:59:05 -04:00 committed by Alex Deucher
parent 6552a103f9
commit 9edd1a441c
6 changed files with 109 additions and 61 deletions

View File

@ -51,6 +51,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r700_chip.h"
#include "r600_tex.h"
#include "r700_oglprog.h"
#include "r700_vertprog.h"
struct r600_context;
typedef struct r600_context context_t;
@ -155,6 +156,8 @@ struct r600_context {
struct r600_hw_state atoms;
struct r700_vertex_program *selected_vp;
/* Vertex buffers
*/
GLvector4f dummy_attrib[_TNL_ATTRIB_MAX];

View File

@ -211,8 +211,7 @@ static void r700SetupVTXConstants(GLcontext * ctx,
void r700SetupStreams(GLcontext *ctx)
{
context_t *context = R700_CONTEXT(ctx);
struct r700_vertex_program *vpc
= (struct r700_vertex_program *)ctx->VertexProgram._Current;
struct r700_vertex_program *vp = context->selected_vp;
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *vb = &tnl->vb;
unsigned int i, j = 0;
@ -221,7 +220,7 @@ void r700SetupStreams(GLcontext *ctx)
R600_STATECHANGE(context, vtx);
for(i=0; i<VERT_ATTRIB_MAX; i++) {
if(vpc->mesa_program.Base.InputsRead & (1 << i)) {
if(vp->mesa_program->Base.InputsRead & (1 << i)) {
rcommon_emit_vector(ctx,
&context->radeon.tcl.aos[j],
vb->AttribPtr[i]->data,
@ -237,8 +236,7 @@ void r700SetupStreams(GLcontext *ctx)
static void r700SendVTXState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
struct r700_vertex_program *vpc
= (struct r700_vertex_program *)ctx->VertexProgram._Current;
struct r700_vertex_program *vp = context->selected_vp;
unsigned int i, j = 0;
BATCH_LOCALS(&context->radeon);
radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
@ -258,7 +256,7 @@ static void r700SendVTXState(GLcontext *ctx, struct radeon_state_atom *atom)
COMMIT_BATCH();
for(i=0; i<VERT_ATTRIB_MAX; i++) {
if(vpc->mesa_program.Base.InputsRead & (1 << i)) {
if(vp->mesa_program->Base.InputsRead & (1 << i)) {
/* currently aos are packed */
r700SetupVTXConstants(ctx,
i,

View File

@ -46,7 +46,7 @@ static struct gl_program *r700NewProgram(GLcontext * ctx,
{
struct gl_program *pProgram = NULL;
struct r700_vertex_program *vp;
struct r700_vertex_program_cont *vpc;
struct r700_fragment_program *fp;
radeon_print(RADEON_SHADER, RADEON_VERBOSE,
@ -56,16 +56,11 @@ static struct gl_program *r700NewProgram(GLcontext * ctx,
{
case GL_VERTEX_STATE_PROGRAM_NV:
case GL_VERTEX_PROGRAM_ARB:
vp = CALLOC_STRUCT(r700_vertex_program);
vpc = CALLOC_STRUCT(r700_vertex_program_cont);
pProgram = _mesa_init_vertex_program(ctx,
&vp->mesa_program,
&vpc->mesa_program,
target,
id);
vp->translated = GL_FALSE;
vp->loaded = GL_FALSE;
vp->shaderbo = NULL;
break;
case GL_FRAGMENT_PROGRAM_NV:
case GL_FRAGMENT_PROGRAM_ARB:
@ -89,7 +84,8 @@ static struct gl_program *r700NewProgram(GLcontext * ctx,
static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog)
{
struct r700_vertex_program * vp;
struct r700_vertex_program_cont * vpc;
struct r700_vertex_program *vp, *tmp;
struct r700_fragment_program * fp;
radeon_print(RADEON_SHADER, RADEON_VERBOSE,
@ -99,14 +95,20 @@ static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog)
{
case GL_VERTEX_STATE_PROGRAM_NV:
case GL_VERTEX_PROGRAM_ARB:
vp = (struct r700_vertex_program*)prog;
/* Release DMA region */
vpc = (struct r700_vertex_program_cont*)prog;
vp = vpc->progs;
while (vp) {
tmp = vp->next;
/* Release DMA region */
r600DeleteShader(ctx, vp->shaderbo);
r600DeleteShader(ctx, vp->shaderbo);
/* Clean up */
Clean_Up_Assembler(&(vp->r700AsmCode));
Clean_Up_Shader(&(vp->r700Shader));
/* Clean up */
Clean_Up_Assembler(&(vp->r700AsmCode));
Clean_Up_Shader(&(vp->r700Shader));
_mesa_free(vp);
vp = tmp;
}
break;
case GL_FRAGMENT_PROGRAM_NV:
case GL_FRAGMENT_PROGRAM_ARB:

View File

@ -319,14 +319,13 @@ static GLuint r700PredictRenderSize(GLcontext* ctx)
{
context_t *context = R700_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct r700_vertex_program *vpc
= (struct r700_vertex_program *)ctx->VertexProgram._Current;
struct r700_vertex_program *vp = context->selected_vp;
struct vertex_buffer *vb = &tnl->vb;
GLboolean flushed;
GLuint dwords, i;
GLuint state_size;
/* pre calculate aos count so state prediction works */
context->radeon.tcl.aos_count = _mesa_bitcount(vpc->mesa_program.Base.InputsRead);
context->radeon.tcl.aos_count = _mesa_bitcount(vp->mesa_program->Base.InputsRead);
dwords = PRE_EMIT_STATE_BUFSZ;
for (i = 0; i < vb->PrimitiveCount; i++)
@ -365,7 +364,6 @@ static GLboolean r700RunRender(GLcontext * ctx,
/* mark vtx as dirty since it changes per-draw */
R600_STATECHANGE(context, vtx);
r700UpdateShaders(ctx);
r700SetScissor(context);
r700SetupVertexProgram(ctx);
r700SetupFragmentProgram(ctx);
@ -427,7 +425,10 @@ static GLboolean r700RunTCLRender(GLcontext * ctx, /*----------------------*/
/* TODO : sw fallback */
/* Need shader bo's setup before bo check */
r700UpdateShaders(ctx);
/**
* Ensure all enabled and complete textures are uploaded along with any buffers being used.
*/
if(!r600ValidateBuffers(ctx))

View File

@ -35,6 +35,7 @@
#include "main/mtypes.h"
#include "tnl/t_context.h"
#include "shader/program.h"
#include "shader/prog_parameter.h"
#include "shader/prog_statevars.h"
@ -258,28 +259,54 @@ GLboolean Find_Instruction_Dependencies_vp(struct r700_vertex_program *vp,
return GL_TRUE;
}
GLboolean r700TranslateVertexShader(struct r700_vertex_program *vp,
struct gl_vertex_program *mesa_vp)
struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx,
struct gl_vertex_program *mesa_vp)
{
context_t *context = R700_CONTEXT(ctx);
struct r700_vertex_program *vp;
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *vb = &tnl->vb;
unsigned int unBit;
unsigned int i;
vp = _mesa_calloc(sizeof(*vp));
vp->mesa_program = (struct gl_vertex_program *)_mesa_clone_program(ctx, &mesa_vp->Base);
for(i=0; i<VERT_ATTRIB_MAX; i++)
{
unBit = 1 << i;
if(vp->mesa_program->Base.InputsRead & unBit) /* ctx->Array.ArrayObj->xxxxxxx */
{
vp->aos_desc[i].size = vb->AttribPtr[i]->size;
vp->aos_desc[i].stride = vb->AttribPtr[i]->size * sizeof(GL_FLOAT);/* when emit array, data is packed. vb->AttribPtr[i]->stride;*/
vp->aos_desc[i].type = GL_FLOAT;
}
}
if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
{
vp->r700AsmCode.bR6xx = 1;
}
//Init_Program
Init_r700_AssemblerBase(SPT_VP, &(vp->r700AsmCode), &(vp->r700Shader) );
Map_Vertex_Program( vp, mesa_vp );
if(GL_FALSE == Find_Instruction_Dependencies_vp(vp, mesa_vp))
{
return GL_FALSE;
return NULL;
}
if(GL_FALSE == AssembleInstr(mesa_vp->Base.NumInstructions,
&(mesa_vp->Base.Instructions[0]),
&(vp->r700AsmCode)) )
{
return GL_FALSE;
return NULL;
}
if(GL_FALSE == Process_Vertex_Exports(&(vp->r700AsmCode), mesa_vp->Base.OutputsWritten) )
{
return GL_FALSE;
return NULL;
}
vp->r700Shader.nRegs = (vp->r700AsmCode.number_used_registers == 0) ? 0
@ -289,72 +316,82 @@ GLboolean r700TranslateVertexShader(struct r700_vertex_program *vp,
vp->translated = GL_TRUE;
return GL_TRUE;
return vp;
}
void r700SelectVertexShader(GLcontext *ctx)
{
context_t *context = R700_CONTEXT(ctx);
struct r700_vertex_program *vpc
= (struct r700_vertex_program *)ctx->VertexProgram._Current;
struct r700_vertex_program_cont *vpc;
struct r700_vertex_program *vp;
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *vb = &tnl->vb;
unsigned int unBit;
unsigned int i;
GLboolean match;
vpc = (struct r700_vertex_program_cont *)ctx->VertexProgram._Current;
#if 0
if (context->radeon.NewGLState & (_NEW_PROGRAM_CONSTANTS|_NEW_PROGRAM))
{
vpc->needUpdateVF = 1;
}
#endif
if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
for (vp = vpc->progs; vp; vp = vp->next)
{
vpc->r700AsmCode.bR6xx = 1;
}
match = GL_TRUE;
for(i=0; i<VERT_ATTRIB_MAX; i++)
{
unBit = 1 << i;
if(vpc->mesa_program.Base.InputsRead & unBit) /* ctx->Array.ArrayObj->xxxxxxx */
if(vpc->mesa_program.Base.InputsRead & unBit)
{
vpc->aos_desc[i].size = vb->AttribPtr[i]->size;
vpc->aos_desc[i].stride = vb->AttribPtr[i]->size * sizeof(GL_FLOAT);/* when emit array, data is packed. vb->AttribPtr[i]->stride;*/
vpc->aos_desc[i].type = GL_FLOAT;
if (vp->aos_desc[i].size != vb->AttribPtr[i]->size)
match = GL_FALSE;
break;
}
}
if(GL_FALSE == vpc->translated) {
r700TranslateVertexShader(vpc, &(vpc->mesa_program) );
if (match)
{
context->selected_vp = vp;
return;
}
}
vp = r700TranslateVertexShader(ctx, &(vpc->mesa_program) );
if(!vp)
{
radeon_error("Failed to translate vertex shader. \n");
return;
}
vp->next = vpc->progs;
vpc->progs = vp;
context->selected_vp = vp;
return;
}
void * r700GetActiveVpShaderBo(GLcontext * ctx)
{
struct r700_vertex_program *vp
= (struct r700_vertex_program *)ctx->VertexProgram._Current;
context_t *context = R700_CONTEXT(ctx);
struct r700_vertex_program *vp = context->selected_vp;;
return vp->shaderbo;
if (vp)
return vp->shaderbo;
else
return NULL;
}
GLboolean r700SetupVertexProgram(GLcontext * ctx)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
struct r700_vertex_program *vp
= (struct r700_vertex_program *)ctx->VertexProgram._Current;
struct r700_vertex_program *vp = context->selected_vp;
struct gl_program_parameter_list *paramList;
unsigned int unNumParamData;
unsigned int ui;
if (vp->needUpdateVF)
{
vp->loaded = GL_FALSE;
vp->r700Shader.bNeedsAssembly = GL_TRUE;
Process_Vertex_Program_Vfetch_Instructions(vp, &(vp->mesa_program));
r600DeleteShader(ctx, vp->shaderbo);
}
if(GL_FALSE == vp->loaded)
{
if(vp->r700Shader.bNeedsAssembly == GL_TRUE)
@ -410,7 +447,7 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx)
*/
/* sent out shader constants. */
paramList = vp->mesa_program.Base.Parameters;
paramList = vp->mesa_program->Base.Parameters;
if(NULL != paramList) {
_mesa_load_state_parameters(ctx, paramList);

View File

@ -43,7 +43,7 @@ typedef struct ArrayDesc //TEMP
struct r700_vertex_program
{
struct gl_vertex_program mesa_program; /* Must be first */
struct gl_vertex_program *mesa_program; /* Must be first */
struct r700_vertex_program *next;
@ -59,6 +59,13 @@ struct r700_vertex_program
ArrayDesc aos_desc[VERT_ATTRIB_MAX];
};
struct r700_vertex_program_cont
{
struct gl_vertex_program mesa_program;
struct r700_vertex_program *progs;
};
//Internal
unsigned int Map_Vertex_Output(r700_AssemblerBase *pAsm,
struct gl_vertex_program *mesa_vp,
@ -74,7 +81,7 @@ void Map_Vertex_Program(struct r700_vertex_program *vp,
GLboolean Find_Instruction_Dependencies_vp(struct r700_vertex_program *vp,
struct gl_vertex_program *mesa_vp);
GLboolean r700TranslateVertexShader(struct r700_vertex_program *vp,
struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx,
struct gl_vertex_program *mesa_vp);
/* Interface */