diff options
Diffstat (limited to 'src/mesa/drivers/dri/r600/evergreen_oglprog.c')
-rw-r--r-- | src/mesa/drivers/dri/r600/evergreen_oglprog.c | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/r600/evergreen_oglprog.c b/src/mesa/drivers/dri/r600/evergreen_oglprog.c new file mode 100644 index 00000000000..9fe523234cc --- /dev/null +++ b/src/mesa/drivers/dri/r600/evergreen_oglprog.c @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2008-2009 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Authors: + * Richard Li <[email protected]>, <[email protected]> + */ + +#include <string.h> + +#include "main/glheader.h" +#include "main/imports.h" +#include "program/program.h" + +#include "tnl/tnl.h" + +#include "r600_context.h" +#include "r600_emit.h" + +#include "evergreen_oglprog.h" +#include "evergreen_fragprog.h" +#include "evergreen_vertprog.h" + + +static void evergreen_freeVertProgCache(GLcontext *ctx, struct r700_vertex_program_cont *cache) +{ + struct evergreen_vertex_program *tmp, *vp = cache->progs; + + while (vp) { + tmp = vp->next; + /* Release DMA region */ + r600DeleteShader(ctx, vp->shaderbo); + + if(NULL != vp->constbo0) + { + r600DeleteShader(ctx, vp->constbo0); + } + + /* Clean up */ + Clean_Up_Assembler(&(vp->r700AsmCode)); + Clean_Up_Shader(&(vp->r700Shader)); + + _mesa_reference_vertprog(ctx, &vp->mesa_program, NULL); + free(vp); + vp = tmp; + } +} + +static struct gl_program *evergreenNewProgram(GLcontext * ctx, + GLenum target, + GLuint id) +{ + struct gl_program *pProgram = NULL; + + struct evergreen_vertex_program_cont *vpc; + struct evergreen_fragment_program *fp; + + radeon_print(RADEON_SHADER, RADEON_VERBOSE, + "%s %u, %u\n", __func__, target, id); + + switch (target) + { + case GL_VERTEX_STATE_PROGRAM_NV: + case GL_VERTEX_PROGRAM_ARB: + vpc = CALLOC_STRUCT(evergreen_vertex_program_cont); + pProgram = _mesa_init_vertex_program(ctx, + &vpc->mesa_program, + target, + id); + + break; + case GL_FRAGMENT_PROGRAM_NV: + case GL_FRAGMENT_PROGRAM_ARB: + fp = CALLOC_STRUCT(evergreen_fragment_program); + pProgram = _mesa_init_fragment_program(ctx, + &fp->mesa_program, + target, + id); + fp->translated = GL_FALSE; + fp->loaded = GL_FALSE; + + fp->shaderbo = NULL; + + fp->constbo0 = NULL; + + break; + default: + _mesa_problem(ctx, "Bad target in evergreenNewProgram"); + } + + return pProgram; +} + +static void evergreenDeleteProgram(GLcontext * ctx, struct gl_program *prog) +{ + struct evergreen_vertex_program_cont *vpc = (struct evergreen_vertex_program_cont *)prog; + struct evergreen_fragment_program * fp; + + radeon_print(RADEON_SHADER, RADEON_VERBOSE, + "%s %p\n", __func__, prog); + + switch (prog->Target) + { + case GL_VERTEX_STATE_PROGRAM_NV: + case GL_VERTEX_PROGRAM_ARB: + evergreen_freeVertProgCache(ctx, vpc); + break; + case GL_FRAGMENT_PROGRAM_NV: + case GL_FRAGMENT_PROGRAM_ARB: + fp = (struct evergreen_fragment_program*)prog; + /* Release DMA region */ + + r600DeleteShader(ctx, fp->shaderbo); + + if(NULL != fp->constbo0) + { + r600DeleteShader(ctx, fp->constbo0); + } + + /* Clean up */ + Clean_Up_Assembler(&(fp->r700AsmCode)); + Clean_Up_Shader(&(fp->r700Shader)); + break; + default: + _mesa_problem(ctx, "Bad target in evergreenNewProgram"); + } + + _mesa_delete_program(ctx, prog); +} + +static GLboolean +evergreenProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) +{ + struct evergreen_vertex_program_cont *vpc = (struct evergreen_vertex_program_cont *)prog; + struct evergreen_fragment_program * fp = (struct evergreen_fragment_program*)prog; + + switch (target) { + case GL_VERTEX_PROGRAM_ARB: + evergreen_freeVertProgCache(ctx, vpc); + vpc->progs = NULL; + break; + case GL_FRAGMENT_PROGRAM_ARB: + r600DeleteShader(ctx, fp->shaderbo); + + if(NULL != fp->constbo0) + { + r600DeleteShader(ctx, fp->constbo0); + fp->constbo0 = NULL; + } + + Clean_Up_Assembler(&(fp->r700AsmCode)); + Clean_Up_Shader(&(fp->r700Shader)); + fp->translated = GL_FALSE; + fp->loaded = GL_FALSE; + fp->shaderbo = NULL; + break; + } + + /* XXX check if program is legal, within limits */ + return GL_TRUE; +} + +static GLboolean evergreenIsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) +{ + + return GL_TRUE; +} + +void evergreenInitShaderFuncs(struct dd_function_table *functions) +{ + functions->NewProgram = evergreenNewProgram; + functions->DeleteProgram = evergreenDeleteProgram; + functions->ProgramStringNotify = evergreenProgramStringNotify; + functions->IsProgramNative = evergreenIsProgramNative; +} |