draw: corrections to allow for different cliptest cases
[mesa.git] / src / mesa / drivers / dri / r600 / evergreen_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 #include "program/program.h"
32
33 #include "tnl/tnl.h"
34
35 #include "r600_context.h"
36 #include "r600_emit.h"
37
38 #include "evergreen_oglprog.h"
39 #include "evergreen_fragprog.h"
40 #include "evergreen_vertprog.h"
41
42
43 static void evergreen_freeVertProgCache(GLcontext *ctx, struct r700_vertex_program_cont *cache)
44 {
45 struct evergreen_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 *evergreenNewProgram(GLcontext * ctx,
68 GLenum target,
69 GLuint id)
70 {
71 struct gl_program *pProgram = NULL;
72
73 struct evergreen_vertex_program_cont *vpc;
74 struct evergreen_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(evergreen_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(evergreen_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 evergreenNewProgram");
107 }
108
109 return pProgram;
110 }
111
112 static void evergreenDeleteProgram(GLcontext * ctx, struct gl_program *prog)
113 {
114 struct evergreen_vertex_program_cont *vpc = (struct evergreen_vertex_program_cont *)prog;
115 struct evergreen_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 evergreen_freeVertProgCache(ctx, vpc);
125 break;
126 case GL_FRAGMENT_PROGRAM_NV:
127 case GL_FRAGMENT_PROGRAM_ARB:
128 fp = (struct evergreen_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 evergreenNewProgram");
144 }
145
146 _mesa_delete_program(ctx, prog);
147 }
148
149 static GLboolean
150 evergreenProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
151 {
152 struct evergreen_vertex_program_cont *vpc = (struct evergreen_vertex_program_cont *)prog;
153 struct evergreen_fragment_program * fp = (struct evergreen_fragment_program*)prog;
154
155 switch (target) {
156 case GL_VERTEX_PROGRAM_ARB:
157 evergreen_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 evergreenIsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
182 {
183
184 return GL_TRUE;
185 }
186
187 void evergreenInitShaderFuncs(struct dd_function_table *functions)
188 {
189 functions->NewProgram = evergreenNewProgram;
190 functions->DeleteProgram = evergreenDeleteProgram;
191 functions->ProgramStringNotify = evergreenProgramStringNotify;
192 functions->IsProgramNative = evergreenIsProgramNative;
193 }