Merge branch 'master' into slang_shaders
This commit is contained in:
commit
02559cd99a
16 changed files with 71 additions and 75 deletions
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
|
@ -48,7 +48,7 @@ jobs:
|
||||||
|
|
||||||
build_macOS:
|
build_macOS:
|
||||||
name: Build macOS
|
name: Build macOS
|
||||||
runs-on: macos-13
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,11 @@ task copyTask {
|
||||||
include 'metalplate01_rgba.ktx'
|
include 'metalplate01_rgba.ktx'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
copy {
|
||||||
|
from rootProject.ext.assetPath + 'models'
|
||||||
|
into 'assets/models'
|
||||||
|
include 'plane_z.gltf'
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Platform specific macros for the example main entry points
|
* Platform specific macros for the example main entry points
|
||||||
*
|
*
|
||||||
* Copyright (C) 2024 by Sascha Willems - www.saschawillems.de
|
* Copyright (C) 2024-2025 by Sascha Willems - www.saschawillems.de
|
||||||
*
|
*
|
||||||
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||||
*/
|
*/
|
||||||
|
|
@ -42,12 +42,12 @@ int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance
|
||||||
VulkanExample *vulkanExample; \
|
VulkanExample *vulkanExample; \
|
||||||
void android_main(android_app* state) \
|
void android_main(android_app* state) \
|
||||||
{ \
|
{ \
|
||||||
|
androidApp = state; \
|
||||||
|
vks::android::getDeviceConfig(); \
|
||||||
vulkanExample = new VulkanExample(); \
|
vulkanExample = new VulkanExample(); \
|
||||||
state->userData = vulkanExample; \
|
state->userData = vulkanExample; \
|
||||||
state->onAppCmd = VulkanExample::handleAppCommand; \
|
state->onAppCmd = VulkanExample::handleAppCommand; \
|
||||||
state->onInputEvent = VulkanExample::handleAppInput; \
|
state->onInputEvent = VulkanExample::handleAppInput; \
|
||||||
androidApp = state; \
|
|
||||||
vks::android::getDeviceConfig(); \
|
|
||||||
vulkanExample->renderLoop(); \
|
vulkanExample->renderLoop(); \
|
||||||
delete(vulkanExample); \
|
delete(vulkanExample); \
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Android Vulkan function pointer loader
|
* Android Vulkan function pointer loader
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016-2024 by Sascha Willems - www.saschawillems.de
|
* Copyright (C) 2016-2025 by Sascha Willems - www.saschawillems.de
|
||||||
*
|
*
|
||||||
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||||
*/
|
*/
|
||||||
|
|
@ -359,7 +359,6 @@ namespace vks
|
||||||
jni->DeleteLocalRef(jmessage);
|
jni->DeleteLocalRef(jmessage);
|
||||||
|
|
||||||
androidApp->activity->vm->DetachCurrentThread();
|
androidApp->activity->vm->DetachCurrentThread();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Android Vulkan function pointer prototypes
|
* Android Vulkan function pointer prototypes
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016-2024 by Sascha Willems - www.saschawillems.de
|
* Copyright (C) 2016-2025 by Sascha Willems - www.saschawillems.de
|
||||||
*
|
*
|
||||||
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||||
*/
|
*/
|
||||||
|
|
@ -29,16 +29,6 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// Missing from the NDK
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
template<typename T, typename... Args>
|
|
||||||
std::unique_ptr<T> make_unique(Args&&... args)
|
|
||||||
{
|
|
||||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Global reference to android application object
|
// Global reference to android application object
|
||||||
extern android_app* androidApp;
|
extern android_app* androidApp;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ VkResult VulkanExampleBase::createInstance()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Enabled requested instance extensions
|
// Enabled requested instance extensions
|
||||||
if (enabledInstanceExtensions.size() > 0)
|
if (!enabledInstanceExtensions.empty())
|
||||||
{
|
{
|
||||||
for (const char * enabledExtension : enabledInstanceExtensions)
|
for (const char * enabledExtension : enabledInstanceExtensions)
|
||||||
{
|
{
|
||||||
|
|
@ -120,7 +120,7 @@ VkResult VulkanExampleBase::createInstance()
|
||||||
instanceExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
instanceExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instanceExtensions.size() > 0) {
|
if (!instanceExtensions.empty()) {
|
||||||
instanceCreateInfo.enabledExtensionCount = (uint32_t)instanceExtensions.size();
|
instanceCreateInfo.enabledExtensionCount = (uint32_t)instanceExtensions.size();
|
||||||
instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.data();
|
instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.data();
|
||||||
}
|
}
|
||||||
|
|
@ -316,7 +316,7 @@ void VulkanExampleBase::renderLoop()
|
||||||
|
|
||||||
benchmark.run([=] { render(); }, vulkanDevice->properties);
|
benchmark.run([=] { render(); }, vulkanDevice->properties);
|
||||||
vkDeviceWaitIdle(device);
|
vkDeviceWaitIdle(device);
|
||||||
if (benchmark.filename != "") {
|
if (!benchmark.filename.empty()) {
|
||||||
benchmark.saveResults();
|
benchmark.saveResults();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
@ -344,7 +344,7 @@ void VulkanExampleBase::renderLoop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
|
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||||
while (1)
|
while (true)
|
||||||
{
|
{
|
||||||
int ident;
|
int ident;
|
||||||
int events;
|
int events;
|
||||||
|
|
@ -353,9 +353,9 @@ void VulkanExampleBase::renderLoop()
|
||||||
|
|
||||||
focused = true;
|
focused = true;
|
||||||
|
|
||||||
while ((ident = ALooper_pollOnce(focused ? 0 : -1, NULL, &events, (void**)&source)) > ALOOPER_POLL_TIMEOUT)
|
while ((ident = ALooper_pollOnce(focused ? 0 : -1, nullptr, &events, (void**)&source)) > ALOOPER_POLL_TIMEOUT)
|
||||||
{
|
{
|
||||||
if (source != NULL)
|
if (source != nullptr)
|
||||||
{
|
{
|
||||||
source->process(androidApp, source);
|
source->process(androidApp, source);
|
||||||
}
|
}
|
||||||
|
|
@ -404,8 +404,6 @@ void VulkanExampleBase::renderLoop()
|
||||||
|
|
||||||
updateOverlay();
|
updateOverlay();
|
||||||
|
|
||||||
bool updateView = false;
|
|
||||||
|
|
||||||
// Check touch state (for movement)
|
// Check touch state (for movement)
|
||||||
if (touchDown) {
|
if (touchDown) {
|
||||||
touchTimer += frameTimer;
|
touchTimer += frameTimer;
|
||||||
|
|
@ -422,23 +420,20 @@ void VulkanExampleBase::renderLoop()
|
||||||
if (std::abs(gamePadState.axisLeft.x) > deadZone)
|
if (std::abs(gamePadState.axisLeft.x) > deadZone)
|
||||||
{
|
{
|
||||||
camera.rotate(glm::vec3(0.0f, gamePadState.axisLeft.x * 0.5f, 0.0f));
|
camera.rotate(glm::vec3(0.0f, gamePadState.axisLeft.x * 0.5f, 0.0f));
|
||||||
updateView = true;
|
|
||||||
}
|
}
|
||||||
if (std::abs(gamePadState.axisLeft.y) > deadZone)
|
if (std::abs(gamePadState.axisLeft.y) > deadZone)
|
||||||
{
|
{
|
||||||
camera.rotate(glm::vec3(gamePadState.axisLeft.y * 0.5f, 0.0f, 0.0f));
|
camera.rotate(glm::vec3(gamePadState.axisLeft.y * 0.5f, 0.0f, 0.0f));
|
||||||
updateView = true;
|
|
||||||
}
|
}
|
||||||
// Zoom
|
// Zoom
|
||||||
if (std::abs(gamePadState.axisRight.y) > deadZone)
|
if (std::abs(gamePadState.axisRight.y) > deadZone)
|
||||||
{
|
{
|
||||||
camera.translate(glm::vec3(0.0f, 0.0f, gamePadState.axisRight.y * 0.01f));
|
camera.translate(glm::vec3(0.0f, 0.0f, gamePadState.axisRight.y * 0.01f));
|
||||||
updateView = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
updateView = camera.updatePad(gamePadState.axisLeft, gamePadState.axisRight, frameTimer);
|
camera.updatePad(gamePadState.axisLeft, gamePadState.axisRight, frameTimer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -915,9 +910,9 @@ VulkanExampleBase::~VulkanExampleBase()
|
||||||
{
|
{
|
||||||
vkDestroyRenderPass(device, renderPass, nullptr);
|
vkDestroyRenderPass(device, renderPass, nullptr);
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < frameBuffers.size(); i++)
|
for (auto& frameBuffer : frameBuffers)
|
||||||
{
|
{
|
||||||
vkDestroyFramebuffer(device, frameBuffers[i], nullptr);
|
vkDestroyFramebuffer(device, frameBuffer, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& shaderModule : shaderModules)
|
for (auto& shaderModule : shaderModules)
|
||||||
|
|
@ -1509,7 +1504,6 @@ int32_t VulkanExampleBase::handleAppInput(struct android_app* app, AInputEvent*
|
||||||
{
|
{
|
||||||
int32_t keyCode = AKeyEvent_getKeyCode((const AInputEvent*)event);
|
int32_t keyCode = AKeyEvent_getKeyCode((const AInputEvent*)event);
|
||||||
int32_t action = AKeyEvent_getAction((const AInputEvent*)event);
|
int32_t action = AKeyEvent_getAction((const AInputEvent*)event);
|
||||||
int32_t button = 0;
|
|
||||||
|
|
||||||
if (action == AKEY_EVENT_ACTION_UP)
|
if (action == AKEY_EVENT_ACTION_UP)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1554,7 +1548,7 @@ int32_t VulkanExampleBase::handleAppInput(struct android_app* app, AInputEvent*
|
||||||
|
|
||||||
void VulkanExampleBase::handleAppCommand(android_app * app, int32_t cmd)
|
void VulkanExampleBase::handleAppCommand(android_app * app, int32_t cmd)
|
||||||
{
|
{
|
||||||
assert(app->userData != NULL);
|
assert(app->userData != nullptr);
|
||||||
VulkanExampleBase* vulkanExample = reinterpret_cast<VulkanExampleBase*>(app->userData);
|
VulkanExampleBase* vulkanExample = reinterpret_cast<VulkanExampleBase*>(app->userData);
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
|
|
@ -1568,7 +1562,7 @@ void VulkanExampleBase::handleAppCommand(android_app * app, int32_t cmd)
|
||||||
break;
|
break;
|
||||||
case APP_CMD_INIT_WINDOW:
|
case APP_CMD_INIT_WINDOW:
|
||||||
LOGD("APP_CMD_INIT_WINDOW");
|
LOGD("APP_CMD_INIT_WINDOW");
|
||||||
if (androidApp->window != NULL)
|
if (androidApp->window != nullptr)
|
||||||
{
|
{
|
||||||
if (vulkanExample->initVulkan()) {
|
if (vulkanExample->initVulkan()) {
|
||||||
vulkanExample->prepare();
|
vulkanExample->prepare();
|
||||||
|
|
@ -3195,8 +3189,8 @@ void VulkanExampleBase::windowResize()
|
||||||
vkDestroyImage(device, depthStencil.image, nullptr);
|
vkDestroyImage(device, depthStencil.image, nullptr);
|
||||||
vkFreeMemory(device, depthStencil.memory, nullptr);
|
vkFreeMemory(device, depthStencil.memory, nullptr);
|
||||||
setupDepthStencil();
|
setupDepthStencil();
|
||||||
for (uint32_t i = 0; i < frameBuffers.size(); i++) {
|
for (auto& frameBuffer : frameBuffers) {
|
||||||
vkDestroyFramebuffer(device, frameBuffers[i], nullptr);
|
vkDestroyFramebuffer(device, frameBuffer, nullptr);
|
||||||
}
|
}
|
||||||
setupFrameBuffer();
|
setupFrameBuffer();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,8 +77,8 @@ class VulkanExampleBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string getWindowTitle() const;
|
std::string getWindowTitle() const;
|
||||||
uint32_t destWidth;
|
uint32_t destWidth{};
|
||||||
uint32_t destHeight;
|
uint32_t destHeight{};
|
||||||
bool resizing = false;
|
bool resizing = false;
|
||||||
void handleMouseMove(int32_t x, int32_t y);
|
void handleMouseMove(int32_t x, int32_t y);
|
||||||
void nextFrame();
|
void nextFrame();
|
||||||
|
|
@ -122,13 +122,13 @@ protected:
|
||||||
// Handle to the device graphics queue that command buffers are submitted to
|
// Handle to the device graphics queue that command buffers are submitted to
|
||||||
VkQueue queue{ VK_NULL_HANDLE };
|
VkQueue queue{ VK_NULL_HANDLE };
|
||||||
// Depth buffer format (selected during Vulkan initialization)
|
// Depth buffer format (selected during Vulkan initialization)
|
||||||
VkFormat depthFormat;
|
VkFormat depthFormat{VK_FORMAT_UNDEFINED};
|
||||||
// Command buffer pool
|
// Command buffer pool
|
||||||
VkCommandPool cmdPool{ VK_NULL_HANDLE };
|
VkCommandPool cmdPool{ VK_NULL_HANDLE };
|
||||||
/** @brief Pipeline stages used to wait at for graphics queue submissions */
|
/** @brief Pipeline stages used to wait at for graphics queue submissions */
|
||||||
VkPipelineStageFlags submitPipelineStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
VkPipelineStageFlags submitPipelineStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
// Contains command buffers and semaphores to be presented to the queue
|
// Contains command buffers and semaphores to be presented to the queue
|
||||||
VkSubmitInfo submitInfo;
|
VkSubmitInfo submitInfo{};
|
||||||
// Command buffers used for rendering
|
// Command buffers used for rendering
|
||||||
std::vector<VkCommandBuffer> drawCmdBuffers;
|
std::vector<VkCommandBuffer> drawCmdBuffers;
|
||||||
// Global render pass for frame buffer writes
|
// Global render pass for frame buffer writes
|
||||||
|
|
@ -151,7 +151,7 @@ protected:
|
||||||
VkSemaphore presentComplete;
|
VkSemaphore presentComplete;
|
||||||
// Command buffer submission and execution
|
// Command buffer submission and execution
|
||||||
VkSemaphore renderComplete;
|
VkSemaphore renderComplete;
|
||||||
} semaphores;
|
} semaphores{};
|
||||||
std::vector<VkFence> waitFences;
|
std::vector<VkFence> waitFences;
|
||||||
bool requiresStencil{ false };
|
bool requiresStencil{ false };
|
||||||
public:
|
public:
|
||||||
|
|
@ -170,7 +170,7 @@ public:
|
||||||
vks::Benchmark benchmark;
|
vks::Benchmark benchmark;
|
||||||
|
|
||||||
/** @brief Encapsulated physical and logical vulkan device */
|
/** @brief Encapsulated physical and logical vulkan device */
|
||||||
vks::VulkanDevice *vulkanDevice;
|
vks::VulkanDevice *vulkanDevice{};
|
||||||
|
|
||||||
/** @brief Example settings that can be changed e.g. by command line arguments */
|
/** @brief Example settings that can be changed e.g. by command line arguments */
|
||||||
struct Settings {
|
struct Settings {
|
||||||
|
|
@ -234,7 +234,7 @@ public:
|
||||||
struct TouchPos {
|
struct TouchPos {
|
||||||
int32_t x;
|
int32_t x;
|
||||||
int32_t y;
|
int32_t y;
|
||||||
} touchPos;
|
} touchPos{};
|
||||||
bool touchDown = false;
|
bool touchDown = false;
|
||||||
double touchTimer = 0.0;
|
double touchTimer = 0.0;
|
||||||
int64_t lastTapTime = 0;
|
int64_t lastTapTime = 0;
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ public:
|
||||||
VkDeviceMemory memory{ VK_NULL_HANDLE };
|
VkDeviceMemory memory{ VK_NULL_HANDLE };
|
||||||
};
|
};
|
||||||
Image renderImage;
|
Image renderImage;
|
||||||
Image depthStencilRenderImage;
|
|
||||||
|
|
||||||
VulkanExample() : VulkanExampleBase()
|
VulkanExample() : VulkanExampleBase()
|
||||||
{
|
{
|
||||||
|
|
@ -67,7 +66,7 @@ public:
|
||||||
deviceCreatepNextChain = &enabledDynamicRenderingFeaturesKHR;
|
deviceCreatepNextChain = &enabledDynamicRenderingFeaturesKHR;
|
||||||
}
|
}
|
||||||
|
|
||||||
~VulkanExample()
|
~VulkanExample() override
|
||||||
{
|
{
|
||||||
if (device) {
|
if (device) {
|
||||||
vkDestroyPipeline(device, pipeline, nullptr);
|
vkDestroyPipeline(device, pipeline, nullptr);
|
||||||
|
|
@ -160,7 +159,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable physical device features required for this example
|
// Enable physical device features required for this example
|
||||||
virtual void getEnabledFeatures()
|
void getEnabledFeatures() override
|
||||||
{
|
{
|
||||||
// Enable anisotropic filtering if supported
|
// Enable anisotropic filtering if supported
|
||||||
if (deviceFeatures.samplerAnisotropy) {
|
if (deviceFeatures.samplerAnisotropy) {
|
||||||
|
|
@ -174,7 +173,7 @@ public:
|
||||||
model.loadFromFile(getAssetPath() + "models/voyager.gltf", vulkanDevice, queue, glTFLoadingFlags);
|
model.loadFromFile(getAssetPath() + "models/voyager.gltf", vulkanDevice, queue, glTFLoadingFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void buildCommandBuffers()
|
void buildCommandBuffers() override
|
||||||
{
|
{
|
||||||
VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo();
|
VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo();
|
||||||
|
|
||||||
|
|
@ -365,7 +364,7 @@ public:
|
||||||
memcpy(uniformBuffer.mapped, &uniformData, sizeof(uniformData));
|
memcpy(uniformBuffer.mapped, &uniformData, sizeof(uniformData));
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare()
|
void prepare() override
|
||||||
{
|
{
|
||||||
VulkanExampleBase::prepare();
|
VulkanExampleBase::prepare();
|
||||||
|
|
||||||
|
|
@ -390,7 +389,7 @@ public:
|
||||||
VulkanExampleBase::submitFrame();
|
VulkanExampleBase::submitFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void render()
|
void render() override
|
||||||
{
|
{
|
||||||
if (!prepared)
|
if (!prepared)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ public:
|
||||||
deviceCreatepNextChain = &enabledPhysicalDeviceHostImageCopyFeaturesEXT;
|
deviceCreatepNextChain = &enabledPhysicalDeviceHostImageCopyFeaturesEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
~VulkanExample()
|
~VulkanExample() override
|
||||||
{
|
{
|
||||||
if (device) {
|
if (device) {
|
||||||
destroyTextureImage(texture);
|
destroyTextureImage(texture);
|
||||||
|
|
@ -82,7 +82,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable physical device features required for this example
|
// Enable physical device features required for this example
|
||||||
virtual void getEnabledFeatures()
|
void getEnabledFeatures() override
|
||||||
{
|
{
|
||||||
// Enable anisotropic filtering if supported
|
// Enable anisotropic filtering if supported
|
||||||
if (deviceFeatures.samplerAnisotropy) {
|
if (deviceFeatures.samplerAnisotropy) {
|
||||||
|
|
@ -134,7 +134,6 @@ public:
|
||||||
texture.height = ktxTexture->baseHeight;
|
texture.height = ktxTexture->baseHeight;
|
||||||
texture.mipLevels = ktxTexture->numLevels;
|
texture.mipLevels = ktxTexture->numLevels;
|
||||||
ktx_uint8_t *ktxTextureData = ktxTexture_GetData(ktxTexture);
|
ktx_uint8_t *ktxTextureData = ktxTexture_GetData(ktxTexture);
|
||||||
ktx_size_t ktxTextureSize = ktxTexture_GetSize(ktxTexture);
|
|
||||||
|
|
||||||
const VkFormat imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
const VkFormat imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
|
||||||
|
|
@ -271,7 +270,7 @@ public:
|
||||||
vkFreeMemory(device, texture.deviceMemory, nullptr);
|
vkFreeMemory(device, texture.deviceMemory, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void buildCommandBuffers()
|
void buildCommandBuffers() override
|
||||||
{
|
{
|
||||||
VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo();
|
VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo();
|
||||||
|
|
||||||
|
|
@ -371,11 +370,11 @@ public:
|
||||||
VkPipelineMultisampleStateCreateInfo multisampleState = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0);
|
VkPipelineMultisampleStateCreateInfo multisampleState = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0);
|
||||||
std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
|
std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
|
||||||
VkPipelineDynamicStateCreateInfo dynamicState = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables);
|
VkPipelineDynamicStateCreateInfo dynamicState = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables);
|
||||||
std::array<VkPipelineShaderStageCreateInfo,2> shaderStages;
|
|
||||||
|
|
||||||
// Shaders
|
// Shaders
|
||||||
shaderStages[0] = loadShader(getShadersPath() + "texture/texture.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
|
std::array<VkPipelineShaderStageCreateInfo,2> shaderStages = {
|
||||||
shaderStages[1] = loadShader(getShadersPath() + "texture/texture.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
|
loadShader(getShadersPath() + "texture/texture.vert.spv", VK_SHADER_STAGE_VERTEX_BIT),
|
||||||
|
loadShader(getShadersPath() + "texture/texture.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT)
|
||||||
|
};
|
||||||
|
|
||||||
VkGraphicsPipelineCreateInfo pipelineCreateInfo = vks::initializers::pipelineCreateInfo(pipelineLayout, renderPass, 0);
|
VkGraphicsPipelineCreateInfo pipelineCreateInfo = vks::initializers::pipelineCreateInfo(pipelineLayout, renderPass, 0);
|
||||||
pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
|
pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
|
||||||
|
|
@ -413,14 +412,14 @@ public:
|
||||||
plane.loadFromFile(getAssetPath() + "models/plane_z.gltf", vulkanDevice, queue, glTFLoadingFlags);
|
plane.loadFromFile(getAssetPath() + "models/plane_z.gltf", vulkanDevice, queue, glTFLoadingFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare()
|
void prepare() override
|
||||||
{
|
{
|
||||||
VulkanExampleBase::prepare();
|
VulkanExampleBase::prepare();
|
||||||
|
|
||||||
// Get the function pointers required host image copies
|
// Get the function pointers required host image copies
|
||||||
vkCopyMemoryToImageEXT = reinterpret_cast<PFN_vkCopyMemoryToImageEXT>(vkGetDeviceProcAddr(device, "vkCopyMemoryToImageEXT"));
|
vkCopyMemoryToImageEXT = reinterpret_cast<PFN_vkCopyMemoryToImageEXT>(vkGetDeviceProcAddr(device, "vkCopyMemoryToImageEXT"));
|
||||||
vkTransitionImageLayoutEXT = reinterpret_cast<PFN_vkTransitionImageLayoutEXT>(vkGetDeviceProcAddr(device, "vkTransitionImageLayoutEXT"));
|
vkTransitionImageLayoutEXT = reinterpret_cast<PFN_vkTransitionImageLayoutEXT>(vkGetDeviceProcAddr(device, "vkTransitionImageLayoutEXT"));
|
||||||
vkGetPhysicalDeviceFormatProperties2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties2>(vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2"));
|
vkGetPhysicalDeviceFormatProperties2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties2>(vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2KHR"));
|
||||||
|
|
||||||
loadAssets();
|
loadAssets();
|
||||||
loadTexture();
|
loadTexture();
|
||||||
|
|
@ -440,7 +439,7 @@ public:
|
||||||
VulkanExampleBase::submitFrame();
|
VulkanExampleBase::submitFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void render()
|
void render() override
|
||||||
{
|
{
|
||||||
if (!prepared)
|
if (!prepared)
|
||||||
return;
|
return;
|
||||||
|
|
@ -448,7 +447,7 @@ public:
|
||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
|
void OnUpdateUIOverlay(vks::UIOverlay *overlay) override
|
||||||
{
|
{
|
||||||
if (overlay->header("Settings")) {
|
if (overlay->header("Settings")) {
|
||||||
if (overlay->sliderFloat("LOD bias", &uniformData.lodBias, 0.0f, (float)texture.mipLevels)) {
|
if (overlay->sliderFloat("LOD bias", &uniformData.lodBias, 0.0f, (float)texture.mipLevels)) {
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,8 @@ public:
|
||||||
camera.setRotation(glm::vec3(0.5f, 210.05f, 0.0f));
|
camera.setRotation(glm::vec3(0.5f, 210.05f, 0.0f));
|
||||||
camera.setPerspective(60.0f, (float)width / (float)height, 0.1f, 256.0f);
|
camera.setPerspective(60.0f, (float)width / (float)height, 0.1f, 256.0f);
|
||||||
ui.subpass = 2;
|
ui.subpass = 2;
|
||||||
|
|
||||||
|
enabledFeatures.fragmentStoresAndAtomics = VK_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
~VulkanExample()
|
~VulkanExample()
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
* Contrary to the other examples, this one won't make use of helper functions or initializers
|
* Contrary to the other examples, this one won't make use of helper functions or initializers
|
||||||
* Except in a few cases (swap chain setup e.g.)
|
* Except in a few cases (swap chain setup e.g.)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016-2024 by Sascha Willems - www.saschawillems.de
|
* Copyright (C) 2016-2025 by Sascha Willems - www.saschawillems.de
|
||||||
*
|
*
|
||||||
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||||
*/
|
*/
|
||||||
|
|
@ -126,7 +126,7 @@ public:
|
||||||
// Values not set here are initialized in the base class constructor
|
// Values not set here are initialized in the base class constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
~VulkanExample()
|
~VulkanExample() override
|
||||||
{
|
{
|
||||||
// Clean up used Vulkan resources
|
// Clean up used Vulkan resources
|
||||||
// Note: Inherited destructor cleans up resources stored in base class
|
// Note: Inherited destructor cleans up resources stored in base class
|
||||||
|
|
@ -452,7 +452,7 @@ public:
|
||||||
|
|
||||||
// Create the depth (and stencil) buffer attachments used by our framebuffers
|
// Create the depth (and stencil) buffer attachments used by our framebuffers
|
||||||
// Note: Override of virtual function in the base class and called from within VulkanExampleBase::prepare
|
// Note: Override of virtual function in the base class and called from within VulkanExampleBase::prepare
|
||||||
void setupDepthStencil()
|
void setupDepthStencil() override
|
||||||
{
|
{
|
||||||
// Create an optimal image used as the depth stencil attachment
|
// Create an optimal image used as the depth stencil attachment
|
||||||
VkImageCreateInfo imageCI{};
|
VkImageCreateInfo imageCI{};
|
||||||
|
|
@ -502,7 +502,7 @@ public:
|
||||||
|
|
||||||
// Create a frame buffer for each swap chain image
|
// Create a frame buffer for each swap chain image
|
||||||
// Note: Override of virtual function in the base class and called from within VulkanExampleBase::prepare
|
// Note: Override of virtual function in the base class and called from within VulkanExampleBase::prepare
|
||||||
void setupFrameBuffer()
|
void setupFrameBuffer() override
|
||||||
{
|
{
|
||||||
// Create a frame buffer for every image in the swapchain
|
// Create a frame buffer for every image in the swapchain
|
||||||
frameBuffers.resize(swapChain.images.size());
|
frameBuffers.resize(swapChain.images.size());
|
||||||
|
|
@ -533,7 +533,7 @@ public:
|
||||||
// This allows the driver to know up-front what the rendering will look like and is a good opportunity to optimize especially on tile-based renderers (with multiple subpasses)
|
// This allows the driver to know up-front what the rendering will look like and is a good opportunity to optimize especially on tile-based renderers (with multiple subpasses)
|
||||||
// Using sub pass dependencies also adds implicit layout transitions for the attachment used, so we don't need to add explicit image memory barriers to transform them
|
// Using sub pass dependencies also adds implicit layout transitions for the attachment used, so we don't need to add explicit image memory barriers to transform them
|
||||||
// Note: Override of virtual function in the base class and called from within VulkanExampleBase::prepare
|
// Note: Override of virtual function in the base class and called from within VulkanExampleBase::prepare
|
||||||
void setupRenderPass()
|
void setupRenderPass() override
|
||||||
{
|
{
|
||||||
// This example will use a single render pass with one subpass
|
// This example will use a single render pass with one subpass
|
||||||
|
|
||||||
|
|
@ -622,7 +622,7 @@ public:
|
||||||
// Vulkan loads its shaders from an immediate binary representation called SPIR-V
|
// Vulkan loads its shaders from an immediate binary representation called SPIR-V
|
||||||
// Shaders are compiled offline from e.g. GLSL using the reference glslang compiler
|
// Shaders are compiled offline from e.g. GLSL using the reference glslang compiler
|
||||||
// This function loads such a shader from a binary file and returns a shader module structure
|
// This function loads such a shader from a binary file and returns a shader module structure
|
||||||
VkShaderModule loadSPIRVShader(std::string filename)
|
VkShaderModule loadSPIRVShader(const std::string& filename)
|
||||||
{
|
{
|
||||||
size_t shaderSize;
|
size_t shaderSize;
|
||||||
char* shaderCode{ nullptr };
|
char* shaderCode{ nullptr };
|
||||||
|
|
@ -886,7 +886,7 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare()
|
void prepare() override
|
||||||
{
|
{
|
||||||
VulkanExampleBase::prepare();
|
VulkanExampleBase::prepare();
|
||||||
createSynchronizationPrimitives();
|
createSynchronizationPrimitives();
|
||||||
|
|
@ -900,7 +900,7 @@ public:
|
||||||
prepared = true;
|
prepared = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void render()
|
void render() override
|
||||||
{
|
{
|
||||||
if (!prepared)
|
if (!prepared)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ public:
|
||||||
deviceCreatepNextChain = &enabledFeatures;
|
deviceCreatepNextChain = &enabledFeatures;
|
||||||
}
|
}
|
||||||
|
|
||||||
~VulkanExample()
|
~VulkanExample() override
|
||||||
{
|
{
|
||||||
// Clean up used Vulkan resources
|
// Clean up used Vulkan resources
|
||||||
// Note: Inherited destructor cleans up resources stored in base class
|
// Note: Inherited destructor cleans up resources stored in base class
|
||||||
|
|
@ -140,6 +140,14 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void getEnabledFeatures() override
|
||||||
|
{
|
||||||
|
// Vulkan 1.3 device support is required for this example
|
||||||
|
if (deviceProperties.apiVersion < VK_API_VERSION_1_3) {
|
||||||
|
vks::tools::exitFatal("Selected GPU does not support support Vulkan 1.3", VK_ERROR_INCOMPATIBLE_DRIVER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This function is used to request a device memory type that supports all the property flags we request (e.g. device local, host visible)
|
// This function is used to request a device memory type that supports all the property flags we request (e.g. device local, host visible)
|
||||||
// Upon success it will return the index of the memory type that fits our requested memory properties
|
// Upon success it will return the index of the memory type that fits our requested memory properties
|
||||||
// This is necessary as implementations can offer an arbitrary number of memory types with different memory properties
|
// This is necessary as implementations can offer an arbitrary number of memory types with different memory properties
|
||||||
|
|
@ -381,7 +389,7 @@ public:
|
||||||
|
|
||||||
// Create the depth (and stencil) buffer attachments
|
// Create the depth (and stencil) buffer attachments
|
||||||
// While we don't do any depth testing in this sample, having depth testing is very common so it's a good idea to learn it from the very start
|
// While we don't do any depth testing in this sample, having depth testing is very common so it's a good idea to learn it from the very start
|
||||||
void setupDepthStencil()
|
void setupDepthStencil() override
|
||||||
{
|
{
|
||||||
// Create an optimal tiled image used as the depth stencil attachment
|
// Create an optimal tiled image used as the depth stencil attachment
|
||||||
VkImageCreateInfo imageCI{ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
|
VkImageCreateInfo imageCI{ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
|
||||||
|
|
@ -428,7 +436,7 @@ public:
|
||||||
// Vulkan loads its shaders from an immediate binary representation called SPIR-V
|
// Vulkan loads its shaders from an immediate binary representation called SPIR-V
|
||||||
// Shaders are compiled offline from e.g. GLSL using the reference glslang compiler
|
// Shaders are compiled offline from e.g. GLSL using the reference glslang compiler
|
||||||
// This function loads such a shader from a binary file and returns a shader module structure
|
// This function loads such a shader from a binary file and returns a shader module structure
|
||||||
VkShaderModule loadSPIRVShader(std::string filename)
|
VkShaderModule loadSPIRVShader(const std::string& filename)
|
||||||
{
|
{
|
||||||
size_t shaderSize;
|
size_t shaderSize;
|
||||||
char* shaderCode{ nullptr };
|
char* shaderCode{ nullptr };
|
||||||
|
|
@ -661,7 +669,7 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare()
|
void prepare() override
|
||||||
{
|
{
|
||||||
VulkanExampleBase::prepare();
|
VulkanExampleBase::prepare();
|
||||||
createSynchronizationPrimitives();
|
createSynchronizationPrimitives();
|
||||||
|
|
@ -673,7 +681,7 @@ public:
|
||||||
prepared = true;
|
prepared = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void render() override
|
void render() override
|
||||||
{
|
{
|
||||||
// Use a fence to wait until the command buffer has finished execution before using it again
|
// Use a fence to wait until the command buffer has finished execution before using it again
|
||||||
vkWaitForFences(device, 1, &waitFences[currentFrame], VK_TRUE, UINT64_MAX);
|
vkWaitForFences(device, 1, &waitFences[currentFrame], VK_TRUE, UINT64_MAX);
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue