X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Farbprogram.c;h=911b6fa3960472148311efd18daca655d6459e34;hb=b9b88516f8d3efc902696f1092519e298ceb7cdb;hp=8150b5f4ec1ddedd2b5468c4f5c3b536e1e37d6d;hpb=1a1db1746db82efc7f0643508886dfc78a15eb71;p=mesa.git diff --git a/src/mesa/main/arbprogram.c b/src/mesa/main/arbprogram.c index 8150b5f4ec1..911b6fa3960 100644 --- a/src/mesa/main/arbprogram.c +++ b/src/mesa/main/arbprogram.c @@ -1,6 +1,5 @@ /* * Mesa 3-D graphics library - * Version: 7.0 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -17,9 +16,10 @@ * 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 - * BRIAN PAUL 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. + * THE AUTHORS OR COPYRIGHT HOLDERS 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. */ /** @@ -36,9 +36,15 @@ #include "main/macros.h" #include "main/mtypes.h" #include "main/arbprogram.h" +#include "main/shaderapi.h" #include "program/arbprogparse.h" #include "program/program.h" +#include "program/prog_print.h" +#ifdef _MSC_VER +#include +#define PATH_MAX _MAX_PATH +#endif /** * Bind a program (make it current) @@ -50,7 +56,6 @@ _mesa_BindProgramARB(GLenum target, GLuint id) { struct gl_program *curProg, *newProg; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); /* Error-check target and get curProg */ if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) { @@ -118,8 +123,8 @@ _mesa_BindProgramARB(GLenum target, GLuint id) } /* Never null pointers */ - ASSERT(ctx->VertexProgram.Current); - ASSERT(ctx->FragmentProgram.Current); + assert(ctx->VertexProgram.Current); + assert(ctx->FragmentProgram.Current); if (ctx->Driver.BindProgram) ctx->Driver.BindProgram(ctx, target, newProg); @@ -136,7 +141,8 @@ _mesa_DeleteProgramsARB(GLsizei n, const GLuint *ids) { GLint i; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + FLUSH_VERTICES(ctx, 0); if (n < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glDeleteProgramsNV" ); @@ -190,7 +196,6 @@ _mesa_GenProgramsARB(GLsizei n, GLuint *ids) GLuint first; GLuint i; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (n < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGenPrograms"); @@ -200,13 +205,18 @@ _mesa_GenProgramsARB(GLsizei n, GLuint *ids) if (!ids) return; + _mesa_HashLockMutex(ctx->Shared->Programs); + first = _mesa_HashFindFreeKeyBlock(ctx->Shared->Programs, n); /* Insert pointer to dummy program as placeholder */ for (i = 0; i < (GLuint) n; i++) { - _mesa_HashInsert(ctx->Shared->Programs, first + i, &_mesa_DummyProgram); + _mesa_HashInsertLocked(ctx->Shared->Programs, first + i, + &_mesa_DummyProgram); } + _mesa_HashUnlockMutex(ctx->Shared->Programs); + /* Return the program names */ for (i = 0; i < (GLuint) n; i++) { ids[i] = first + i; @@ -248,12 +258,12 @@ get_local_param_pointer(struct gl_context *ctx, const char *func, if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) { prog = &(ctx->VertexProgram.Current->Base); - maxParams = ctx->Const.VertexProgram.MaxLocalParams; + maxParams = ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams; } else if (target == GL_FRAGMENT_PROGRAM_ARB && ctx->Extensions.ARB_fragment_program) { prog = &(ctx->FragmentProgram.Current->Base); - maxParams = ctx->Const.FragmentProgram.MaxLocalParams; + maxParams = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams; } else { _mesa_error(ctx, GL_INVALID_ENUM, @@ -266,6 +276,12 @@ get_local_param_pointer(struct gl_context *ctx, const char *func, return GL_FALSE; } + if (!prog->LocalParams) { + prog->LocalParams = calloc(maxParams, sizeof(float[4])); + if (!prog->LocalParams) + return GL_FALSE; + } + *param = prog->LocalParams[index]; return GL_TRUE; } @@ -277,7 +293,7 @@ get_env_param_pointer(struct gl_context *ctx, const char *func, { if (target == GL_FRAGMENT_PROGRAM_ARB && ctx->Extensions.ARB_fragment_program) { - if (index >= ctx->Const.FragmentProgram.MaxEnvParams) { + if (index >= ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxEnvParams) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func); return GL_FALSE; } @@ -286,7 +302,7 @@ get_env_param_pointer(struct gl_context *ctx, const char *func, } else if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) { - if (index >= ctx->Const.VertexProgram.MaxEnvParams) { + if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxEnvParams) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func); return GL_FALSE; } @@ -303,8 +319,8 @@ _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len, const GLvoid *string) { struct gl_program *base; + bool failed; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_PROGRAM); @@ -337,13 +353,57 @@ _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len, return; } - if (ctx->Program.ErrorPos == -1) { + failed = ctx->Program.ErrorPos != -1; + + if (!failed) { /* finally, give the program to the driver for translation/checking */ if (!ctx->Driver.ProgramStringNotify(ctx, target, base)) { + failed = true; _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramStringARB(rejected by driver"); } } + + if (ctx->_Shader->Flags & GLSL_DUMP) { + const char *shader_type = + target == GL_FRAGMENT_PROGRAM_ARB ? "fragment" : "vertex"; + + fprintf(stderr, "ARB_%s_program source for program %d:\n", + shader_type, base->Id); + fprintf(stderr, "%s\n", (const char *) string); + + if (failed) { + fprintf(stderr, "ARB_%s_program %d failed to compile.\n", + shader_type, base->Id); + } else { + fprintf(stderr, "Mesa IR for ARB_%s_program %d:\n", + shader_type, base->Id); + _mesa_print_program(base); + fprintf(stderr, "\n"); + } + fflush(stderr); + } + + /* Capture vp-*.shader_test/fp-*.shader_test files. */ + const char *capture_path = _mesa_get_shader_capture_path(); + if (capture_path != NULL) { + FILE *file; + char filename[PATH_MAX]; + const char *shader_type = + target == GL_FRAGMENT_PROGRAM_ARB ? "fragment" : "vertex"; + + _mesa_snprintf(filename, sizeof(filename), "%s/%cp-%u.shader_test", + capture_path, shader_type[0], base->Id); + file = fopen(filename, "w"); + if (file) { + fprintf(file, + "[require]\nGL_ARB_%s_program\n\n[%s program]\n%s\n", + shader_type, shader_type, (const char *) string); + fclose(file); + } else { + _mesa_warning(ctx, "Failed to open %s", filename); + } + } } @@ -385,7 +445,6 @@ _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat *param; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); @@ -408,7 +467,6 @@ _mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index, GLfloat *param; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); @@ -425,7 +483,6 @@ _mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, { GET_CURRENT_CONTEXT(ctx); GLfloat * dest; - ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); @@ -435,7 +492,7 @@ _mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, if (target == GL_FRAGMENT_PROGRAM_ARB && ctx->Extensions.ARB_fragment_program) { - if ((index + count) > ctx->Const.FragmentProgram.MaxEnvParams) { + if ((index + count) > ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxEnvParams) { _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)"); return; } @@ -443,7 +500,7 @@ _mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, } else if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) { - if ((index + count) > ctx->Const.VertexProgram.MaxEnvParams) { + if ((index + count) > ctx->Const.Program[MESA_SHADER_VERTEX].MaxEnvParams) { _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)"); return; } @@ -480,8 +537,6 @@ _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index, GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - if (get_env_param_pointer(ctx, "glGetProgramEnvParameterfv", target, index, ¶m)) { COPY_4V(params, param); @@ -495,13 +550,12 @@ _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index, { GET_CURRENT_CONTEXT(ctx); GLfloat *param; - ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); if (get_local_param_pointer(ctx, "glProgramLocalParameterARB", target, index, ¶m)) { - ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS); + assert(index < MAX_PROGRAM_LOCAL_PARAMS); ASSIGN_4V(param, x, y, z, w); } } @@ -522,7 +576,6 @@ _mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, { GET_CURRENT_CONTEXT(ctx); GLfloat *dest; - ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); @@ -530,28 +583,20 @@ _mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fv(count)"); } - if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program) { - if ((index + count) > ctx->Const.FragmentProgram.MaxLocalParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)"); - return; - } - dest = ctx->FragmentProgram.Current->Base.LocalParams[index]; - } - else if (target == GL_VERTEX_PROGRAM_ARB - && ctx->Extensions.ARB_vertex_program) { - if ((index + count) > ctx->Const.VertexProgram.MaxLocalParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)"); + if (get_local_param_pointer(ctx, "glProgramLocalParameters4fvEXT", + target, index, &dest)) { + GLuint maxParams = target == GL_FRAGMENT_PROGRAM_ARB ? + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams : + ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams; + + if ((index + count) > maxParams) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glProgramLocalParameters4fvEXT(index + count)"); return; } - dest = ctx->VertexProgram.Current->Base.LocalParams[index]; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameters4fvEXT(target)"); - return; - } - memcpy(dest, params, count * 4 * sizeof(GLfloat)); + memcpy(dest, params, count * 4 * sizeof(GLfloat)); + } } @@ -581,7 +626,6 @@ _mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index, { GLfloat *param; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (get_local_param_pointer(ctx, "glProgramLocalParameters4fvEXT", target, index, ¶m)) { @@ -596,7 +640,6 @@ _mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index, { GLfloat *param; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (get_local_param_pointer(ctx, "glProgramLocalParameters4fvEXT", target, index, ¶m)) { @@ -612,25 +655,23 @@ _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params) struct gl_program *prog; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) { prog = &(ctx->VertexProgram.Current->Base); - limits = &ctx->Const.VertexProgram; + limits = &ctx->Const.Program[MESA_SHADER_VERTEX]; } else if (target == GL_FRAGMENT_PROGRAM_ARB && ctx->Extensions.ARB_fragment_program) { prog = &(ctx->FragmentProgram.Current->Base); - limits = &ctx->Const.FragmentProgram; + limits = &ctx->Const.Program[MESA_SHADER_FRAGMENT]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); return; } - ASSERT(prog); - ASSERT(limits); + assert(prog); + assert(limits); /* Queries supported for both vertex and fragment programs */ switch (pname) { @@ -796,8 +837,6 @@ _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string) char *dst = (char *) string; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - if (target == GL_VERTEX_PROGRAM_ARB) { prog = &(ctx->VertexProgram.Current->Base); } @@ -809,7 +848,7 @@ _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string) return; } - ASSERT(prog); + assert(prog); if (pname != GL_PROGRAM_STRING_ARB) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");