2
3
4
5
9#include "Render/Vulkan/VulkanRenderBackend.h"
10#include "Core/Reflect/TypeReflect.h"
11#include "Render/Renderer/DescriptorSetManager/DescriptorSetManager.h"
12#include "Render/Renderer/RendererManager.h"
13#include "Core/Library/StringLibrary.h"
14#include "Render/Renderer/Renderer.h"
15#include "Render/Renderer/DescriptorSetManager/BindLessTextureManager.h"
16#include "Resources/Shader/Shader.h"
28
29
38
39
40 for (
auto& pair : m_Shaders)
42 for (
int i = 0; i < pair.second.size(); i++)
45 ss << pair.first <<
"." << pair.second[i];
47 ResourcePool<Shader>::UnLoad(ss.str());
59 SPICES_CORE_INFO(
"Please do not do that!");
69 SPICES_CORE_WARN(
"Material::m_MaterialPath is empty.");
80 if (m_Shaders.find(stage) == m_Shaders.end())
83 ss <<
"Material: " <<
m_MaterialPath <<
" : Not find sush shader: " << stage;
85 SPICES_CORE_WARN(ss.str());
88 return m_Shaders[stage];
95 std::unique_lock<std::mutex> lock(m_Mutex);
97 m_Shaders[name].push_back(shader);
98 m_DefaultShaders[name].push_back(shader);
105 std::unique_lock<std::mutex> lock(m_Mutex);
107 m_TextureParams.push_back(name, texture);
108 m_DefaultTextureParams.push_back(name, texture);
115 std::unique_lock<std::mutex> lock(m_Mutex);
117 m_ConstantParams.push_back(name, {param, param});
124 if (m_MaterialParameterBuffer ==
nullptr)
126 SPICES_CORE_ERROR(
"Bad access to material buffer address.")
132 return m_MaterialParameterBuffer->GetAddress();
140 std::unique_lock<std::mutex> lock(m_Mutex);
143
144
151
152
154 std::vector<std::string> sv = StringLibrary::SplitString(m_MaterialPath,
'.');
155 auto renderer = RendererManager::GetRenderer(sv[0]);
156 renderer->RegistryMaterial(m_MaterialPath, sv[1]);
166
167
171 for (
auto& pair : m_Shaders)
173 for (
int i = 0; i < pair.second.size(); i++)
175 std::stringstream ss;
176 ss << pair.second[i] <<
"." << pair.first;
178 ResourcePool<Shader>::Load<Shader>(ss.str(), pair.second[i], pair.first);
184
185
189 m_MaterialParameterBuffer =
nullptr;
190 m_Buffermemoryblocks = scl::runtime_memory_block();
194
195
199 m_ConstantParams.for_each([&](
const std::string& k,
const ConstantParams& v) {
200 m_Buffermemoryblocks.add_element(k, v.value.paramType);
204 m_Buffermemoryblocks.build();
208
209
210 uint64_t size = m_TextureParams.size() *
sizeof(
int) + m_Buffermemoryblocks.get_bytes();
215 const std::vector<std::string> sv = StringLibrary::SplitString(m_MaterialPath,
'.');
216 auto renderer = RendererManager::GetRenderer(sv[0]);
217 renderer->RegistryMaterial(m_MaterialPath, sv[1]);
224
225
229 m_MaterialParameterBuffer = std::make_unique<VulkanBuffer>(
230 VulkanRenderBackend::GetState(),
231 "MaterialParameterBuffer",
233 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
234 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
235 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
240
241
246 m_TextureParams.for_each([&](
const std::string& k, TextureParam& v) {
249
250
251
252 if (v.textureType ==
"Texture2D")
254 if(v.texturePath ==
"")
260 const std::shared_ptr<Texture> texture = ResourcePool<Texture>::Load<Texture2D>(v.texturePath, v.texturePath);
261 v.index = BindLessTextureManager::Registry(v.texturePath);
263 const auto descriptorSet = DescriptorSetManager::Registry(
"PreRenderer", SpicesShader::BINDLESS_TEXTURE_SET);
266
267
268 VkWriteDescriptorSet write {};
269 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
270 write.dstBinding = SpicesShader::BINDLESS_TEXTURE_BINDING;
271 write.dstSet = descriptorSet->Get();
272 write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
273 write.pImageInfo = texture->GetResource<VulkanImage>()->GetImageInfo();
274 write.descriptorCount = 1;
275 write.dstArrayElement = v.index;
278
279
280 vkUpdateDescriptorSets(VulkanRenderBackend::GetState().m_Device, 1, &write, 0,
nullptr);
283 m_MaterialParameterBuffer->WriteToBuffer(&v.index,
sizeof(
int), tindex *
sizeof(
int));
284 m_MaterialParameterBuffer->Flush();
288
289
292 SPICES_CORE_ERROR(
"Material::BuildMaterial(): Invalid textureType.");
301
302
306 m_Buffermemoryblocks.for_each([&](
const std::string& name,
void* pt) {
307 ConstantParam& ref = m_ConstantParams.find_value(name)->value;
308 size_t size = m_TextureParams.size() *
sizeof(
int) + m_Buffermemoryblocks.item_location(name);
311
312
313 if (ref.paramType ==
"float4")
315 *
static_cast<glm::vec4*>(pt) = std::any_cast<glm::vec4>(ref.paramValue);
316 m_MaterialParameterBuffer->WriteToBuffer(pt,
sizeof(glm::vec4), size);
317 m_MaterialParameterBuffer->Flush();
319 else if (ref.paramType ==
"float3")
321 *
static_cast<glm::vec3*>(pt) = std::any_cast<glm::vec3>(ref.paramValue);
322 m_MaterialParameterBuffer->WriteToBuffer(pt,
sizeof(glm::vec3), size);
323 m_MaterialParameterBuffer->Flush();
325 else if (ref.paramType ==
"float2")
327 *
static_cast<glm::vec2*>(pt) = std::any_cast<glm::vec2>(ref.paramValue);
328 m_MaterialParameterBuffer->WriteToBuffer(pt,
sizeof(glm::vec2), size);
329 m_MaterialParameterBuffer->Flush();
331 else if (ref.paramType ==
"float")
333 *
static_cast<
float*>(pt) = std::any_cast<
float>(ref.paramValue);
334 m_MaterialParameterBuffer->WriteToBuffer(pt,
sizeof(
float), size);
335 m_MaterialParameterBuffer->Flush();
337 else if (ref.paramType ==
"int")
339 *
static_cast<
int*>(pt) = std::any_cast<
int>(ref.paramValue);
340 m_MaterialParameterBuffer->WriteToBuffer(pt,
sizeof(
int), size);
341 m_MaterialParameterBuffer->Flush();
343 else if (ref.paramType ==
"bool")
345 *
static_cast<
bool*>(pt) = std::any_cast<
bool>(ref.paramValue);
346 m_MaterialParameterBuffer->WriteToBuffer(pt,
sizeof(
bool), size);
347 m_MaterialParameterBuffer->Flush();
351 SPICES_CORE_ERROR(
"Material::BuildMaterial(): Invalid paramType.")
359
360
363 std::vector<std::string> sv = StringLibrary::SplitString(m_MaterialPath,
'.');
364 auto renderer = RendererManager::GetRenderer(sv[0]);
365 renderer->RegistryMaterial(m_MaterialPath, sv[1]);
373 std::unique_lock<std::mutex> lock(m_Mutex);
376
377
381 for (
auto& pair : m_Shaders)
383 for (
int i = 0; i < pair.second.size(); i++)
385 std::stringstream ss;
386 ss << pair.first <<
"." << pair.second[i];
388 ResourcePool<Shader>::Load<Shader>(ss.str(), pair.second[i], pair.first);
394
395
399 m_Buffermemoryblocks = scl::runtime_memory_block();
401 m_ConstantParams.for_each([&](
const std::string& k,
const ConstantParams& v) {
402 m_Buffermemoryblocks.add_element(k, v.value.paramType);
406 m_Buffermemoryblocks.build();
410
411
416 m_TextureParams.for_each([&](
const std::string& k, TextureParam& v) {
419
420
421
422 if (v.textureType ==
"Texture2D")
424 if (v.texturePath ==
"")
430 std::shared_ptr<Texture> texture = ResourcePool<Texture>::Load<Texture2D>(v.texturePath, v.texturePath);
431 v.index = BindLessTextureManager::Registry(v.texturePath);
433 auto descriptorSet = DescriptorSetManager::Registry(
"PreRenderer", SpicesShader::BINDLESS_TEXTURE_SET);
436
437
438 VkWriteDescriptorSet write {};
439 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
440 write.dstBinding = SpicesShader::BINDLESS_TEXTURE_BINDING;
441 write.dstSet = descriptorSet->Get();
442 write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
443 write.pImageInfo = texture->GetResource<VulkanImage>()->GetImageInfo();
444 write.descriptorCount = 1;
445 write.dstArrayElement = v.index;
448
449
450 vkUpdateDescriptorSets(VulkanRenderBackend::GetState().m_Device, 1, &write, 0,
nullptr);
453 m_MaterialParameterBuffer->WriteToBuffer(&v.index,
sizeof(
int), tindex *
sizeof(
int));
454 m_MaterialParameterBuffer->Flush();
458
459
462 SPICES_CORE_ERROR(
"Material::BuildMaterial(): Invalid textureType.")
471
472
476 m_Buffermemoryblocks.for_each([&](
const std::string& name,
void* pt) {
477 ConstantParam& ref = m_ConstantParams.find_value(name)->value;
478 size_t size = m_TextureParams.size() *
sizeof(
int) + m_Buffermemoryblocks.item_location(name);
481
482
483 if (ref.paramType ==
"float4")
485 *
static_cast<glm::vec4*>(pt) = std::any_cast<glm::vec4>(ref.paramValue);
486 m_MaterialParameterBuffer->WriteToBuffer(pt,
sizeof(glm::vec4), size);
487 m_MaterialParameterBuffer->Flush();
489 else if (ref.paramType ==
"float3")
491 *
static_cast<glm::vec3*>(pt) = std::any_cast<glm::vec3>(ref.paramValue);
492 m_MaterialParameterBuffer->WriteToBuffer(pt,
sizeof(glm::vec3), size);
493 m_MaterialParameterBuffer->Flush();
495 else if (ref.paramType ==
"float2")
497 *
static_cast<glm::vec2*>(pt) = std::any_cast<glm::vec2>(ref.paramValue);
498 m_MaterialParameterBuffer->WriteToBuffer(pt,
sizeof(glm::vec2), size);
499 m_MaterialParameterBuffer->Flush();
501 else if (ref.paramType ==
"float")
503 *
static_cast<
float*>(pt) = std::any_cast<
float>(ref.paramValue);
504 m_MaterialParameterBuffer->WriteToBuffer(pt,
sizeof(
float), size);
505 m_MaterialParameterBuffer->Flush();
507 else if (ref.paramType ==
"int")
509 *
static_cast<
int*>(pt) = std::any_cast<
int>(ref.paramValue);
510 m_MaterialParameterBuffer->WriteToBuffer(pt,
sizeof(
int), size);
511 m_MaterialParameterBuffer->Flush();
513 else if (ref.paramType ==
"bool")
515 *
static_cast<
bool*>(pt) = std::any_cast<
bool>(ref.paramValue);
516 m_MaterialParameterBuffer->WriteToBuffer(pt,
sizeof(
bool), size);
517 m_MaterialParameterBuffer->Flush();
521 SPICES_CORE_ERROR(
"Material::BuildMaterial(): Invalid paramType.")
#define SPICES_PROFILE_ZONEN(...)
#define SPICES_PROFILE_ZONE
static bool Load(const std::string &fileName, Material *outMaterial)
Public called API, it is entrance.
This enum defines tree types of material file.
void BuildMaterial(bool isAutoRegistry=true)
This interface need to be overwritten by specific material. It defines how we build texture and descr...
void PushToTextureParams(const std::string &name, const TextureParam &texture)
Push item to ShaderPath.
const std::vector< std::string > & GetShaderPath(const std::string &stage)
Get material shader path.
bool m_AlreadyBuild
True if this material already build a buffer.
void UpdateMaterial()
Update material data to buffer.
void Deserialize()
Deserialize the data from a disk file(.material) to this class.
void PushToShaderPath(const std::string &name, const std::string &shader)
Push item to ShaderPath.
void PushToConstParams(const std::string &name, const ConstantParam ¶m)
Push item to ConstParams.
uint64_t GetMaterialParamsAddress() const
Get material parameter address on GPU.
bool m_IsDrawWindow
True if this material needs to draw a window.
Material(const std::string &materialPath)
Constructor Function. Deserialize immediately. Usually call it.
virtual ~Material()
Destructor Function.
std::string m_MaterialPath
void Serialize()
Serialize this class data to a disk file(.material).
Material Class. This class contains a branch of parameter and shader, also descriptor.
This struct's data is defined from .material file.
This struct's data is defined from .material file.