Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / r600 / r700_oglprog.c
1 /*
2  * Copyright (C) 2008-2009  Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20  */
21
22 /*
23  * Authors:
24  *   Richard Li <RichardZ.Li@amd.com>, <richardradeon@gmail.com>
25  */
26
27 #include <string.h>
28
29 #include "main/glheader.h"
30 #include "main/imports.h"
31
32 #include "program/program.h"
33 #include "tnl/tnl.h"
34
35 #include "r600_context.h"
36 #include "r600_emit.h"
37
38 #include "r700_oglprog.h"
39 #include "r700_fragprog.h"
40 #include "r700_vertprog.h"
41
42
43 static void freeVertProgCache(struct gl_context *ctx, struct r700_vertex_program_cont *cache)
44 {
45         struct r700_vertex_program *tmp, *vp = cache->progs;
46
47         while (vp) {
48                 tmp = vp->next;
49                 /* Release DMA region */
50                 r600DeleteShader(ctx, vp->shaderbo);
51
52         if(NULL != vp->constbo0)
53         {
54                     r600DeleteShader(ctx, vp->constbo0);
55         }
56
57                 /* Clean up */
58                 Clean_Up_Assembler(&(vp->r700AsmCode));
59                 Clean_Up_Shader(&(vp->r700Shader));
60                 
61                 _mesa_reference_vertprog(ctx, &vp->mesa_program, NULL);
62                 free(vp);
63                 vp = tmp;
64         }
65 }
66
67 static struct gl_program *r700NewProgram(struct gl_context * ctx, 
68                                          GLenum target,
69                                                              GLuint id)
70 {
71         struct gl_program *pProgram = NULL;
72
73     struct r700_vertex_program_cont *vpc;
74         struct r700_fragment_program *fp;
75
76         radeon_print(RADEON_SHADER, RADEON_VERBOSE,
77                         "%s %u, %u\n", __func__, target, id);
78
79     switch (target) 
80     {
81     case GL_VERTEX_STATE_PROGRAM_NV:
82     case GL_VERTEX_PROGRAM_ARB:     
83         vpc       = CALLOC_STRUCT(r700_vertex_program_cont);
84             pProgram = _mesa_init_vertex_program(ctx, 
85                                              &vpc->mesa_program,
86                                                                  target, 
87                                              id);
88         
89             break;
90     case GL_FRAGMENT_PROGRAM_NV:
91     case GL_FRAGMENT_PROGRAM_ARB:
92                 fp       = CALLOC_STRUCT(r700_fragment_program);
93                 pProgram = _mesa_init_fragment_program(ctx, 
94                                                &fp->mesa_program,
95                                                                        target, 
96                                                id);
97         fp->translated = GL_FALSE;
98         fp->loaded     = GL_FALSE;
99
100         fp->shaderbo   = NULL;
101
102                 fp->constbo0   = NULL;
103
104             break;
105     default:
106             _mesa_problem(ctx, "Bad target in r700NewProgram");
107     }
108
109         return pProgram;
110 }
111
112 static void r700DeleteProgram(struct gl_context * ctx, struct gl_program *prog)
113 {
114     struct r700_vertex_program_cont *vpc = (struct r700_vertex_program_cont *)prog;
115     struct r700_fragment_program * fp;
116
117         radeon_print(RADEON_SHADER, RADEON_VERBOSE,
118                         "%s %p\n", __func__, prog);
119
120     switch (prog->Target) 
121     {
122     case GL_VERTEX_STATE_PROGRAM_NV:
123     case GL_VERTEX_PROGRAM_ARB:     
124             freeVertProgCache(ctx, vpc);
125             break;
126     case GL_FRAGMENT_PROGRAM_NV:
127     case GL_FRAGMENT_PROGRAM_ARB:
128                 fp = (struct r700_fragment_program*)prog;
129         /* Release DMA region */
130
131         r600DeleteShader(ctx, fp->shaderbo);
132
133         if(NULL != fp->constbo0)
134         {
135                     r600DeleteShader(ctx, fp->constbo0);
136         }
137
138         /* Clean up */
139         Clean_Up_Assembler(&(fp->r700AsmCode));
140         Clean_Up_Shader(&(fp->r700Shader));
141             break;
142     default:
143             _mesa_problem(ctx, "Bad target in r700NewProgram");
144     }
145
146         _mesa_delete_program(ctx, prog);
147 }
148
149 static GLboolean
150 r700ProgramStringNotify(struct gl_context * ctx, GLenum target, struct gl_program *prog)
151 {
152         struct r700_vertex_program_cont *vpc = (struct r700_vertex_program_cont *)prog;
153         struct r700_fragment_program * fp = (struct r700_fragment_program*)prog;
154
155         switch (target) {
156         case GL_VERTEX_PROGRAM_ARB:
157                 freeVertProgCache(ctx, vpc);
158                 vpc->progs = NULL;
159                 break;
160         case GL_FRAGMENT_PROGRAM_ARB:
161                 r600DeleteShader(ctx, fp->shaderbo);
162
163         if(NULL != fp->constbo0)
164         {
165                     r600DeleteShader(ctx, fp->constbo0);
166                     fp->constbo0   = NULL;
167         }
168
169                 Clean_Up_Assembler(&(fp->r700AsmCode));
170                 Clean_Up_Shader(&(fp->r700Shader));
171                 fp->translated = GL_FALSE;
172                 fp->loaded     = GL_FALSE;
173                 fp->shaderbo   = NULL;
174                 break;
175         }
176                 
177         /* XXX check if program is legal, within limits */
178         return GL_TRUE;
179 }
180
181 static GLboolean r700IsProgramNative(struct gl_context * ctx, GLenum target, struct gl_program *prog)
182 {
183
184         return GL_TRUE;
185 }
186
187 void r700InitShaderFuncs(struct dd_function_table *functions)
188 {
189         functions->NewProgram = r700NewProgram;
190         functions->DeleteProgram = r700DeleteProgram;
191         functions->ProgramStringNotify = r700ProgramStringNotify;
192         functions->IsProgramNative = r700IsProgramNative;
193 }