From 1815d60f21a551f7ee040037878d35fd27b4a42a Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Fri, 10 May 2024 15:53:32 -0400 Subject: [PATCH] Add debug markers for peeking via RenderDoc --- extern/libphysis | 2 +- parts/mdl/mdlpart.cpp | 60 +++++++++++- renderer/CMakeLists.txt | 5 +- renderer/include/device.h | 7 +- renderer/include/drawobject.h | 2 +- renderer/include/gamerenderer.h | 7 +- renderer/include/rendermanager.h | 2 +- renderer/src/device.cpp | 33 ++++++- renderer/src/gamerenderer.cpp | 155 +++++++++++++++++++++++++++---- renderer/src/imguipass.cpp | 2 +- renderer/src/rendermanager.cpp | 11 ++- 11 files changed, 250 insertions(+), 36 deletions(-) diff --git a/extern/libphysis b/extern/libphysis index 47b2c3f..4fdec34 160000 --- a/extern/libphysis +++ b/extern/libphysis @@ -1 +1 @@ -Subproject commit 47b2c3fbc2159d81e40bcfbaf07687555592f47b +Subproject commit 4fdec34e301140dd49da29be9da530312cb3a6c6 diff --git a/parts/mdl/mdlpart.cpp b/parts/mdl/mdlpart.cpp index 069a8e8..d73f851 100644 --- a/parts/mdl/mdlpart.cpp +++ b/parts/mdl/mdlpart.cpp @@ -223,6 +223,7 @@ RenderMaterial MDLPart::createMaterial(const physis_Material &material) // create the material parameters for this shader package newMaterial.materialBuffer = renderer->device().createBuffer(newMaterial.shaderPackage.material_parameters_size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + renderer->device().nameBuffer(newMaterial.materialBuffer, "g_MaterialParameter"); // TODO: add material name // assumed to be floats, maybe not always true? std::vector buffer(newMaterial.shaderPackage.material_parameters_size / sizeof(float)); @@ -253,23 +254,72 @@ RenderMaterial MDLPart::createMaterial(const physis_Material &material) newMaterial.type = MaterialType::Skin; } - newMaterial.tableTexture = renderer->device().createDummyTexture(); + if (material.color_table.num_rows > 0) { + int width = 4; + int height = material.color_table.num_rows; + + qInfo() << "Creating color table" << width << "X" << height; + + std::vector rgbaData(width * height * 4); + int offset = 0; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + const auto row = material.color_table.rows[y]; + + glm::vec4 color; + if (x == 0) { + color = glm::vec4{row.diffuse_color[0], row.diffuse_color[1], row.diffuse_color[2], row.specular_strength}; + } else if (x == 1) { + color = glm::vec4{row.specular_color[0], row.specular_color[1], row.specular_color[2], row.gloss_strength}; + } else if (x == 2) { + color = glm::vec4{row.emissive_color[0], row.emissive_color[1], row.emissive_color[2], row.tile_set}; + } else if (x == 3) { + color = glm::vec4{row.material_repeat[0], row.material_repeat[1], row.material_skew[0], row.material_skew[1]}; + } + + rgbaData[offset] = color.x; + rgbaData[offset + 1] = color.y; + rgbaData[offset + 2] = color.z; + rgbaData[offset + 3] = color.a; + + offset += 4; + } + } + + physis_Texture textureConfig; + textureConfig.texture_type = TextureType::TwoDimensional; + textureConfig.width = width; + textureConfig.height = height; + textureConfig.depth = 1; + textureConfig.rgba = reinterpret_cast(rgbaData.data()); + textureConfig.rgba_size = rgbaData.size() * sizeof(float); + + // TODO: use 16-bit floating points like the game + newMaterial.tableTexture = renderer->addGameTexture(VK_FORMAT_R32G32B32A32_SFLOAT, textureConfig); + renderer->device().nameTexture(*newMaterial.tableTexture, "g_SamplerTable"); // TODO: add material name + } + + qInfo() << "Loading" << t; char type = t[t.length() - 5]; auto texture = physis_texture_parse(cache.lookupFile(QLatin1String(material.textures[i]))); if (texture.rgba != nullptr) { switch (type) { case 'm': { - newMaterial.multiTexture = renderer->addGameTexture(texture); + newMaterial.multiTexture = renderer->addGameTexture(VK_FORMAT_R8G8B8A8_UNORM, texture); + renderer->device().nameTexture(*newMaterial.multiTexture, material.textures[i]); } break; case 'd': { - newMaterial.diffuseTexture = renderer->addGameTexture(texture); + newMaterial.diffuseTexture = renderer->addGameTexture(VK_FORMAT_R8G8B8A8_UNORM, texture); + renderer->device().nameTexture(*newMaterial.diffuseTexture, material.textures[i]); } break; case 'n': { - newMaterial.normalTexture = renderer->addGameTexture(texture); + newMaterial.normalTexture = renderer->addGameTexture(VK_FORMAT_R8G8B8A8_UNORM, texture); + renderer->device().nameTexture(*newMaterial.normalTexture, material.textures[i]); } break; case 's': { - newMaterial.specularTexture = renderer->addGameTexture(texture); + newMaterial.specularTexture = renderer->addGameTexture(VK_FORMAT_R8G8B8A8_UNORM, texture); + renderer->device().nameTexture(*newMaterial.specularTexture, material.textures[i]); } break; default: qDebug() << "unhandled type" << type; diff --git a/renderer/CMakeLists.txt b/renderer/CMakeLists.txt index e3cb90f..77d394a 100644 --- a/renderer/CMakeLists.txt +++ b/renderer/CMakeLists.txt @@ -4,6 +4,7 @@ find_package(spirv_cross_core REQUIRED) find_package(spirv_cross_glsl REQUIRED) find_package(SPIRV-Headers REQUIRED) +find_package(glslang REQUIRED) add_library(renderer STATIC) target_sources(renderer @@ -50,7 +51,9 @@ target_link_libraries(renderer imgui dxbc spirv-cross-core - spirv-cross-glsl) + spirv-cross-glsl + glslang::SPIRV + glslang::glslang-default-resource-limits) target_compile_definitions(renderer PUBLIC GLM_FORCE_RADIANS GLM_FORCE_DEPTH_ZERO_TO_ONE GLM_ENABLE_EXPERIMENTAL) target_compile_options(renderer PUBLIC -fexceptions) # needed for spirv-cross and dxbc diff --git a/renderer/include/device.h b/renderer/include/device.h index ac5640c..bfec1df 100644 --- a/renderer/include/device.h +++ b/renderer/include/device.h @@ -59,6 +59,11 @@ public: VkResult nameObject(VkObjectType type, uint64_t object, std::string_view name); void nameTexture(Texture &texture, std::string_view name); + void nameBuffer(Buffer &buffer, std::string_view name); - Texture addGameTexture(physis_Texture gameTexture); + Texture addGameTexture(VkFormat format, physis_Texture gameTexture); + + void beginDebugMarker(VkCommandBuffer command_buffer, VkDebugUtilsLabelEXT marker_info); + void endDebugMarker(VkCommandBuffer command_buffer); + void insertDebugLabel(VkCommandBuffer command_buffer, VkDebugUtilsLabelEXT label_info); }; \ No newline at end of file diff --git a/renderer/include/drawobject.h b/renderer/include/drawobject.h index 5c6578d..b5d8cea 100644 --- a/renderer/include/drawobject.h +++ b/renderer/include/drawobject.h @@ -25,7 +25,7 @@ struct RenderMaterial { std::optional specularTexture; std::optional multiTexture; - Texture tableTexture; + std::optional tableTexture; Buffer materialBuffer; }; diff --git a/renderer/include/gamerenderer.h b/renderer/include/gamerenderer.h index 9e22bbf..94c17f2 100644 --- a/renderer/include/gamerenderer.h +++ b/renderer/include/gamerenderer.h @@ -58,7 +58,11 @@ private: void beginPass(uint32_t imageIndex, VkCommandBuffer commandBuffer, std::string_view passName); void endPass(VkCommandBuffer commandBuffer, std::string_view passName); - CachedPipeline &bindPipeline(VkCommandBuffer commandBuffer, std::string_view passName, physis_Shader &vertexShader, physis_Shader &pixelShader); + CachedPipeline &bindPipeline(VkCommandBuffer commandBuffer, + std::string_view passName, + physis_Shader &vertexShader, + physis_Shader &pixelShader, + std::string_view shaderName); VkShaderModule convertShaderModule(const physis_Shader &shader, spv::ExecutionModel executionModel); spirv_cross::CompilerGLSL getShaderModuleResources(const physis_Shader &shader); @@ -66,6 +70,7 @@ private: physis_SHPK directionalLightningShpk; physis_SHPK createViewPositionShpk; + physis_SHPK backgroundShpk; // combined vertex + pixel code length std::unordered_map m_cachedPipelines; diff --git a/renderer/include/rendermanager.h b/renderer/include/rendermanager.h index 171bb91..909c1b8 100644 --- a/renderer/include/rendermanager.h +++ b/renderer/include/rendermanager.h @@ -34,7 +34,7 @@ public: DrawObject addDrawObject(const physis_MDL &model, int lod); void reloadDrawObject(DrawObject &model, uint32_t lod); - Texture addGameTexture(physis_Texture gameTexture); + Texture addGameTexture(VkFormat format, physis_Texture gameTexture); void render(const std::vector &models); diff --git a/renderer/src/device.cpp b/renderer/src/device.cpp index cb443ef..50d164b 100644 --- a/renderer/src/device.cpp +++ b/renderer/src/device.cpp @@ -340,7 +340,13 @@ void Device::nameTexture(Texture &texture, std::string_view name) nameObject(VK_OBJECT_TYPE_DEVICE_MEMORY, reinterpret_cast(texture.imageMemory), name.data()); } -Texture Device::addGameTexture(physis_Texture gameTexture) +void Device::nameBuffer(Buffer &buffer, std::string_view name) +{ + nameObject(VK_OBJECT_TYPE_BUFFER, reinterpret_cast(buffer.buffer), name.data()); + nameObject(VK_OBJECT_TYPE_DEVICE_MEMORY, reinterpret_cast(buffer.memory), name.data()); +} + +Texture Device::addGameTexture(VkFormat format, physis_Texture gameTexture) { Texture newTexture = {}; @@ -359,7 +365,7 @@ Texture Device::addGameTexture(physis_Texture gameTexture) imageInfo.extent.depth = gameTexture.depth; imageInfo.mipLevels = 1; imageInfo.arrayLayers = 1; - imageInfo.format = VK_FORMAT_R8G8B8A8_UNORM; + imageInfo.format = format; imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; @@ -468,4 +474,25 @@ Texture Device::addGameTexture(physis_Texture gameTexture) vkCreateImageView(device, &viewInfo, nullptr, &newTexture.imageView); return newTexture; -} \ No newline at end of file +} + +void Device::beginDebugMarker(VkCommandBuffer command_buffer, VkDebugUtilsLabelEXT marker_info) +{ + auto func = (PFN_vkCmdBeginDebugUtilsLabelEXT)vkGetDeviceProcAddr(device, "vkCmdBeginDebugUtilsLabelEXT"); + if (func != nullptr) + func(command_buffer, &marker_info); +} + +void Device::endDebugMarker(VkCommandBuffer command_buffer) +{ + auto func = (PFN_vkCmdEndDebugUtilsLabelEXT)vkGetDeviceProcAddr(device, "vkCmdEndDebugUtilsLabelEXT"); + if (func != nullptr) + func(command_buffer); +} + +void Device::insertDebugLabel(VkCommandBuffer command_buffer, VkDebugUtilsLabelEXT label_info) +{ + auto func = (PFN_vkCmdInsertDebugUtilsLabelEXT)vkGetDeviceProcAddr(device, "vkCmdInsertDebugUtilsLabelEXT"); + if (func != nullptr) + func(command_buffer, &label_info); +} diff --git a/renderer/src/gamerenderer.cpp b/renderer/src/gamerenderer.cpp index 83dd059..2c1cc3a 100644 --- a/renderer/src/gamerenderer.cpp +++ b/renderer/src/gamerenderer.cpp @@ -8,6 +8,9 @@ #include #include +#include +#include +#include #include #include @@ -63,8 +66,11 @@ GameRenderer::GameRenderer(Device &device, GameData *data) m_dummyTex = m_device.createDummyTexture(); m_dummyBuffer = m_device.createDummyBuffer(); - m_tileNormal = m_device.addGameTexture(physis_texture_parse(physis_gamedata_extract_file(m_data, "chara/common/texture/-tile_n.tex"))); - m_tileDiffuse = m_device.addGameTexture(physis_texture_parse(physis_gamedata_extract_file(m_data, "chara/common/texture/-tile_d.tex"))); + m_tileNormal = + m_device.addGameTexture(VK_FORMAT_R8G8B8A8_UNORM, physis_texture_parse(physis_gamedata_extract_file(m_data, "chara/common/texture/-tile_n.tex"))); + m_device.nameTexture(m_tileNormal, "chara/common/texture/-tile_n.tex"); + m_tileDiffuse = m_device.addGameTexture(VK_FORMAT_R8G8B8A8_UNORM, physis_t"Exexture_parse(physis_gamedata_extract_file(m_data, "chara/common/texture/-tile_d.tex"))); + m_device.nameTexture(m_tileDiffuse, "chara/common/texture/-tile_d.tex"); size_t vertexSize = planeVertices.size() * sizeof(glm::vec4); m_planeVertexBuffer = m_device.createBuffer(vertexSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); @@ -72,15 +78,18 @@ GameRenderer::GameRenderer(Device &device, GameData *data) directionalLightningShpk = physis_parse_shpk(physis_gamedata_extract_file(m_data, "shader/sm5/shpk/directionallighting.shpk")); createViewPositionShpk = physis_parse_shpk(physis_gamedata_extract_file(m_data, "shader/sm5/shpk/createviewposition.shpk")); + backgroundShpk = physis_parse_shpk(physis_gamedata_extract_file(m_data, "shader/sm5/shpk/bg.shpk")); // camera data { g_CameraParameter = m_device.createBuffer(sizeof(CameraParameter), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + m_device.nameBuffer(g_CameraParameter, "g_CameraParameter"); } // instance data { g_InstanceParameter = m_device.createBuffer(sizeof(InstanceParameter), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + m_device.nameBuffer(g_InstanceParameter, "g_InstanceParameter"); InstanceParameter instanceParameter{}; instanceParameter.g_InstanceParameter.m_MulColor = glm::vec4(1.0f); @@ -100,6 +109,7 @@ GameRenderer::GameRenderer(Device &device, GameData *data) // model data { g_ModelParameter = m_device.createBuffer(sizeof(ModelParameter), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + m_device.nameBuffer(g_ModelParameter, "g_ModelParameter"); ModelParameter modelParameter{}; modelParameter.g_ModelParameter.m_Params = glm::vec4(1.0f); @@ -109,6 +119,7 @@ GameRenderer::GameRenderer(Device &device, GameData *data) // material data { g_TransparencyMaterialParameter = m_device.createBuffer(sizeof(MaterialParameters), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + m_device.nameBuffer(g_TransparencyMaterialParameter, "g_TransparencyMaterialParameter"); MaterialParameters materialParameter{}; materialParameter.parameters[0] = glm::vec4(1.0f, 1.0f, 1.0f, 2.0f); // diffuse color then alpha threshold @@ -119,6 +130,7 @@ GameRenderer::GameRenderer(Device &device, GameData *data) // light data { g_LightParam = m_device.createBuffer(sizeof(LightParam), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + m_device.nameBuffer(g_LightParam, "g_LightParam"); LightParam lightParam{}; lightParam.m_Position = glm::vec4(-5); @@ -135,11 +147,13 @@ GameRenderer::GameRenderer(Device &device, GameData *data) // common data { g_CommonParameter = m_device.createBuffer(sizeof(CommonParameter), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + m_device.nameBuffer(g_CommonParameter, "g_CommonParameter"); } // scene data { g_SceneParameter = m_device.createBuffer(sizeof(SceneParameter), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + m_device.nameBuffer(g_SceneParameter, "g_SceneParameter"); SceneParameter sceneParameter{}; m_device.copyToBuffer(g_SceneParameter, &sceneParameter, sizeof(SceneParameter)); @@ -148,8 +162,18 @@ GameRenderer::GameRenderer(Device &device, GameData *data) // customize data { g_CustomizeParameter = m_device.createBuffer(sizeof(CustomizeParameter), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + m_device.nameBuffer(g_CustomizeParameter, "g_CustomizeParameter"); CustomizeParameter customizeParameter{}; + customizeParameter.m_SkinColor = glm::vec4(1.0f); + customizeParameter.m_HairFresnelValue0 = glm::vec4(1.0f); + customizeParameter.m_LipColor = glm::vec4(1.0f); + customizeParameter.m_MainColor = glm::vec4(1.0f); + customizeParameter.m_HairFresnelValue0 = glm::vec4(1.0f); + customizeParameter.m_MeshColor = glm::vec4(1.0f); + customizeParameter.m_LeftColor = glm::vec4(1.0f); + customizeParameter.m_RightColor = glm::vec4(1.0f); + customizeParameter.m_OptionColor = glm::vec4(1.0f); m_device.copyToBuffer(g_CustomizeParameter, &customizeParameter, sizeof(CustomizeParameter)); } @@ -157,6 +181,7 @@ GameRenderer::GameRenderer(Device &device, GameData *data) // material parameter dynamic { g_MaterialParameterDynamic = m_device.createBuffer(sizeof(MaterialParameterDynamic), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + m_device.nameBuffer(g_MaterialParameterDynamic, "g_MaterialParameterDynamic"); MaterialParameterDynamic materialParameterDynamic{}; @@ -166,6 +191,7 @@ GameRenderer::GameRenderer(Device &device, GameData *data) // decal color { g_DecalColor = m_device.createBuffer(sizeof(glm::vec4), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + m_device.nameBuffer(g_DecalColor, "g_DecalColor"); glm::vec4 color{}; @@ -175,6 +201,7 @@ GameRenderer::GameRenderer(Device &device, GameData *data) // ambient params { g_AmbientParam = m_device.createBuffer(sizeof(AmbientParameters), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + m_device.nameBuffer(g_AmbientParam, "g_AmbientParam"); AmbientParameters ambientParameters{}; for (int i = 0; i < 6; i++) { @@ -190,6 +217,7 @@ GameRenderer::GameRenderer(Device &device, GameData *data) // shader type parameter if (m_dawntrailMode) { g_ShaderTypeParameter = m_device.createBuffer(sizeof(ShaderTypeParameter), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + m_device.nameBuffer(g_ShaderTypeParameter, "g_ShaderTypeParameter"); ShaderTypeParameter shaderTypeParameter{}; @@ -249,6 +277,11 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca beginPass(imageIndex, commandBuffer, pass); for (auto &model : models) { + VkDebugUtilsLabelEXT labelExt{}; + labelExt.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; + labelExt.pLabelName = model.name.toStdString().c_str(); + m_device.beginDebugMarker(commandBuffer, labelExt); + // copy bone data { const size_t bufferSize = sizeof(glm::mat3x4) * 64; @@ -361,7 +394,7 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca physis_Shader vertexShader = renderMaterial.shaderPackage.vertex_shaders[vertexShaderIndice]; physis_Shader pixelShader = renderMaterial.shaderPackage.pixel_shaders[pixelShaderIndice]; - auto &pipeline = bindPipeline(commandBuffer, pass, vertexShader, pixelShader); + auto &pipeline = bindPipeline(commandBuffer, pass, vertexShader, pixelShader, renderMaterial.mat.shpk_name); bindDescriptorSets(commandBuffer, pipeline, &model, &renderMaterial, pass); VkDeviceSize offsets[] = {0}; @@ -371,6 +404,8 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca vkCmdDrawIndexed(commandBuffer, part.numIndices, 1, 0, 0, 0); } } + + m_device.endDebugMarker(commandBuffer); } endPass(commandBuffer, pass); @@ -416,7 +451,7 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca physis_Shader vertexShader = createViewPositionShpk.vertex_shaders[vertexShaderIndice]; physis_Shader pixelShader = createViewPositionShpk.pixel_shaders[pixelShaderIndice]; - auto &pipeline = bindPipeline(commandBuffer, "PASS_LIGHTING_OPAQUE_VIEWPOSITION", vertexShader, pixelShader); + auto &pipeline = bindPipeline(commandBuffer, "PASS_LIGHTING_OPAQUE_VIEWPOSITION", vertexShader, pixelShader, "createviewposition.shpk"); bindDescriptorSets(commandBuffer, pipeline, nullptr, nullptr, pass); VkDeviceSize offsets[] = {0}; @@ -471,7 +506,7 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca physis_Shader vertexShader = directionalLightningShpk.vertex_shaders[vertexShaderIndice]; physis_Shader pixelShader = directionalLightningShpk.pixel_shaders[pixelShaderIndice]; - auto &pipeline = bindPipeline(commandBuffer, pass, vertexShader, pixelShader); + auto &pipeline = bindPipeline(commandBuffer, pass, vertexShader, pixelShader, "directionallighting.shpk"); bindDescriptorSets(commandBuffer, pipeline, nullptr, nullptr, pass); VkDeviceSize offsets[] = {0}; @@ -580,7 +615,7 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca physis_Shader vertexShader = renderMaterial.shaderPackage.vertex_shaders[vertexShaderIndice]; physis_Shader pixelShader = renderMaterial.shaderPackage.pixel_shaders[pixelShaderIndice]; - auto &pipeline = bindPipeline(commandBuffer, pass, vertexShader, pixelShader); + auto &pipeline = bindPipeline(commandBuffer, pass, vertexShader, pixelShader, renderMaterial.mat.shpk_name); bindDescriptorSets(commandBuffer, pipeline, &model, &renderMaterial, pass); VkDeviceSize offsets[] = {0}; @@ -613,6 +648,11 @@ void GameRenderer::resize() void GameRenderer::beginPass(uint32_t imageIndex, VkCommandBuffer commandBuffer, const std::string_view passName) { + VkDebugUtilsLabelEXT labelExt{}; + labelExt.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; + labelExt.pLabelName = passName.data(); + m_device.beginDebugMarker(commandBuffer, labelExt); + VkRenderingInfo renderingInfo{VK_STRUCTURE_TYPE_RENDERING_INFO}; renderingInfo.renderArea.extent = m_device.swapChain->extent; @@ -760,16 +800,24 @@ void GameRenderer::beginPass(uint32_t imageIndex, VkCommandBuffer commandBuffer, void GameRenderer::endPass(VkCommandBuffer commandBuffer, std::string_view passName) { vkCmdEndRendering(commandBuffer); + + m_device.endDebugMarker(commandBuffer); } -GameRenderer::CachedPipeline & -GameRenderer::bindPipeline(VkCommandBuffer commandBuffer, std::string_view passName, physis_Shader &vertexShader, physis_Shader &pixelShader) +GameRenderer::CachedPipeline &GameRenderer::bindPipeline(VkCommandBuffer commandBuffer, + std::string_view passName, + physis_Shader &vertexShader, + physis_Shader &pixelShader, + std::string_view shaderName) { const uint32_t hash = vertexShader.len + pixelShader.len + physis_shpk_crc(passName.data()); if (!m_cachedPipelines.contains(hash)) { auto vertexShaderModule = convertShaderModule(vertexShader, spv::ExecutionModelVertex); auto fragmentShaderModule = convertShaderModule(pixelShader, spv::ExecutionModelFragment); + m_device.nameObject(VK_OBJECT_TYPE_SHADER_MODULE, reinterpret_cast(vertexShaderModule), shaderName); + m_device.nameObject(VK_OBJECT_TYPE_SHADER_MODULE, reinterpret_cast(fragmentShaderModule), shaderName); + VkPipelineShaderStageCreateInfo vertexShaderStageInfo = {}; vertexShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; vertexShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; @@ -1082,6 +1130,53 @@ GameRenderer::bindPipeline(VkCommandBuffer commandBuffer, std::string_view passN return pipeline; } +std::vector compileGLSL(const std::string_view sourceString, const EShLanguage sourceLanguage) +{ + static bool ProcessInitialized = false; + + if (!ProcessInitialized) { + glslang::InitializeProcess(); + ProcessInitialized = true; + } + + const char *InputCString = sourceString.data(); + + glslang::TShader shader(sourceLanguage); + shader.setStrings(&InputCString, 1); + + int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100 + + shader.setEnvInput(glslang::EShSourceGlsl, sourceLanguage, glslang::EShClientVulkan, ClientInputSemanticsVersion); + + shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_3); + shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_6); + + if (!shader.parse(GetDefaultResources(), 100, false, EShMsgDefault)) { + return {}; + } + + glslang::TProgram Program; + Program.addShader(&shader); + + if (!Program.link(EShMsgDefault)) { + return {}; + } + + std::vector SpirV; + spv::SpvBuildLogger logger; + + glslang::SpvOptions spvOptions; + spvOptions.generateDebugInfo = true; + spvOptions.stripDebugInfo = false; + spvOptions.disableOptimizer = true; + spvOptions.emitNonSemanticShaderDebugSource = true; + spvOptions.emitNonSemanticShaderDebugInfo = true; + + glslang::GlslangToSpv(*Program.getIntermediate(sourceLanguage), SpirV, &logger, &spvOptions); + + return SpirV; +} + VkShaderModule GameRenderer::convertShaderModule(const physis_Shader &shader, spv::ExecutionModel executionModel) { dxvk::DxbcReader reader(reinterpret_cast(shader.bytecode), shader.len); @@ -1091,14 +1186,6 @@ VkShaderModule GameRenderer::convertShaderModule(const physis_Shader &shader, sp dxvk::DxbcModuleInfo info; auto result = module.compile(info, "test"); - VkShaderModuleCreateInfo createInfo = {}; - createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - createInfo.codeSize = result.code.size(); - createInfo.pCode = reinterpret_cast(result.code.data()); - - VkShaderModule shaderModule; - vkCreateShaderModule(m_device.device, &createInfo, nullptr, &shaderModule); - // TODO: for debug only spirv_cross::CompilerGLSL glsl(result.code.data(), result.code.dwords()); @@ -1106,6 +1193,23 @@ VkShaderModule GameRenderer::convertShaderModule(const physis_Shader &shader, sp int i = 0; for (auto texture : resources.stage_inputs) { + if (texture.name == "v0") { + glsl.set_name(texture.id, "Position"); + } else if (texture.name == "v1") { + glsl.set_name(texture.id, "Color"); + } else if (texture.name == "v2") { + glsl.set_name(texture.id, "Normal"); + } else if (texture.name == "v3") { + glsl.set_name(texture.id, "TexCoord"); + } else if (texture.name == "v4") { + glsl.set_name(texture.id, "Tangent"); + } else if (texture.name == "v5") { + glsl.set_name(texture.id, "Bitangent"); + } else if (texture.name == "v6") { + glsl.set_name(texture.id, "BoneWeight"); + } else if (texture.name == "v7") { + glsl.set_name(texture.id, "BoneId"); + } // glsl.set_name(texture.id, shader.) // qInfo() << shader.resource_parameters[i].name << texture.id; // qInfo() << "stage input" << i << texture.name << glsl.get_type(texture.type_id).width; @@ -1136,6 +1240,16 @@ VkShaderModule GameRenderer::convertShaderModule(const physis_Shader &shader, sp qInfo() << "Compiled GLSL:" << glsl.compile().c_str(); + auto newModule = compileGLSL(glsl.compile(), executionModel == spv::ExecutionModelVertex ? EShLanguage::EShLangVertex : EShLanguage::EShLangFragment); + + VkShaderModuleCreateInfo createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + createInfo.codeSize = newModule.size() * sizeof(uint32_t); + createInfo.pCode = reinterpret_cast(newModule.data()); + + VkShaderModule shaderModule; + vkCreateShaderModule(m_device.device, &createInfo, nullptr, &shaderModule); + return shaderModule; } @@ -1228,13 +1342,20 @@ GameRenderer::createDescriptorFor(const DrawObject *object, const CachedPipeline } else if (strcmp(name, "g_SamplerSpecular") == 0) { Q_ASSERT(material); info->imageView = material->specularTexture->imageView; + } else if (strcmp(name, "g_SamplerMask") == 0) { + Q_ASSERT(material); + info->imageView = material->multiTexture->imageView; } else if (strcmp(name, "g_SamplerTileNormal") == 0) { info->imageView = m_tileNormal.imageView; } else if (strcmp(name, "g_SamplerTileDiffuse") == 0) { info->imageView = m_tileDiffuse.imageView; } else if (strcmp(name, "g_SamplerTable") == 0) { Q_ASSERT(material); - info->imageView = material->tableTexture.imageView; + if (!material->tableTexture.has_value()) { + qWarning() << "Attempted to use table texture for a non-dyeable material. Something has went wrong!"; + } else { + info->imageView = material->tableTexture->imageView; + } } else { info->imageView = m_dummyTex.imageView; qInfo() << "Unknown image" << name; diff --git a/renderer/src/imguipass.cpp b/renderer/src/imguipass.cpp index e81888b..000a6fc 100644 --- a/renderer/src/imguipass.cpp +++ b/renderer/src/imguipass.cpp @@ -311,7 +311,7 @@ void ImGuiPass::createFontImage() texture.rgba = pixels; texture.rgba_size = width * height * 4; - auto tex = renderer_.addGameTexture(texture); + auto tex = renderer_.addGameTexture(VK_FORMAT_R8G8B8A8_UNORM, texture); fontImageView_ = tex.imageView; fontSampler_ = renderer_.defaultSampler(); diff --git a/renderer/src/rendermanager.cpp b/renderer/src/rendermanager.cpp index 4576b58..2c5e7dd 100644 --- a/renderer/src/rendermanager.cpp +++ b/renderer/src/rendermanager.cpp @@ -100,8 +100,11 @@ RenderManager::RenderManager(GameData *data) createInfo.ppEnabledExtensionNames = instanceExtensions.data(); createInfo.enabledExtensionCount = instanceExtensions.size(); createInfo.pApplicationInfo = &applicationInfo; - // createInfo.ppEnabledLayerNames = layers; - // createInfo.enabledLayerCount = 1; + + if (qgetenv("NOVUS_ENABLE_VALIDATION") == QByteArrayLiteral("1")) { + createInfo.ppEnabledLayerNames = layers; + createInfo.enabledLayerCount = 1; + } vkCreateInstance(&createInfo, nullptr, &m_device->instance); @@ -520,9 +523,9 @@ void RenderManager::reloadDrawObject(DrawObject &DrawObject, uint32_t lod) DrawObject.boneInfoBuffer = m_device->createBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); } -Texture RenderManager::addGameTexture(physis_Texture gameTexture) +Texture RenderManager::addGameTexture(VkFormat format, physis_Texture gameTexture) { - return m_device->addGameTexture(gameTexture); + return m_device->addGameTexture(format, gameTexture); } Device &RenderManager::device()