#include #include #include #include #include"common/MFCommon.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; mi_data_bytes=0; mi_shader_stage=0; } 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 &type_name,const AnsiString &name) { if(!shader_map.KeyExist(flag_bit)) return(false); if(!mdi.hasStruct(type_name)) return(false); ShaderCreateInfo *sc=shader_map[flag_bit]; if(!sc) return(false); UBODescriptor *ubo=mdi.GetUBO(name); if(ubo) { if(ubo->type!=type_name) return(false); ubo->stage_flag|=flag_bit; return sc->sdm->AddUBO(set_type,ubo); } else { ubo=new UBODescriptor(); ubo->type=type_name; hgl::strcpy(ubo->name,DESCRIPTOR_NAME_MAX_LENGTH,name); return sc->sdm->AddUBO(set_type,mdi.AddUBO(flag_bit,set_type,ubo)); } } bool MaterialCreateInfo::AddSampler(const VkShaderStageFlagBits flag_bit,const DescriptorSetType set_type,const SamplerType &st,const AnsiString &name) { if(!shader_map.KeyExist(flag_bit)) return(false); RANGE_CHECK_RETURN_FALSE(st); ShaderCreateInfo *sc=shader_map[flag_bit]; if(!sc) return(false); SamplerDescriptor *sampler=mdi.GetSampler(name); AnsiString st_name=GetSamplerTypeName(st); if(sampler) { if(sampler->type!=st_name) return(false); sampler->stage_flag|=flag_bit; return sc->sdm->AddSampler(set_type,sampler); } else { sampler=new SamplerDescriptor(); sampler->type=st_name; hgl::strcpy(sampler->name,DESCRIPTOR_NAME_MAX_LENGTH,name); return sc->sdm->AddSampler(set_type,mdi.AddSampler(flag_bit,set_type,sampler)); } } bool MaterialCreateInfo::AddUBO(const uint32_t flag_bits,const DescriptorSetType &set_type,const ShaderBufferSource &ss) { if(flag_bits==0)return(false); //没有任何SHADER用? if(!mdi.hasStruct(ss.struct_name)) mdi.AddStruct(ss.struct_name,ss.codes); uint result=0; VkShaderStageFlagBits bit; for(int i=0;i0)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; const uint32_t ubo_range=config->dev_attr->physical_device->GetUBORange(); //Mali-T系/G71为16k,Intel/PowerVR为128M,AMD无限制。nVidia和Mali-G除G71外为64k const uint32_t mi_max_count=ubo_range/data_bytes; const AnsiString MI_MAX_COUNT=AnsiString::numberOf(mi_max_count>256?256:mi_max_count); //我们使用uint8传递材质实例ID,所以最大数量为256。未来如考虑使用更多,需综合考虑 mdi.AddStruct(MaterialInstanceStruct,mi_codes); mdi.AddStruct(SBS_MaterialInstanceData); UBODescriptor *ubo=new UBODescriptor(); ubo->type=SBS_MaterialInstanceData.struct_name; hgl::strcpy(ubo->name,DESCRIPTOR_NAME_MAX_LENGTH,SBS_MaterialInstanceData.name); ubo->stage_flag=shader_stage_flag_bits; mdi.AddUBO(shader_stage_flag_bits,DescriptorSetType::PerMaterial,ubo); auto *it=shader_map.GetDataList(); for(int i=0;ikey&shader_stage_flag_bits) { (*it)->value->AddDefine("MI_MAX_COUNT",MI_MAX_COUNT); (*it)->value->SetMaterialInstance(ubo,mi_codes); } ++it; } vert->AddMaterialInstanceID(); //增加一个材质实例ID mi_shader_stage=shader_stage_flag_bits; return(true); } bool MaterialCreateInfo::CreateShader(const GPUDeviceAttribute *dev_attr) { if(shader_map.IsEmpty()) return(false); mdi.Resort(); ShaderCreateInfo *sc,*last=nullptr; for(int i=0;iGetShaderStage()AddOutput(VAT_UINT,VAN::MaterialInstanceID,Interpolation::Flat); sc->AddFunction(mtl::func::HandoverMI); } sc->CreateShader(last); last=sc; } return(true); } STD_MTL_NAMESPACE_END