#include #include #include #include #include"common/MFCommon.h" #include"ShaderLibrary.h" using namespace hgl; using namespace hgl::graph; STD_MTL_NAMESPACE_BEGIN MaterialCreateInfo::MaterialCreateInfo(const MaterialCreateConfig *mc) { config=mc; if(hasVertex ())shader_map.Add(vert=new ShaderCreateInfoVertex (&mdi));else vert=nullptr; if(hasGeometry ())shader_map.Add(geom=new ShaderCreateInfoGeometry(&mdi));else geom=nullptr; if(hasFragment ())shader_map.Add(frag=new ShaderCreateInfoFragment(&mdi));else frag=nullptr; ubo_range=0; ssbo_range=0; { mi_data_bytes=0; mi_shader_stage=0; mi_max_count=0; mi_ubo=nullptr; } } bool MaterialCreateInfo::AddStruct(const AnsiString &struct_name,const AnsiString &codes) { if(struct_name.IsEmpty()||codes.IsEmpty()) return(false); return mdi.AddStruct(struct_name,codes); } bool MaterialCreateInfo::AddUBO(const VkShaderStageFlagBits flag_bit,const DescriptorSetType set_type,const AnsiString &struct_name,const AnsiString &name) { if(!shader_map.ContainsKey(flag_bit)) return(false); if(!mdi.hasStruct(struct_name)) return(false); ShaderCreateInfo *sc=shader_map[flag_bit]; if(!sc) return(false); UBODescriptor *ubo=mdi.GetUBO(name); if(ubo) { if(ubo->type!=struct_name) return(false); ubo->stage_flag|=flag_bit; return sc->AddUBO(set_type,ubo); } else { ubo=new UBODescriptor(); ubo->type=struct_name; hgl::strcpy(ubo->name,DESCRIPTOR_NAME_MAX_LENGTH,name); return sc->AddUBO(set_type,mdi.AddUBO(flag_bit,set_type,ubo)); } } bool MaterialCreateInfo::AddUBO(const uint32_t flag_bits,const DescriptorSetType &set_type,const AnsiString &struct_name,const AnsiString &name) { if(flag_bits==0)return(false); //没有任何SHADER用? if(!mdi.hasStruct(struct_name)) return(false); uint result=0; VkShaderStageFlagBits bit; for(int i=0;itype!=st_name) return(false); sampler->stage_flag|=flag_bit; return sc->AddSampler(set_type,sampler); } else { sampler=new SamplerDescriptor(); sampler->type=st_name; hgl::strcpy(sampler->name,DESCRIPTOR_NAME_MAX_LENGTH,name); return sc->AddSampler(set_type,mdi.AddSampler(flag_bit,set_type,sampler)); } } namespace { UBODescriptor *CreateUBODescriptor(const ShaderBufferSource &sbs,const uint32_t flag_bits) { UBODescriptor *ubo=new UBODescriptor; ubo->type=sbs.struct_name; hgl::strcpy(ubo->name,DESCRIPTOR_NAME_MAX_LENGTH,sbs.name); ubo->stage_flag=flag_bits; return ubo; } }//namespace /** * 设置材质实例代码与数据长度 * @param glsl_codes 材质实例GLSL代码 * @param data_bytes 单个材质实例数据长度 * @param shader_stage_flag_bits 具体使用材质实例的shader * @return 是否设置成功 */ bool MaterialCreateInfo::SetMaterialInstance(const AnsiString &glsl_codes,const uint32_t data_bytes,const uint32_t shader_stage_flag_bits) { if(mi_data_bytes>0)return(false); //已经有数据了 if(shader_stage_flag_bits==0)return(false); if(data_bytes>0&&glsl_codes.Length()<4)return(false); mi_data_bytes=data_bytes; if(data_bytes>0) mi_codes=glsl_codes; mi_max_count=hgl_min(ubo_range/data_bytes,HGL_U16_MAX); mdi.AddStruct(MaterialInstanceStruct,mi_codes); mdi.AddStruct(SBS_MaterialInstance); mi_ubo=CreateUBODescriptor(SBS_MaterialInstance,shader_stage_flag_bits); mdi.AddUBO(shader_stage_flag_bits,SBS_MaterialInstance.set_type,mi_ubo); const AnsiString MI_MAX_COUNT_STRING=AnsiString::numberOf(mi_max_count); auto *it=shader_map.GetDataList(); for(int i=0;ikey&shader_stage_flag_bits) { (*it)->value->AddDefine("MI_MAX_COUNT",MI_MAX_COUNT_STRING); (*it)->value->SetMaterialInstance(mi_ubo,mi_codes); } ++it; } mi_shader_stage=shader_stage_flag_bits; return(true); } bool MaterialCreateInfo::SetLocalToWorld(const uint32_t shader_stage_flag_bits) { if(shader_stage_flag_bits==0)return(false); l2w_max_count=hgl_min(ubo_range/sizeof(Matrix4f),HGL_U16_MAX); mdi.AddStruct(SBS_LocalToWorld); l2w_ubo=CreateUBODescriptor(SBS_LocalToWorld,shader_stage_flag_bits); mdi.AddUBO(shader_stage_flag_bits,SBS_LocalToWorld.set_type,l2w_ubo); const AnsiString L2W_MAX_COUNT_STRING=AnsiString::numberOf(l2w_max_count); auto *it=shader_map.GetDataList(); for(int i=0;ikey&shader_stage_flag_bits) { (*it)->value->AddDefine("L2W_MAX_COUNT",L2W_MAX_COUNT_STRING); } ++it; } l2w_shader_stage=shader_stage_flag_bits; return(true); } void MaterialCreateInfo::SetDevice(const VulkanDevAttr *dev_attr) { ubo_range=dev_attr->physical_device->GetUBORange(); //Mali-T系/G71为16k,nVidia和Mali-G系列除G71外为64k,Intel/PowerVR为128M,AMD无限制。 ssbo_range=dev_attr->physical_device->GetSSBORange(); } bool MaterialCreateInfo::CreateShader() { if(shader_map.IsEmpty()) return(false); mdi.Resort(); ShaderCreateInfo *sc,*last=nullptr; for(int i=0;i(sc->GetShaderStage())AddMaterialInstanceOutput(); sc->CreateShader(last); last=sc; } return(true); } STD_MTL_NAMESPACE_END