shader.cpp revision 36ffccf19c02a54a6dc9952dc9c181d4fda2a020
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "src/pixelflinger2/pixelflinger2.h"
17
18#include <assert.h>
19#include <stdio.h>
20
21#include <llvm/LLVMContext.h>
22
23static gl_shader * ShaderCreate(const GGLInterface * iface, GLenum type)
24{
25    if (GL_VERTEX_SHADER != type && GL_FRAGMENT_SHADER != type)
26    {
27        gglError(GL_INVALID_ENUM);
28        return NULL;
29    }
30//    gl_shader * shader = _mesa_new_shader(0, type);
31//    if(!shader)
32//        gglError(GL_OUT_OF_MEMORY);
33//    return shader;
34    return NULL;
35}
36
37static GLboolean ShaderCompile(const GGLInterface * iface, gl_shader * shader,
38                               const char * glsl, char ** infoLog)
39{
40    GGL_GET_CONST_CONTEXT(ctx, iface);
41    if (!glsl)
42    {
43        gglError(GL_INVALID_VALUE);
44        return GL_FALSE;
45    }
46//    shader->Source = glsl;
47//    _slang_compile(ctx->glCtx, shader);
48//    shader->Source = NULL;
49//    if (infoLog)
50//        *infoLog = shader->InfoLog;
51//    return shader->CompileStatus;
52   return GL_FALSE;
53}
54
55static void ShaderFree(const GGLInterface * iface, gl_shader * shader)
56{
57    GGL_GET_CONST_CONTEXT(ctx, iface);
58//    _mesa_free_shader(ctx->glCtx, shader);
59}
60
61static gl_shader_program * ShaderProgramCreate(const GGLInterface * iface)
62{
63//    gl_shader_program * program = _mesa_new_shader_program(0);
64//    if (!program)
65//        gglError(GL_OUT_OF_MEMORY);
66//    return program;
67   return NULL;
68}
69
70static GLboolean ShaderProgramLink(const GGLInterface * iface, gl_shader_program * program,
71                                   const unsigned count, gl_shader ** shaders, char ** infoLog)
72{
73    GGL_GET_CONST_CONTEXT(ctx, iface);
74
75//    program->NumShaders = count;
76//    program->Shaders = shaders;
77//
78//    _slang_link(ctx->glCtx, program);
79//
80//    program->NumShaders = 0;
81//    program->Shaders = NULL;
82//
83//    if (infoLog)
84//        *infoLog = program->InfoLog;
85//
86//    return program->LinkStatus;
87   return GL_FALSE;
88}
89
90struct gl_program;
91struct ShaderKey;
92
93static void GetShaderKey(const GGLContext * ctx, const gl_program * shader, ShaderKey * key)
94{
95//    memset(key, 0, sizeof(*key));
96//    if (GL_FRAGMENT_SHADER == shader->Target)
97//    {
98//        key->scanLineKey.frontStencil = ctx->frontStencil;
99//        key->scanLineKey.backStencil = ctx->backStencil;
100//        key->scanLineKey.bufferState = ctx->bufferState;
101//        key->scanLineKey.blendState = ctx->blendState;
102//    }
103//
104//    for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++)
105//        if (shader->SamplersUsed & (1 << i))
106//        {
107//            const GGLTexture & texture = ctx->textureState.textures[i];
108//            key->textureFormats[i] = texture.format;
109//            assert((1 << 2) > texture.wrapS);
110//            key->textureParameters[i] |= texture.wrapS;
111//            assert((1 << 2) > texture.wrapT);
112//            key->textureParameters[i] |= texture.wrapT << 2;
113//            assert((1 << 3) > texture.minFilter);
114//            key->textureParameters[i] |= texture.minFilter << (2 + 2);
115//            assert((1 << 1) > texture.magFilter);
116//            key->textureParameters[i] |= texture.magFilter << (2 + 2 + 3);
117//        }
118}
119
120static inline char HexDigit(unsigned char d)
121{
122    return (d > 9 ? d + 'A' - 10 : d + '0');
123}
124
125static const unsigned SHADER_KEY_STRING_LEN = GGL_MAXCOMBINEDTEXTUREIMAGEUNITS * 4 + 2;
126
127static void GetShaderKeyString(const GLenum type, const ShaderKey * key,
128                               char * buffer, const unsigned bufferSize)
129{
130//    assert(1 == sizeof(char));
131//    assert(0xff >= GGL_PIXEL_FORMAT_COUNT);
132//    assert(SHADER_KEY_STRING_LEN <= bufferSize);
133//    char * str = buffer;
134//    if (GL_VERTEX_SHADER == type)
135//        *str++ = 'v';
136//    else if (GL_FRAGMENT_SHADER == type)
137//        *str++ = 'f';
138//    else
139//        assert(0);
140//    for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++)
141//    {
142//        *str++ = HexDigit(key->textureFormats[i] / 16);
143//        *str++ = HexDigit(key->textureFormats[i] % 16);
144//        *str++ = HexDigit(key->textureParameters[i] / 16);
145//        *str++ = HexDigit(key->textureParameters[i] % 16);
146//    }
147//    *str++ = '\0';
148}
149
150//static const unsigned SCANLINE_KEY_STRING_LEN = 2 * sizeof(((ShaderKey *)0)->scanLineKey) +
151//                                            3 + SHADER_KEY_STRING_LEN;
152
153static char * GetScanlineKeyString(const ShaderKey * key, char * buffer,
154                                   const unsigned bufferSize)
155{
156//    assert(1 == sizeof(char));
157//    assert(0xff >= GGL_PIXEL_FORMAT_COUNT);
158//    assert(SCANLINE_KEY_STRING_LEN <= bufferSize);
159//    char * str = buffer;
160//    *str++ = 's';
161//    const unsigned char * start = (const unsigned char *)&key->scanLineKey;
162//    const unsigned char * const end = start + sizeof(key->scanLineKey);
163//    for (; start < end; start++)
164//    {
165//        *str++ = HexDigit(*start / 16);
166//        *str++ = HexDigit(*start % 16);
167//    }
168//    GetShaderKeyString(GL_FRAGMENT_SHADER, key, str, bufferSize - (str - buffer));
169//    return buffer;
170   return NULL;
171}
172
173static void ShaderUse(GGLInterface * iface, gl_shader_program * program)
174{
175    GGL_GET_CONST_CONTEXT(ctx, iface);
176    assert(program);
177    if (!program)
178    {
179//        ctx->glCtx->Shader.CurrentProgram = NULL;
180        // so drawing calls will do nothing until ShaderUse with a program
181        SetShaderVerifyFunctions(iface);
182        return;
183    }
184
185//    if (program->VertexProgram)
186//    {
187//        if (!program->STVP)
188//        {
189//            program->STVP = CALLOC_STRUCT(st_vertex_program);
190//            program->STVP->Base = *program->VertexProgram;
191//            st_translate_vertex_program(ctx->glCtx, program->STVP, NULL, NULL, NULL);
192//        }
193//
194//        _mesa_update_shader_textures_used(program->VertexProgram);
195//
196//        ShaderKey shaderKey;
197//        GetShaderKey(ctx, program->VertexProgram, &shaderKey);
198//        ShaderFunction_t function = NULL;
199//        if (!program->GLVMVP || NULL == (function = program->GLVMVP->functions[shaderKey]))
200//        {
201//            char shaderName [SHADER_KEY_STRING_LEN] = {0};
202//            GetShaderKeyString(GL_VERTEX_SHADER, &shaderKey, shaderName, Elements(shaderName));
203//            create_program(program->STVP->state.tokens, GALLIVM_VS, &program->GLVMVP,
204//                           &ctx->glCtx->Shader.cpu, ctx, program->VertexProgram,
205//                           shaderName, NULL);
206//            program->GLVMVP->functions[shaderKey] = program->GLVMVP->function;
207//            debug_printf("jit new vertex shader %p \n", program->GLVMVP->function); //getchar();
208//        }
209//        else
210//        {
211//            program->GLVMVP->function = function;
212//            //debug_printf("use cached vertex shader %p \n", function);
213//        }
214//        ctx->PickRaster(iface);
215//    }
216//    if (program->FragmentProgram)
217//    {
218//        if (!program->STFP)
219//        {
220//            program->STFP = CALLOC_STRUCT(st_fragment_program);
221//            program->STFP->Base = *program->FragmentProgram;
222//            st_translate_fragment_program(ctx->glCtx, program->STFP, NULL);
223//        }
224//
225//        _mesa_update_shader_textures_used(program->FragmentProgram);
226//
227//        ShaderKey shaderKey;
228//        GetShaderKey(ctx, program->FragmentProgram, &shaderKey);
229//        ShaderFunction_t function = NULL;
230//        if (!program->GLVMFP || NULL == (function = program->GLVMFP->functions[shaderKey]))
231//        {
232//            char shaderName [SHADER_KEY_STRING_LEN] = {0};
233//            GetShaderKeyString(GL_FRAGMENT_SHADER, &shaderKey, shaderName, Elements(shaderName));
234//
235//            char scanlineName [SCANLINE_KEY_STRING_LEN] = {0};
236//            GetScanlineKeyString(&shaderKey, scanlineName, Elements(scanlineName));
237//            create_program(program->STFP->state.tokens, GALLIVM_FS,  &program->GLVMFP,
238//                           &ctx->glCtx->Shader.cpu, ctx, program->FragmentProgram,
239//                           shaderName, scanlineName);
240//            program->GLVMFP->functions[shaderKey] = program->GLVMFP->function;
241//            debug_printf("jit new fragment shader %p \n", program->GLVMFP->function);
242//        }
243//        else
244//        {
245//            program->GLVMFP->function = function;
246//            //debug_printf("use cached fragment shader %p \n", function);
247//        }
248//        ctx->PickScanLine(iface);
249//    }
250//    ctx->glCtx->Shader.CurrentProgram = program;
251}
252
253static void ShaderProgramFree(const GGLInterface * iface, gl_shader_program * program)
254{
255    GGL_GET_CONST_CONTEXT(ctx, iface);
256//    if (ctx->glCtx->Shader.CurrentProgram == program)
257//    {
258//        ctx->glCtx->Shader.CurrentProgram = NULL;
259//        SetShaderVerifyFunctions(const_cast<GGLInterface *>(iface));
260//    }
261//    assert(program);
262//    if (program->GLVMVP)
263//        gallivm_prog_delete(ctx->glCtx->Shader.cpu, program->GLVMVP);
264//    program->GLVMVP = NULL;
265//    if (program->GLVMFP)
266//        gallivm_prog_delete(ctx->glCtx->Shader.cpu, program->GLVMFP);
267//    program->GLVMFP = NULL;
268//    SAFE_FREE(program->STVP);
269//    SAFE_FREE(program->STFP);
270//    _mesa_free_shader_program(ctx->glCtx, program);
271}
272
273static void ShaderAttributeBind(const GGLInterface * iface, const gl_shader_program * program,
274                               GLuint index, const GLchar * name)
275{
276    GGL_GET_CONST_CONTEXT(ctx, iface);
277//    _mesa_bind_attrib_location(ctx->glCtx, program, index, name, DEFAULTP);
278}
279
280static GLint ShaderAttributeLocation(const GGLInterface * iface, const gl_shader_program * program,
281                                     const char * name)
282{
283    GGL_GET_CONST_CONTEXT(ctx, iface);
284//    return _mesa_get_attrib_location(ctx->glCtx, program, name);
285   return -2;
286}
287
288static GLint ShaderUniformLocation(const GGLInterface * iface, const gl_shader_program * program,
289                                   const char * name)
290{
291    GGL_GET_CONST_CONTEXT(ctx, iface);
292//    return _mesa_get_shader_uniform_location(ctx->glCtx, program, name);
293   return -2;
294}
295
296static void ShaderUniformGetfv(const GGLInterface * iface, gl_shader_program * program,
297                               GLint location, GLfloat * params)
298{
299    GGL_GET_CONST_CONTEXT(ctx, iface);
300//    _mesa_get_uniformfv(ctx->glCtx, program, location, params);
301}
302
303static void ShaderUniformGetiv(const GGLInterface * iface, gl_shader_program * program,
304                               GLint location, GLint * params)
305{
306    GGL_GET_CONST_CONTEXT(ctx, iface);
307//    _mesa_get_uniformiv(ctx->glCtx, program, location, params);
308}
309
310static GLint ShaderUniform(const GGLInterface * iface, gl_shader_program * program,
311                          GLint location, GLsizei count, const GLvoid *values, GLenum type)
312{
313    GGL_GET_CONST_CONTEXT(ctx, iface);
314//    if (!program)
315//    {
316//        gglError(GL_INVALID_OPERATION);
317//        return -2;
318//    }
319//    return _mesa_uniform(ctx->glCtx, program, location, count, values, type);
320   return -2;
321}
322
323static void ShaderUniformMatrix(const GGLInterface * iface, gl_shader_program * program,
324                                GLint cols, GLint rows, GLint location, GLsizei count,
325                                GLboolean transpose, const GLfloat *values)
326{
327    GGL_GET_CONST_CONTEXT(ctx, iface);
328//    if (!program)
329//        return gglError(GL_INVALID_OPERATION);
330//    _mesa_uniform_matrix(ctx->glCtx, program, cols, rows, location, count, transpose, values);
331}
332
333static void ShaderVerifyProcessVertex(const GGLInterface * iface, const VertexInput * input,
334                                      VertexOutput * output)
335{
336    GGL_GET_CONST_CONTEXT(ctx, iface);
337//    if (ctx->glCtx->Shader.CurrentProgram)
338//    {
339//        ShaderUse(const_cast<GGLInterface *>(iface), ctx->glCtx->Shader.CurrentProgram);
340//        if (ShaderVerifyProcessVertex != iface->ProcessVertex)
341//            iface->ProcessVertex(iface, input, output);
342//    }
343}
344
345static void ShaderVerifyDrawTriangle(const GGLInterface * iface, const VertexInput * v0,
346                                     const VertexInput * v1, const VertexInput * v2)
347{
348//    GGL_GET_CONST_CONTEXT(ctx, iface);
349//    if (ctx->glCtx->Shader.CurrentProgram)
350//    {
351//        ShaderUse(const_cast<GGLInterface *>(iface), ctx->glCtx->Shader.CurrentProgram);
352//        if (ShaderVerifyDrawTriangle != iface->DrawTriangle)
353//            iface->DrawTriangle(iface, v0, v1, v2);
354//    }
355}
356
357static void ShaderVerifyRasterTriangle(const GGLInterface * iface, const VertexOutput * v1,
358                                       const VertexOutput * v2, const VertexOutput * v3)
359{
360//    GGL_GET_CONST_CONTEXT(ctx, iface);
361//    if (ctx->glCtx->Shader.CurrentProgram)
362//    {
363//        ShaderUse(const_cast<GGLInterface *>(iface), ctx->glCtx->Shader.CurrentProgram);
364//        if (ShaderVerifyRasterTriangle != iface->RasterTriangle)
365//            iface->RasterTriangle(iface, v1, v2, v3);
366//    }
367}
368
369static void ShaderVerifyRasterTrapezoid(const GGLInterface * iface, const VertexOutput * tl,
370                                        const VertexOutput * tr, const VertexOutput * bl,
371                                        const VertexOutput * br)
372{
373    GGL_GET_CONST_CONTEXT(ctx, iface);
374//    if (ctx->glCtx->Shader.CurrentProgram)
375//    {
376//        ShaderUse(const_cast<GGLInterface *>(iface), ctx->glCtx->Shader.CurrentProgram);
377//        if (ShaderVerifyRasterTrapezoid != iface->RasterTrapezoid)
378//            iface->RasterTrapezoid(iface, tl, tr, bl, br);
379//    }
380}
381
382static void ShaderVerifyScanLine(const GGLInterface * iface, const VertexOutput * v1,
383                                 const VertexOutput * v2)
384{
385    GGL_GET_CONST_CONTEXT(ctx, iface);
386//    if (ctx->glCtx->Shader.CurrentProgram)
387//    {
388//        ShaderUse(const_cast<GGLInterface *>(iface), ctx->glCtx->Shader.CurrentProgram);
389//        if (ShaderVerifyScanLine != iface->ScanLine)
390//            iface->ScanLine(iface, v1, v2);
391//    }
392}
393
394// called after state changes so that drawing calls will trigger JIT
395void SetShaderVerifyFunctions(struct GGLInterface * iface)
396{
397    iface->ProcessVertex = ShaderVerifyProcessVertex;
398    iface->DrawTriangle = ShaderVerifyDrawTriangle;
399    iface->RasterTriangle = ShaderVerifyRasterTriangle;
400    iface->RasterTrapezoid = ShaderVerifyRasterTrapezoid;
401    iface->ScanLine = ShaderVerifyScanLine;
402}
403
404void InitializeShaderFunctions(struct GGLInterface * iface)
405{
406    GGL_GET_CONTEXT(ctx, iface);
407    ctx->llvmCtx = new llvm::LLVMContext();
408
409    iface->ShaderCreate = ShaderCreate;
410    iface->ShaderCompile = ShaderCompile;
411    iface->ShaderFree = ShaderFree;
412    iface->ShaderProgramCreate = ShaderProgramCreate;
413    iface->ShaderProgramLink = ShaderProgramLink;
414    iface->ShaderUse = ShaderUse;
415    iface->ShaderProgramFree = ShaderProgramFree;
416    iface->ShaderAttributeBind = ShaderAttributeBind;
417    iface->ShaderAttributeLocation = ShaderAttributeLocation;
418    iface->ShaderUniformLocation = ShaderUniformLocation;
419    iface->ShaderUniformGetfv = ShaderUniformGetfv;
420    iface->ShaderUniformGetiv = ShaderUniformGetiv;
421    iface->ShaderUniform = ShaderUniform;
422    iface->ShaderUniformMatrix = ShaderUniformMatrix;
423}
424
425void DestroyShaderFunctions(GGLInterface * iface)
426{
427    GGL_GET_CONTEXT(ctx, iface);
428//    if (ctx->glCtx->Shader.cpu)
429//    {
430//        gallivm_cpu_engine_delete(ctx->glCtx->Shader.cpu);
431//        ctx->glCtx->Shader.cpu = NULL;
432//    }
433//    SAFE_DELETE(ctx->llvmCtx);
434}