mojoshader_opengl.c
changeset 1090 636ffcd3f14a
parent 1073 6eccf031c7e6
child 1104 9147482e1ec7
equal deleted inserted replaced
1089:b965d0942dff 1090:636ffcd3f14a
    79     MOJOSHADER_glShader *vertex;
    79     MOJOSHADER_glShader *vertex;
    80     MOJOSHADER_glShader *fragment;
    80     MOJOSHADER_glShader *fragment;
    81     GLuint handle;
    81     GLuint handle;
    82     uint32 generation;
    82     uint32 generation;
    83     uint32 uniform_count;
    83     uint32 uniform_count;
       
    84     uint32 texbem_count;
    84     UniformMap *uniforms;
    85     UniformMap *uniforms;
    85     uint32 attribute_count;
    86     uint32 attribute_count;
    86     AttributeMap *attributes;
    87     AttributeMap *attributes;
    87     size_t vs_uniforms_float4_count;
    88     size_t vs_uniforms_float4_count;
    88     GLfloat *vs_uniforms_float4;
    89     GLfloat *vs_uniforms_float4;
   128 
   129 
   129 // Max entries for each register file type...
   130 // Max entries for each register file type...
   130 #define MAX_REG_FILE_F 8192
   131 #define MAX_REG_FILE_F 8192
   131 #define MAX_REG_FILE_I 2047
   132 #define MAX_REG_FILE_I 2047
   132 #define MAX_REG_FILE_B 2047
   133 #define MAX_REG_FILE_B 2047
       
   134 #define MAX_TEXBEMS 3  // ps_1_1 allows 4 texture stages, texbem can't use t0.
   133 
   135 
   134 struct MOJOSHADER_glContext
   136 struct MOJOSHADER_glContext
   135 {
   137 {
   136     // Allocators...
   138     // Allocators...
   137     MOJOSHADER_malloc malloc_fn;
   139     MOJOSHADER_malloc malloc_fn;
   146     uint8 vs_reg_file_b[MAX_REG_FILE_B];
   148     uint8 vs_reg_file_b[MAX_REG_FILE_B];
   147     GLfloat ps_reg_file_f[MAX_REG_FILE_F * 4];
   149     GLfloat ps_reg_file_f[MAX_REG_FILE_F * 4];
   148     GLint ps_reg_file_i[MAX_REG_FILE_I * 4];
   150     GLint ps_reg_file_i[MAX_REG_FILE_I * 4];
   149     uint8 ps_reg_file_b[MAX_REG_FILE_B];
   151     uint8 ps_reg_file_b[MAX_REG_FILE_B];
   150     GLuint sampler_reg_file[16];
   152     GLuint sampler_reg_file[16];
       
   153     GLfloat texbem_state[MAX_TEXBEMS * 6];
   151 
   154 
   152     // This increments every time we change the register files.
   155     // This increments every time we change the register files.
   153     uint32 generation;
   156     uint32 generation;
   154 
   157 
   155     // This keeps track of implicitly linked programs.
   158     // This keeps track of implicitly linked programs.
   767     const uint32 count = program->uniform_count;
   770     const uint32 count = program->uniform_count;
   768     const GLfloat *srcf = program->vs_uniforms_float4;
   771     const GLfloat *srcf = program->vs_uniforms_float4;
   769     const GLint *srci = program->vs_uniforms_int4;
   772     const GLint *srci = program->vs_uniforms_int4;
   770     const GLint *srcb = program->vs_uniforms_bool;
   773     const GLint *srcb = program->vs_uniforms_bool;
   771     GLint loc = 0;
   774     GLint loc = 0;
       
   775     GLint texbem_loc = 0;
   772     uint32 i;
   776     uint32 i;
   773 
   777 
   774     assert(count > 0);  // shouldn't call this with nothing to do!
   778     assert(count > 0);  // shouldn't call this with nothing to do!
   775 
   779 
   776     for (i = 0; i < count; i++)
   780     for (i = 0; i < count; i++)
   784         assert(!u->constant);
   788         assert(!u->constant);
   785 
   789 
   786         // Did we switch from vertex to pixel (to geometry, etc)?
   790         // Did we switch from vertex to pixel (to geometry, etc)?
   787         if (shader_type != uniform_shader_type)
   791         if (shader_type != uniform_shader_type)
   788         {
   792         {
       
   793             if (shader_type == MOJOSHADER_TYPE_PIXEL)
       
   794                 texbem_loc = loc;
       
   795 
   789             // we start with vertex, move to pixel, then to geometry, etc.
   796             // we start with vertex, move to pixel, then to geometry, etc.
   790             //  The array should always be sorted as such.
   797             //  The array should always be sorted as such.
   791             if (uniform_shader_type == MOJOSHADER_TYPE_PIXEL)
   798             if (uniform_shader_type == MOJOSHADER_TYPE_PIXEL)
   792             {
   799             {
   793                 assert(shader_type == MOJOSHADER_TYPE_VERTEX);
   800                 assert(shader_type == MOJOSHADER_TYPE_VERTEX);
   855                     ctx->glProgramLocalParameter4fvARB(arb_shader_type, loc, fv);
   862                     ctx->glProgramLocalParameter4fvARB(arb_shader_type, loc, fv);
   856                 } // for
   863                 } // for
   857             } // else
   864             } // else
   858         } // else if
   865         } // else if
   859     } // for
   866     } // for
       
   867 
       
   868     if (program->texbem_count)
       
   869     {
       
   870         const GLenum target = GL_FRAGMENT_PROGRAM_ARB;
       
   871         GLfloat *srcf = program->ps_uniforms_float4;
       
   872         srcf += (program->ps_uniforms_float4_count * 4) -
       
   873                 (program->texbem_count * 8);
       
   874         loc = texbem_loc;
       
   875         for (i = 0; i < program->texbem_count; i++, srcf += 8)
       
   876         {
       
   877             ctx->glProgramLocalParameter4fvARB(target, loc++, srcf);
       
   878             ctx->glProgramLocalParameter4fvARB(target, loc++, srcf + 4);
       
   879         } // for
       
   880     } // if
   860 } // impl_ARB1_PushUniforms
   881 } // impl_ARB1_PushUniforms
   861 
   882 
   862 static void impl_ARB1_PushSampler(GLint loc, GLuint sampler)
   883 static void impl_ARB1_PushSampler(GLint loc, GLuint sampler)
   863 {
   884 {
   864     // no-op in this profile...arb1 uses the texture units as-is.
   885     // no-op in this profile...arb1 uses the texture units as-is.
  1537                     assert(0 && "Unexpected register type");
  1558                     assert(0 && "Unexpected register type");
  1538             } // if
  1559             } // if
  1539         } // else
  1560         } // else
  1540     } // for
  1561     } // for
  1541 
  1562 
       
  1563     if (shader_type == MOJOSHADER_TYPE_PIXEL)
       
  1564     {
       
  1565         for (i = 0; i < pd->sampler_count; i++)
       
  1566         {
       
  1567             if (pd->samplers[i].texbem)
       
  1568             {
       
  1569                 float4_count += 2;
       
  1570                 program->texbem_count++;
       
  1571             } // if
       
  1572         } // for
       
  1573     } // if
       
  1574 
  1542     #define MAKE_ARRAY(typ, gltyp, siz, count) \
  1575     #define MAKE_ARRAY(typ, gltyp, siz, count) \
  1543         if (count) { \
  1576         if (count) { \
  1544             const size_t buflen = sizeof (gltyp) * siz * count; \
  1577             const size_t buflen = sizeof (gltyp) * siz * count; \
  1545             gltyp *ptr = (gltyp *) Malloc(buflen); \
  1578             gltyp *ptr = (gltyp *) Malloc(buflen); \
  1546             if (ptr == NULL) { \
  1579             if (ptr == NULL) { \
  2268         memcpy(data, program->ps_preshader_regs + (idx * 4), cpy);
  2301         memcpy(data, program->ps_preshader_regs + (idx * 4), cpy);
  2269     } // if
  2302     } // if
  2270 } // MOJOSHADER_glGetPixelPreshaderUniformF
  2303 } // MOJOSHADER_glGetPixelPreshaderUniformF
  2271 
  2304 
  2272 
  2305 
       
  2306 void MOJOSHADER_glSetLegacyBumpMapEnv(unsigned int sampler, float mat00,
       
  2307                                       float mat01, float mat10, float mat11,
       
  2308                                       float lscale, float loffset)
       
  2309 {
       
  2310     if ((sampler == 0) || (sampler > (MAX_TEXBEMS+1)))
       
  2311         return;
       
  2312 
       
  2313     GLfloat *dstf = ctx->texbem_state + (6 * (sampler-1));
       
  2314     *(dstf++) = (GLfloat) mat00;
       
  2315     *(dstf++) = (GLfloat) mat01;
       
  2316     *(dstf++) = (GLfloat) mat10;
       
  2317     *(dstf++) = (GLfloat) mat11;
       
  2318     *(dstf++) = (GLfloat) lscale;
       
  2319     *(dstf++) = (GLfloat) loffset;
       
  2320     ctx->generation++;
       
  2321 } // MOJOSHADER_glSetLegacyBumpMapEnv
       
  2322 
       
  2323 
  2273 void MOJOSHADER_glProgramReady(void)
  2324 void MOJOSHADER_glProgramReady(void)
  2274 {
  2325 {
  2275     MOJOSHADER_glProgram *program = ctx->bound_program;
  2326     MOJOSHADER_glProgram *program = ctx->bound_program;
  2276 
  2327 
  2277     if (program == NULL)
  2328     if (program == NULL)
  2288             ctx->glDisable(GL_PROGRAM_POINT_SIZE);
  2339             ctx->glDisable(GL_PROGRAM_POINT_SIZE);
  2289         ctx->pointsize_enabled = program->uses_pointsize;
  2340         ctx->pointsize_enabled = program->uses_pointsize;
  2290     } // if
  2341     } // if
  2291 
  2342 
  2292     // push Uniforms to the program from our register files...
  2343     // push Uniforms to the program from our register files...
  2293     if ((program->uniform_count) && (program->generation != ctx->generation))
  2344     if ( ((program->uniform_count) || (program->texbem_count)) &&
       
  2345          (program->generation != ctx->generation))
  2294     {
  2346     {
  2295         // vertex shader uniforms come first in program->uniforms array.
  2347         // vertex shader uniforms come first in program->uniforms array.
  2296         const uint32 count = program->uniform_count;
  2348         const uint32 count = program->uniform_count;
  2297         const GLfloat *srcf = ctx->vs_reg_file_f;
  2349         const GLfloat *srcf = ctx->vs_reg_file_f;
  2298         const GLint *srci = ctx->vs_reg_file_i;
  2350         const GLint *srci = ctx->vs_reg_file_i;
  2302         GLint *dsti = program->vs_uniforms_int4;
  2354         GLint *dsti = program->vs_uniforms_int4;
  2303         GLint *dstb = program->vs_uniforms_bool;
  2355         GLint *dstb = program->vs_uniforms_bool;
  2304         const MOJOSHADER_preshader *preshader = NULL;
  2356         const MOJOSHADER_preshader *preshader = NULL;
  2305         uint32 i;
  2357         uint32 i;
  2306 
  2358 
       
  2359         // !!! FIXME: shouldn't this run even if the generation hasn't changed?
  2307         #if SUPPORT_PRESHADERS
  2360         #if SUPPORT_PRESHADERS
  2308         int ran_preshader = 0;
  2361         int ran_preshader = 0;
  2309         if (program->vertex)
  2362         if (program->vertex)
  2310         {
  2363         {
  2311             preshader = program->vertex->parseData->preshader;
  2364             preshader = program->vertex->parseData->preshader;
  2392             } // else if
  2445             } // else if
  2393 
  2446 
  2394             // !!! FIXME: set constants that overlap the array.
  2447             // !!! FIXME: set constants that overlap the array.
  2395         } // for
  2448         } // for
  2396 
  2449 
       
  2450         if (program->texbem_count)
       
  2451         {
       
  2452             const MOJOSHADER_parseData *pd = program->fragment->parseData;
       
  2453             const int samp_count = pd->sampler_count;
       
  2454             const MOJOSHADER_sampler *samps = pd->samplers;
       
  2455             GLfloat *dstf = program->ps_uniforms_float4;
       
  2456             int texbem_count = 0;
       
  2457 
       
  2458             dstf += (program->ps_uniforms_float4_count * 4) -
       
  2459                      (program->texbem_count * 8);
       
  2460 
       
  2461             assert(program->texbem_count <= MAX_TEXBEMS);
       
  2462             for (i = 0; i < samp_count; i++)
       
  2463             {
       
  2464                 if (samps[i].texbem)
       
  2465                 {
       
  2466                     assert(samps[i].index > 0);
       
  2467                     assert(samps[i].index <= MAX_TEXBEMS);
       
  2468                     memcpy(dstf, &ctx->texbem_state[6 * (samps[i].index-1)],
       
  2469                            sizeof (GLfloat) * 6);
       
  2470                     dstf[6] = 0.0f;
       
  2471                     dstf[7] = 0.0f;
       
  2472                     dstf += 8;
       
  2473                     texbem_count++;
       
  2474                 } // if
       
  2475             } // for
       
  2476 
       
  2477             assert(texbem_count == program->texbem_count);
       
  2478         } // for
       
  2479 
  2397         program->generation = ctx->generation;
  2480         program->generation = ctx->generation;
  2398 
  2481 
  2399         ctx->profilePushUniforms();
  2482         ctx->profilePushUniforms();
  2400     } // if
  2483     } // if
  2401 } // MOJOSHADER_glProgramReady
  2484 } // MOJOSHADER_glProgramReady