mojoshader.c
changeset 1160 24ee60c85ec3
parent 1159 d4f97945e2f5
child 1161 6085abb2edaa
equal deleted inserted replaced
1159:d4f97945e2f5 1160:24ee60c85ec3
   191 #if SUPPORT_PROFILE_GLSLES
   191 #if SUPPORT_PROFILE_GLSLES
   192     int profile_supports_glsles;
   192     int profile_supports_glsles;
   193 #endif
   193 #endif
   194 
   194 
   195 #if SUPPORT_PROFILE_METAL
   195 #if SUPPORT_PROFILE_METAL
   196     int metal_used_buffers;
       
   197     int metal_need_header_common;
   196     int metal_need_header_common;
   198     int metal_need_header_math;
   197     int metal_need_header_math;
   199     int metal_need_header_relational;
   198     int metal_need_header_relational;
   200     int metal_need_header_geometric;
   199     int metal_need_header_geometric;
   201     int metal_need_header_graphics;
   200     int metal_need_header_graphics;
  4104                                                   const RegisterType regtype,
  4103                                                   const RegisterType regtype,
  4105                                                   char *buf, const size_t len)
  4104                                                   char *buf, const size_t len)
  4106 {
  4105 {
  4107     const char *shadertype = ctx->shader_type_str;
  4106     const char *shadertype = ctx->shader_type_str;
  4108     const char *type = get_METAL_uniform_type(ctx, regtype);
  4107     const char *type = get_METAL_uniform_type(ctx, regtype);
  4109     snprintf(buf, len, "uniforms_%s", type);
  4108     snprintf(buf, len, "uniforms.uniforms_%s", type);
  4110     return buf;
  4109     return buf;
  4111 } // get_METAL_uniform_array_varname
  4110 } // get_METAL_uniform_array_varname
  4112 
  4111 
  4113 static const char *get_METAL_destarg_varname(Context *ctx, char *buf, size_t len)
  4112 static const char *get_METAL_destarg_varname(Context *ctx, char *buf, size_t len)
  4114 {
  4113 {
  4508 static void emit_METAL_phase(Context *ctx)
  4507 static void emit_METAL_phase(Context *ctx)
  4509 {
  4508 {
  4510     // no-op in Metal.
  4509     // no-op in Metal.
  4511 } // emit_METAL_phase
  4510 } // emit_METAL_phase
  4512 
  4511 
  4513 static void output_METAL_uniform_array(Context *ctx, const RegisterType regtype,
       
  4514                                        const int size, int *commas)
       
  4515 {
       
  4516     if (size > 0)
       
  4517     {
       
  4518         char buf[64];
       
  4519         get_METAL_uniform_array_varname(ctx, regtype, buf, sizeof (buf));
       
  4520         const char *typ;
       
  4521         switch (regtype)
       
  4522         {
       
  4523             case REG_TYPE_CONST: typ = "float4"; break;
       
  4524             case REG_TYPE_CONSTINT: typ ="int4"; break;
       
  4525             case REG_TYPE_CONSTBOOL: typ = "bool"; break;
       
  4526             default:
       
  4527             {
       
  4528                 fail(ctx, "BUG: used a uniform we don't know how to define.");
       
  4529                 return;
       
  4530             } // default
       
  4531         } // switch
       
  4532 
       
  4533         const char *commastr = "";
       
  4534         if (*commas > 0)
       
  4535         {
       
  4536             (*commas)--;
       
  4537             commastr = ",";
       
  4538         } // if
       
  4539 
       
  4540         // !!! FIXME: Can we use size here?
       
  4541         output_line(ctx, "constant %s *%s [[buffer(%d)]]%s", typ, buf,
       
  4542                     ctx->metal_used_buffers, commastr);
       
  4543         ctx->metal_used_buffers++;
       
  4544     } // if
       
  4545 } // output_METAL_uniform_array
       
  4546 
       
  4547 static void emit_METAL_finalize(Context *ctx)
  4512 static void emit_METAL_finalize(Context *ctx)
  4548 {
  4513 {
  4549     // throw some blank lines around to make source more readable.
       
  4550     if (ctx->globals)  // don't add a blank line if the section is empty.
       
  4551     {
       
  4552         push_output(ctx, &ctx->globals);
       
  4553         output_blank_line(ctx);
       
  4554         pop_output(ctx);
       
  4555     } // if
       
  4556 
       
  4557     // If we had a relative addressing of REG_TYPE_INPUT, we need to build
  4514     // If we had a relative addressing of REG_TYPE_INPUT, we need to build
  4558     //  an array for it at the start of main(). GLSL doesn't let you specify
  4515     //  an array for it at the start of main(). GLSL doesn't let you specify
  4559     //  arrays of attributes.
  4516     //  arrays of attributes.
  4560     //float4 blah_array[BIGGEST_ARRAY];
  4517     //float4 blah_array[BIGGEST_ARRAY];
  4561     if (ctx->have_relative_input_registers) // !!! FIXME
  4518     if (ctx->have_relative_input_registers) // !!! FIXME
  4588     pop_output(ctx);
  4545     pop_output(ctx);
  4589 
  4546 
  4590     push_output(ctx, &ctx->mainline_arguments);
  4547     push_output(ctx, &ctx->mainline_arguments);
  4591     ctx->indent++;
  4548     ctx->indent++;
  4592 
  4549 
       
  4550     const int uniform_count = ctx->uniform_float4_count + ctx->uniform_int4_count + ctx->uniform_bool_count;
  4593     int commas = 0;
  4551     int commas = 0;
  4594     if (ctx->uniform_float4_count) commas++;
  4552     if (uniform_count) commas++;
  4595     if (ctx->uniform_int4_count) commas++;
       
  4596     if (ctx->uniform_bool_count) commas++;
       
  4597     if (ctx->inputs) commas++;
  4553     if (ctx->inputs) commas++;
  4598     if (commas) commas--;
  4554     if (commas) commas--;
  4599 
  4555 
  4600     output_METAL_uniform_array(ctx, REG_TYPE_CONST, ctx->uniform_float4_count, &commas);
  4556     if (uniform_count > 0)
  4601     output_METAL_uniform_array(ctx, REG_TYPE_CONSTINT, ctx->uniform_int4_count, &commas);
  4557     {
  4602     output_METAL_uniform_array(ctx, REG_TYPE_CONSTBOOL, ctx->uniform_bool_count, &commas);
  4558         push_output(ctx, &ctx->globals);
       
  4559         output_line(ctx, "struct %sUniforms", ctx->mainfn);
       
  4560         output_line(ctx, "{");
       
  4561         ctx->indent++;
       
  4562         if (ctx->uniform_float4_count > 0)
       
  4563             output_line(ctx, "float4 uniforms_float4[%d];", ctx->uniform_float4_count);
       
  4564         if (ctx->uniform_int4_count > 0)
       
  4565             output_line(ctx, "int4 uniforms_int4[%d];", ctx->uniform_int4_count);
       
  4566         if (ctx->uniform_bool_count > 0)
       
  4567             output_line(ctx, "bool uniforms_bool[%d];", ctx->uniform_bool_count);
       
  4568         ctx->indent--;
       
  4569         output_line(ctx, "};");
       
  4570         pop_output(ctx);
       
  4571 
       
  4572         output_line(ctx, "constant %sUniforms &uniforms [[buffer(16)]]%s", ctx->mainfn, commas ? "," : "");
       
  4573         commas--;
       
  4574     } // if
  4603 
  4575 
  4604     if (ctx->inputs)
  4576     if (ctx->inputs)
  4605         output_line(ctx, "%sInput input [[stage_in]]", ctx->mainfn);
  4577     {
       
  4578         output_line(ctx, "%sInput input [[stage_in]]%s", ctx->mainfn, commas ? "," : "");
       
  4579         commas--;
       
  4580     } // if
  4606 
  4581 
  4607     ctx->indent--;
  4582     ctx->indent--;
  4608     output_line(ctx, ") {");
  4583     output_line(ctx, ") {");
  4609     if (ctx->outputs)
  4584     if (ctx->outputs)
  4610     {
  4585     {
  4628 
  4603 
  4629     if (ctx->outputs)
  4604     if (ctx->outputs)
  4630     {
  4605     {
  4631         push_output(ctx, &ctx->outputs);
  4606         push_output(ctx, &ctx->outputs);
  4632         output_line(ctx, "};");
  4607         output_line(ctx, "};");
       
  4608         output_blank_line(ctx);
       
  4609         pop_output(ctx);
       
  4610     } // if
       
  4611 
       
  4612     // throw some blank lines around to make source more readable.
       
  4613     if (ctx->globals)  // don't add a blank line if the section is empty.
       
  4614     {
       
  4615         push_output(ctx, &ctx->globals);
  4633         output_blank_line(ctx);
  4616         output_blank_line(ctx);
  4634         pop_output(ctx);
  4617         pop_output(ctx);
  4635     } // if
  4618     } // if
  4636 } // emit_METAL_finalize
  4619 } // emit_METAL_finalize
  4637 
  4620 
  4732 } // emit_METAL_const_array
  4715 } // emit_METAL_const_array
  4733 
  4716 
  4734 static void emit_METAL_uniform(Context *ctx, RegisterType regtype, int regnum,
  4717 static void emit_METAL_uniform(Context *ctx, RegisterType regtype, int regnum,
  4735                               const VariableList *var)
  4718                               const VariableList *var)
  4736 {
  4719 {
  4737     // Now that we're pushing all the uniforms as one big array, pack these
  4720     // Now that we're pushing all the uniforms as one struct, pack these
  4738     //  down, so if we only use register c439, it'll actually map to
  4721     //  down, so if we only use register c439, it'll actually map to
  4739     //  metal_uniforms_float4[0]. As we push one big array, this will prevent
  4722     //  uniforms.uniforms_float4[0]. As we push one big struct, this will
  4740     //  uploading unused data.
  4723     //  prevent uploading unused data.
  4741 
  4724 
  4742     const char *utype = get_METAL_uniform_type(ctx, regtype);
  4725     const char *utype = get_METAL_uniform_type(ctx, regtype);
  4743     char varname[64];
  4726     char varname[64];
  4744     char name[64];
  4727     char name[64];
  4745     int index = 0;
  4728     int index = 0;