diff --git a/base/VulkanTools.cpp b/base/VulkanTools.cpp index 40783e78..947f56aa 100644 --- a/base/VulkanTools.cpp +++ b/base/VulkanTools.cpp @@ -19,11 +19,6 @@ const std::string getAssetPath() #endif } -const std::string getShadersPath() -{ - return getAssetPath() + "shaders/glsl/"; -} - namespace vks { namespace tools diff --git a/base/VulkanTools.h b/base/VulkanTools.h index d6b0fd6b..adccbf9f 100644 --- a/base/VulkanTools.h +++ b/base/VulkanTools.h @@ -60,7 +60,6 @@ #endif const std::string getAssetPath(); -const std::string getShadersPath(); namespace vks { diff --git a/base/vulkanexamplebase.cpp b/base/vulkanexamplebase.cpp index 2cfbfbfa..aee433d3 100644 --- a/base/vulkanexamplebase.cpp +++ b/base/vulkanexamplebase.cpp @@ -129,6 +129,11 @@ void VulkanExampleBase::destroyCommandBuffers() vkFreeCommandBuffers(device, cmdPool, static_cast(drawCmdBuffers.size()), drawCmdBuffers.data()); } +std::string VulkanExampleBase::getShadersPath() const +{ + return getAssetPath() + "shaders/" + shaderDir + "/"; +} + void VulkanExampleBase::createPipelineCache() { VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {}; @@ -642,6 +647,18 @@ VulkanExampleBase::VulkanExampleBase(bool enableValidation) uint32_t h = strtol(args[i + 1], &numConvPtr, 10); if (numConvPtr != args[i + 1]) { height = h; }; } + // Select between glsl and hlsl shaders + if ((args[i] == std::string("-s")) || (args[i] == std::string("--shaders"))) { + std::string type; + if (args.size() > i + 1) { + type = args[i + 1]; + } + if (type == "glsl" || type == "hlsl") { + shaderDir = type; + } else { + std::cerr << args[i] << " must be one of 'glsl' or 'hlsl'" << std::endl; + } + } // Benchmark if ((args[i] == std::string("-b")) || (args[i] == std::string("--benchmark"))) { benchmark.active = true; diff --git a/base/vulkanexamplebase.h b/base/vulkanexamplebase.h index 91f9beaf..dfbb203e 100644 --- a/base/vulkanexamplebase.h +++ b/base/vulkanexamplebase.h @@ -73,7 +73,11 @@ private: void setupSwapChain(); void createCommandBuffers(); void destroyCommandBuffers(); + std::string shaderDir = "glsl"; protected: + // Returns the path to the root of the glsl or hlsl shader directory. + std::string getShadersPath() const; + // Frame counter to display fps uint32_t frameCounter = 0; uint32_t lastFPS = 0; @@ -131,7 +135,7 @@ protected: VkSemaphore renderComplete; } semaphores; std::vector waitFences; -public: +public: bool prepared = false; uint32_t width = 1280; uint32_t height = 720; @@ -193,7 +197,7 @@ public: bool middle = false; } mouseButtons; - // OS specific + // OS specific #if defined(_WIN32) HWND window; HINSTANCE windowInstance; @@ -328,7 +332,7 @@ public: /** @brief Loads a SPIR-V shader file for the given shader stage */ VkPipelineShaderStageCreateInfo loadShader(std::string fileName, VkShaderStageFlagBits stage); - + /** @brief Entry point for the main render loop */ void renderLoop(); @@ -369,7 +373,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) \ vulkanExample->renderLoop(); \ delete(vulkanExample); \ return 0; \ -} +} #elif defined(VK_USE_PLATFORM_ANDROID_KHR) // Android entry point #define VULKAN_EXAMPLE_MAIN() \ diff --git a/examples/computeheadless/computeheadless.cpp b/examples/computeheadless/computeheadless.cpp index 11ee8c2f..1b1944bf 100644 --- a/examples/computeheadless/computeheadless.cpp +++ b/examples/computeheadless/computeheadless.cpp @@ -361,13 +361,18 @@ public: VkSpecializationMapEntry specializationMapEntry = vks::initializers::specializationMapEntry(0, 0, sizeof(uint32_t)); VkSpecializationInfo specializationInfo = vks::initializers::specializationInfo(1, &specializationMapEntry, sizeof(SpecializationData), &specializationData); + // TODO: There is no command line arguments parsing (nor Android settings) for this + // example, so we have no way of picking between GLSL or HLSL shaders. + // Hard-code to glsl for now. + const std::string shadersPath = getAssetPath() + "/shaders/glsl/computeheadless"; + VkPipelineShaderStageCreateInfo shaderStage = {}; shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; shaderStage.stage = VK_SHADER_STAGE_COMPUTE_BIT; #if defined(VK_USE_PLATFORM_ANDROID_KHR) - shaderStage.module = vks::tools::loadShader(androidapp->activity->assetManager, (getShadersPath() + "computeheadless/headless.comp.spv").c_str(), device); + shaderStage.module = vks::tools::loadShader(androidapp->activity->assetManager, (shadersPath + "headless.comp.spv").c_str(), device); #else - shaderStage.module = vks::tools::loadShader((getShadersPath() + "computeheadless/headless.comp.spv").c_str(), device); + shaderStage.module = vks::tools::loadShader((shadersPath + "headless.comp.spv").c_str(), device); #endif shaderStage.pName = "main"; shaderStage.pSpecializationInfo = &specializationInfo; diff --git a/examples/imgui/main.cpp b/examples/imgui/main.cpp index 8a2f72f3..f406015a 100644 --- a/examples/imgui/main.cpp +++ b/examples/imgui/main.cpp @@ -110,7 +110,7 @@ public: } // Initialize all Vulkan resources used by the ui - void initResources(VkRenderPass renderPass, VkQueue copyQueue) + void initResources(VkRenderPass renderPass, VkQueue copyQueue, const std::string& shadersPath) { ImGuiIO& io = ImGui::GetIO(); @@ -329,8 +329,8 @@ public: pipelineCreateInfo.pVertexInputState = &vertexInputState; - shaderStages[0] = example->loadShader(getShadersPath() + "imgui/ui.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); - shaderStages[1] = example->loadShader(getShadersPath() + "imgui/ui.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); + shaderStages[0] = example->loadShader(shadersPath + "imgui/ui.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); + shaderStages[1] = example->loadShader(shadersPath + "imgui/ui.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device->logicalDevice, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipeline)); } @@ -759,7 +759,7 @@ public: { imGui = new ImGUI(this); imGui->init((float)width, (float)height); - imGui->initResources(renderPass, queue); + imGui->initResources(renderPass, queue, getShadersPath()); } void prepare() diff --git a/examples/renderheadless/renderheadless.cpp b/examples/renderheadless/renderheadless.cpp index 24003fa7..e33d4330 100644 --- a/examples/renderheadless/renderheadless.cpp +++ b/examples/renderheadless/renderheadless.cpp @@ -591,6 +591,11 @@ public: pipelineCreateInfo.pVertexInputState = &vertexInputState; + // TODO: There is no command line arguments parsing (nor Android settings) for this + // example, so we have no way of picking between GLSL or HLSL shaders. + // Hard-code to glsl for now. + const std::string shadersPath = getAssetPath() + "/shaders/glsl/renderheadless"; + shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; shaderStages[0].pName = "main"; @@ -598,11 +603,11 @@ public: shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; shaderStages[1].pName = "main"; #if defined(VK_USE_PLATFORM_ANDROID_KHR) - shaderStages[0].module = vks::tools::loadShader(androidapp->activity->assetManager, (getShadersPath() + "renderheadless/triangle.vert.spv").c_str(), device); - shaderStages[1].module = vks::tools::loadShader(androidapp->activity->assetManager, (getShadersPath() + "renderheadless/triangle.frag.spv").c_str(), device); + shaderStages[0].module = vks::tools::loadShader(androidapp->activity->assetManager, (shadersPath + "triangle.vert.spv").c_str(), device); + shaderStages[1].module = vks::tools::loadShader(androidapp->activity->assetManager, (shadersPath + "triangle.frag.spv").c_str(), device); #else - shaderStages[0].module = vks::tools::loadShader((getShadersPath() + "renderheadless/triangle.vert.spv").c_str(), device); - shaderStages[1].module = vks::tools::loadShader((getShadersPath() + "renderheadless/triangle.frag.spv").c_str(), device); + shaderStages[0].module = vks::tools::loadShader((shadersPath + "triangle.vert.spv").c_str(), device); + shaderStages[1].module = vks::tools::loadShader((shadersPath + "triangle.frag.spv").c_str(), device); #endif shaderModules = { shaderStages[0].module, shaderStages[1].module }; VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipeline));