r600: enable caching of vertex programs
This commit is contained in:
parent
6552a103f9
commit
9edd1a441c
|
@ -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];
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,7 +95,10 @@ 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;
|
||||
vpc = (struct r700_vertex_program_cont*)prog;
|
||||
vp = vpc->progs;
|
||||
while (vp) {
|
||||
tmp = vp->next;
|
||||
/* Release DMA region */
|
||||
|
||||
r600DeleteShader(ctx, vp->shaderbo);
|
||||
|
@ -107,6 +106,9 @@ static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog)
|
|||
/* 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:
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 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 (match)
|
||||
{
|
||||
context->selected_vp = vp;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(GL_FALSE == vpc->translated) {
|
||||
r700TranslateVertexShader(vpc, &(vpc->mesa_program) );
|
||||
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;;
|
||||
|
||||
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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue