mirror of
https://github.com/KhronosGroup/Vulkan-Hpp.git
synced 2024-10-14 16:32:17 +00:00
Add samples ImmutableSampler, InitTexture, InputAttachment (#315)
+ slightly adjust some other samples.
This commit is contained in:
parent
d4ddb0a2cd
commit
d965a74cc0
@ -25,6 +25,7 @@ set(SOURCES
|
|||||||
11_InitShaders.cpp
|
11_InitShaders.cpp
|
||||||
../utils/shaders.cpp
|
../utils/shaders.cpp
|
||||||
../utils/utils.cpp
|
../utils/utils.cpp
|
||||||
|
../../glslang/StandAlone/ResourceLimits.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group(headers FILES ${HEADERS})
|
source_group(headers FILES ${HEADERS})
|
||||||
|
@ -28,6 +28,7 @@ set(SOURCES
|
|||||||
../utils/math.cpp
|
../utils/math.cpp
|
||||||
../utils/shaders.cpp
|
../utils/shaders.cpp
|
||||||
../utils/utils.cpp
|
../utils/utils.cpp
|
||||||
|
../../glslang/StandAlone/ResourceLimits.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group(headers FILES ${HEADERS})
|
source_group(headers FILES ${HEADERS})
|
||||||
|
@ -28,6 +28,7 @@ set(SOURCES
|
|||||||
../utils/math.cpp
|
../utils/math.cpp
|
||||||
../utils/shaders.cpp
|
../utils/shaders.cpp
|
||||||
../utils/utils.cpp
|
../utils/utils.cpp
|
||||||
|
../../glslang/StandAlone/ResourceLimits.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group(headers FILES ${HEADERS})
|
source_group(headers FILES ${HEADERS})
|
||||||
|
@ -28,6 +28,7 @@ set(SOURCES
|
|||||||
../utils/math.cpp
|
../utils/math.cpp
|
||||||
../utils/shaders.cpp
|
../utils/shaders.cpp
|
||||||
../utils/utils.cpp
|
../utils/utils.cpp
|
||||||
|
../../glslang/StandAlone/ResourceLimits.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group(headers FILES ${HEADERS})
|
source_group(headers FILES ${HEADERS})
|
||||||
|
@ -26,101 +26,6 @@
|
|||||||
static char const* AppName = "DrawTexturedCube";
|
static char const* AppName = "DrawTexturedCube";
|
||||||
static char const* EngineName = "Vulkan.hpp";
|
static char const* EngineName = "Vulkan.hpp";
|
||||||
|
|
||||||
// vertex shader with (P)osition and (T)exCoord in and (T)exCoord out
|
|
||||||
const std::string vertexShaderText_PT_T = R"(
|
|
||||||
#version 400
|
|
||||||
|
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
|
||||||
#extension GL_ARB_shading_language_420pack : enable
|
|
||||||
|
|
||||||
layout (std140, binding = 0) uniform buffer
|
|
||||||
{
|
|
||||||
mat4 mvp;
|
|
||||||
} uniformBuffer;
|
|
||||||
|
|
||||||
layout (location = 0) in vec4 pos;
|
|
||||||
layout (location = 1) in vec2 inTexCoord;
|
|
||||||
|
|
||||||
layout (location = 0) out vec2 outTexCoord;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
outTexCoord = inTexCoord;
|
|
||||||
gl_Position = uniformBuffer.mvp * pos;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
// fragment shader with (T)exCoord in and (C)olor out
|
|
||||||
const std::string fragmentShaderText_T_C = R"(
|
|
||||||
#version 400
|
|
||||||
|
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
|
||||||
#extension GL_ARB_shading_language_420pack : enable
|
|
||||||
|
|
||||||
layout (binding = 1) uniform sampler2D tex;
|
|
||||||
|
|
||||||
layout (location = 0) in vec2 inTexCoord;
|
|
||||||
|
|
||||||
layout (location = 0) out vec4 outColor;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
outColor = textureLod(tex, inTexCoord, 0.0f);
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
struct VertexPT
|
|
||||||
{
|
|
||||||
float x, y, z, w; // Position data
|
|
||||||
float u, v; // texture u,v
|
|
||||||
};
|
|
||||||
|
|
||||||
static const VertexPT texturedCubeData[] =
|
|
||||||
{
|
|
||||||
// left face
|
|
||||||
{ -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f },
|
|
||||||
{ -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f },
|
|
||||||
{ -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f },
|
|
||||||
{ -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f },
|
|
||||||
{ -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f },
|
|
||||||
{ -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f },
|
|
||||||
// front face
|
|
||||||
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f },
|
|
||||||
{ 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f },
|
|
||||||
{ 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f },
|
|
||||||
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f },
|
|
||||||
{ 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f },
|
|
||||||
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
|
|
||||||
// top face
|
|
||||||
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
|
|
||||||
{ 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f },
|
|
||||||
{ 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f },
|
|
||||||
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
|
|
||||||
{ -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f },
|
|
||||||
{ 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f },
|
|
||||||
// bottom face
|
|
||||||
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f },
|
|
||||||
{ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f },
|
|
||||||
{ -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f },
|
|
||||||
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f },
|
|
||||||
{ 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f },
|
|
||||||
{ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f },
|
|
||||||
// right face
|
|
||||||
{ 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
|
|
||||||
{ 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f },
|
|
||||||
{ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f },
|
|
||||||
{ 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f },
|
|
||||||
{ 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
|
|
||||||
{ 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f },
|
|
||||||
// back face
|
|
||||||
{ -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f },
|
|
||||||
{ 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f },
|
|
||||||
{ -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f },
|
|
||||||
{ -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f },
|
|
||||||
{ 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f },
|
|
||||||
{ 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f },
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int /*argc*/, char ** /*argv*/)
|
int main(int /*argc*/, char ** /*argv*/)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -28,6 +28,7 @@ set(SOURCES
|
|||||||
../utils/math.cpp
|
../utils/math.cpp
|
||||||
../utils/shaders.cpp
|
../utils/shaders.cpp
|
||||||
../utils/utils.cpp
|
../utils/utils.cpp
|
||||||
|
../../glslang/StandAlone/ResourceLimits.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group(headers FILES ${HEADERS})
|
source_group(headers FILES ${HEADERS})
|
||||||
|
@ -17,16 +17,11 @@ cmake_minimum_required(VERSION 3.2)
|
|||||||
project(Events)
|
project(Events)
|
||||||
|
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
../utils/geometries.hpp
|
|
||||||
../utils/math.hpp
|
|
||||||
../utils/shaders.hpp
|
|
||||||
../utils/utils.hpp
|
../utils/utils.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
Events.cpp
|
Events.cpp
|
||||||
../utils/math.cpp
|
|
||||||
../utils/shaders.cpp
|
|
||||||
../utils/utils.cpp
|
../utils/utils.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,9 +15,6 @@
|
|||||||
// VulkanHpp Samples : Events
|
// VulkanHpp Samples : Events
|
||||||
// Use basic events
|
// Use basic events
|
||||||
|
|
||||||
#include "../utils/geometries.hpp"
|
|
||||||
#include "../utils/math.hpp"
|
|
||||||
#include "../utils/shaders.hpp"
|
|
||||||
#include "../utils/utils.hpp"
|
#include "../utils/utils.hpp"
|
||||||
#include "vulkan/vulkan.hpp"
|
#include "vulkan/vulkan.hpp"
|
||||||
#include "SPIRV/GlslangToSpv.h"
|
#include "SPIRV/GlslangToSpv.h"
|
||||||
@ -84,7 +81,7 @@ int main(int /*argc*/, char ** /*argv*/)
|
|||||||
device->resetFences(fence.get());
|
device->resetFences(fence.get());
|
||||||
|
|
||||||
// Note that stepping through this code in the debugger is a bad idea because the GPU can TDR waiting for the event.
|
// Note that stepping through this code in the debugger is a bad idea because the GPU can TDR waiting for the event.
|
||||||
// Execute the code from vkQueueSubmit through vkSetEvent without breakpoints
|
// Execute the code from vk::Queue::submit() through vk::Device::setEvent() without breakpoints
|
||||||
waitDestinationStageMask = vk::PipelineStageFlagBits::eBottomOfPipe;
|
waitDestinationStageMask = vk::PipelineStageFlagBits::eBottomOfPipe;
|
||||||
graphicsQueue.submit(submitInfo, fence.get());
|
graphicsQueue.submit(submitInfo, fence.get());
|
||||||
|
|
||||||
@ -92,7 +89,7 @@ int main(int /*argc*/, char ** /*argv*/)
|
|||||||
result = device->waitForFences(fence.get(), true, vk::su::FenceTimeout);
|
result = device->waitForFences(fence.get(), true, vk::su::FenceTimeout);
|
||||||
if (result != vk::Result::eTimeout)
|
if (result != vk::Result::eTimeout)
|
||||||
{
|
{
|
||||||
std::cout << "Didn't get expected timeout in vkWaitForFences, exiting\n";
|
std::cout << "Didn't get expected timeout in vk::Device::waitForFences, exiting\n";
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +111,7 @@ int main(int /*argc*/, char ** /*argv*/)
|
|||||||
commandBuffers[0]->setEvent(event.get(), vk::PipelineStageFlagBits::eBottomOfPipe);
|
commandBuffers[0]->setEvent(event.get(), vk::PipelineStageFlagBits::eBottomOfPipe);
|
||||||
commandBuffers[0]->end();
|
commandBuffers[0]->end();
|
||||||
|
|
||||||
// Look for the event on the CPU. It should be RESET since we haven't sent the command buffer yet.
|
// Look for the event on the CPU. It should be vk::Result::eEventReset since we haven't sent the command buffer yet.
|
||||||
result = device->getEventStatus(event.get());
|
result = device->getEventStatus(event.get());
|
||||||
assert(result == vk::Result::eEventReset);
|
assert(result == vk::Result::eEventReset);
|
||||||
|
|
||||||
|
45
samples/ImmutableSampler/CMakeLists.txt
Normal file
45
samples/ImmutableSampler/CMakeLists.txt
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# Copyright(c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.2)
|
||||||
|
|
||||||
|
project(ImmutableSampler)
|
||||||
|
|
||||||
|
set(HEADERS
|
||||||
|
../utils/geometries.hpp
|
||||||
|
../utils/math.hpp
|
||||||
|
../utils/shaders.hpp
|
||||||
|
../utils/utils.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
ImmutableSampler.cpp
|
||||||
|
../utils/math.cpp
|
||||||
|
../utils/shaders.cpp
|
||||||
|
../utils/utils.cpp
|
||||||
|
../../glslang/StandAlone/ResourceLimits.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
source_group(headers FILES ${HEADERS})
|
||||||
|
source_group(sources FILES ${SOURCES})
|
||||||
|
|
||||||
|
add_executable(ImmutableSampler
|
||||||
|
${HEADERS}
|
||||||
|
${SOURCES}
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(ImmutableSampler PROPERTIES FOLDER "Samples")
|
||||||
|
target_include_directories(ImmutableSampler PUBLIC ${CMAKE_SOURCE_DIR}/glslang)
|
||||||
|
target_link_libraries(ImmutableSampler PUBLIC glslang SPIRV "$ENV{VULKAN_SDK}/Lib/vulkan-1.lib"
|
||||||
|
)
|
168
samples/ImmutableSampler/ImmutableSampler.cpp
Normal file
168
samples/ImmutableSampler/ImmutableSampler.cpp
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
// Copyright(c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
// VulkanHpp Samples : ImmutableSampler
|
||||||
|
// Use an immutable sampler to texture a cube.
|
||||||
|
|
||||||
|
#include "../utils/geometries.hpp"
|
||||||
|
#include "../utils/math.hpp"
|
||||||
|
#include "../utils/shaders.hpp"
|
||||||
|
#include "../utils/utils.hpp"
|
||||||
|
#include "vulkan/vulkan.hpp"
|
||||||
|
#include "SPIRV/GlslangToSpv.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
static char const* AppName = "ImmutableSampler";
|
||||||
|
static char const* EngineName = "Vulkan.hpp";
|
||||||
|
|
||||||
|
int main(int /*argc*/, char ** /*argv*/)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName, vk::su::getInstanceExtensions());
|
||||||
|
#if !defined(NDEBUG)
|
||||||
|
vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
|
||||||
|
assert(!physicalDevices.empty());
|
||||||
|
|
||||||
|
vk::su::SurfaceData surfaceData(instance, AppName, AppName, vk::Extent2D(500, 500));
|
||||||
|
|
||||||
|
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex = vk::su::findGraphicsAndPresentQueueFamilyIndex(physicalDevices[0], surfaceData.surface);
|
||||||
|
vk::UniqueDevice device = vk::su::createDevice(physicalDevices[0], graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions());
|
||||||
|
|
||||||
|
vk::UniqueCommandPool commandPool = vk::su::createCommandPool(device, graphicsAndPresentQueueFamilyIndex.first);
|
||||||
|
std::vector<vk::UniqueCommandBuffer> commandBuffers = device->allocateCommandBuffersUnique(vk::CommandBufferAllocateInfo(commandPool.get(), vk::CommandBufferLevel::ePrimary, 1));
|
||||||
|
|
||||||
|
vk::Queue graphicsQueue = device->getQueue(graphicsAndPresentQueueFamilyIndex.first, 0);
|
||||||
|
vk::Queue presentQueue = device->getQueue(graphicsAndPresentQueueFamilyIndex.second, 0);
|
||||||
|
|
||||||
|
vk::su::SwapChainData swapChainData(physicalDevices[0], device, surfaceData.surface, surfaceData.extent, vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferSrc
|
||||||
|
, graphicsAndPresentQueueFamilyIndex.first, graphicsAndPresentQueueFamilyIndex.second);
|
||||||
|
|
||||||
|
vk::su::DepthBufferData depthBufferData(physicalDevices[0], device, vk::Format::eD16Unorm, surfaceData.extent);
|
||||||
|
|
||||||
|
vk::su::BufferData uniformBufferData(physicalDevices[0], device, sizeof(glm::mat4x4), vk::BufferUsageFlagBits::eUniformBuffer);
|
||||||
|
vk::su::copyToDevice(device, uniformBufferData.deviceMemory, vk::su::createModelViewProjectionClipMatrix());
|
||||||
|
|
||||||
|
vk::UniqueRenderPass renderPass = vk::su::createRenderPass(device, vk::su::pickColorFormat(physicalDevices[0].getSurfaceFormatsKHR(surfaceData.surface.get())), depthBufferData.format);
|
||||||
|
|
||||||
|
glslang::InitializeProcess();
|
||||||
|
vk::UniqueShaderModule vertexShaderModule = vk::su::createShaderModule(device, vk::ShaderStageFlagBits::eVertex, vertexShaderText_PT_T);
|
||||||
|
vk::UniqueShaderModule fragmentShaderModule = vk::su::createShaderModule(device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText_T_C);
|
||||||
|
glslang::FinalizeProcess();
|
||||||
|
|
||||||
|
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(device, renderPass, swapChainData.imageViews, depthBufferData.imageView, surfaceData.extent);
|
||||||
|
|
||||||
|
vk::su::BufferData vertexBufferData(physicalDevices[0], device, sizeof(texturedCubeData), vk::BufferUsageFlagBits::eVertexBuffer);
|
||||||
|
vk::su::copyToDevice(device, vertexBufferData.deviceMemory, texturedCubeData, sizeof(texturedCubeData) / sizeof(texturedCubeData[0]));
|
||||||
|
|
||||||
|
/* VULKAN_KEY_START */
|
||||||
|
|
||||||
|
vk::su::TextureData textureData(physicalDevices[0], device);
|
||||||
|
|
||||||
|
commandBuffers[0]->begin(vk::CommandBufferBeginInfo());
|
||||||
|
textureData.setCheckerboardTexture(device, commandBuffers[0]);
|
||||||
|
|
||||||
|
vk::DescriptorSetLayoutBinding bindings[2] =
|
||||||
|
{
|
||||||
|
vk::DescriptorSetLayoutBinding(0, vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex),
|
||||||
|
vk::DescriptorSetLayoutBinding(1, vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment, &textureData.textureSampler.get())
|
||||||
|
};
|
||||||
|
vk::UniqueDescriptorSetLayout descriptorSetLayout = device->createDescriptorSetLayoutUnique(vk::DescriptorSetLayoutCreateInfo(vk::DescriptorSetLayoutCreateFlags(), 2, bindings));
|
||||||
|
|
||||||
|
// Create pipeline layout
|
||||||
|
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(vk::PipelineLayoutCreateInfo(vk::PipelineLayoutCreateFlags(), 1, &descriptorSetLayout.get()));
|
||||||
|
|
||||||
|
// Create a single pool to contain data for our descriptor set
|
||||||
|
vk::DescriptorPoolSize poolSizes[2] =
|
||||||
|
{
|
||||||
|
vk::DescriptorPoolSize(vk::DescriptorType::eUniformBuffer, 1),
|
||||||
|
vk::DescriptorPoolSize(vk::DescriptorType::eCombinedImageSampler, 1)
|
||||||
|
};
|
||||||
|
vk::UniqueDescriptorPool descriptorPool = device->createDescriptorPoolUnique(vk::DescriptorPoolCreateInfo(vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, 1, 2, poolSizes));
|
||||||
|
|
||||||
|
// Populate descriptor sets
|
||||||
|
std::vector<vk::UniqueDescriptorSet> descriptorSets = device->allocateDescriptorSetsUnique(vk::DescriptorSetAllocateInfo(descriptorPool.get(), 1, &descriptorSetLayout.get()));
|
||||||
|
|
||||||
|
vk::DescriptorBufferInfo bufferInfo(uniformBufferData.buffer.get(), 0, sizeof(glm::mat4x4));
|
||||||
|
vk::DescriptorImageInfo imageInfo(textureData.textureSampler.get(), textureData.imageData->imageView.get(), vk::ImageLayout::eShaderReadOnlyOptimal);
|
||||||
|
vk::WriteDescriptorSet writeDescriptorSets[2] =
|
||||||
|
{
|
||||||
|
vk::WriteDescriptorSet(descriptorSets[0].get(), 0, 0, 1, vk::DescriptorType::eUniformBuffer, nullptr, &bufferInfo),
|
||||||
|
vk::WriteDescriptorSet(descriptorSets[0].get(), 1, 0, 1, vk::DescriptorType::eCombinedImageSampler, &imageInfo)
|
||||||
|
};
|
||||||
|
device->updateDescriptorSets(vk::ArrayProxy<const vk::WriteDescriptorSet>(2, writeDescriptorSets), nullptr);
|
||||||
|
|
||||||
|
/* VULKAN_KEY_END */
|
||||||
|
|
||||||
|
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique(vk::PipelineCacheCreateInfo());
|
||||||
|
vk::UniquePipeline graphicsPipeline = vk::su::createGraphicsPipeline(device, pipelineCache, vertexShaderModule, fragmentShaderModule, sizeof(texturedCubeData[0]), pipelineLayout, renderPass);
|
||||||
|
|
||||||
|
vk::UniqueSemaphore imageAcquiredSemaphore = device->createSemaphoreUnique(vk::SemaphoreCreateInfo());
|
||||||
|
vk::ResultValue<uint32_t> currentBuffer = device->acquireNextImageKHR(swapChainData.swapChain.get(), vk::su::FenceTimeout, imageAcquiredSemaphore.get(), nullptr);
|
||||||
|
assert(currentBuffer.result == vk::Result::eSuccess);
|
||||||
|
assert(currentBuffer.value < framebuffers.size());
|
||||||
|
|
||||||
|
vk::ClearValue clearValues[2];
|
||||||
|
clearValues[0].color = vk::ClearColorValue(std::array<float, 4>({ 0.2f, 0.2f, 0.2f, 0.2f }));
|
||||||
|
clearValues[1].depthStencil = vk::ClearDepthStencilValue(1.0f, 0);
|
||||||
|
vk::RenderPassBeginInfo renderPassBeginInfo(renderPass.get(), framebuffers[currentBuffer.value].get(), vk::Rect2D(vk::Offset2D(0, 0), surfaceData.extent), 2, clearValues);
|
||||||
|
commandBuffers[0]->beginRenderPass(renderPassBeginInfo, vk::SubpassContents::eInline);
|
||||||
|
commandBuffers[0]->bindPipeline(vk::PipelineBindPoint::eGraphics, graphicsPipeline.get());
|
||||||
|
commandBuffers[0]->bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSets[0].get(), nullptr);
|
||||||
|
|
||||||
|
vk::DeviceSize offset = 0;
|
||||||
|
commandBuffers[0]->bindVertexBuffers(0, vertexBufferData.buffer.get(), offset);
|
||||||
|
|
||||||
|
vk::Viewport viewport(0.0f, 0.0f, static_cast<float>(surfaceData.extent.width), static_cast<float>(surfaceData.extent.height), 0.0f, 1.0f);
|
||||||
|
commandBuffers[0]->setViewport(0, viewport);
|
||||||
|
|
||||||
|
vk::Rect2D scissor(vk::Offset2D(0, 0), surfaceData.extent);
|
||||||
|
commandBuffers[0]->setScissor(0, scissor);
|
||||||
|
|
||||||
|
commandBuffers[0]->draw(12 * 3, 1, 0, 0);
|
||||||
|
commandBuffers[0]->endRenderPass();
|
||||||
|
commandBuffers[0]->end();
|
||||||
|
|
||||||
|
vk::su::submitAndWait(device, graphicsQueue, commandBuffers[0]);
|
||||||
|
|
||||||
|
presentQueue.presentKHR(vk::PresentInfoKHR(0, nullptr, 1, &swapChainData.swapChain.get(), ¤tBuffer.value));
|
||||||
|
Sleep(1000);
|
||||||
|
|
||||||
|
device->waitIdle();
|
||||||
|
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||||
|
DestroyWindow(surfaceData.window);
|
||||||
|
#else
|
||||||
|
#pragma error "unhandled platform"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
catch (vk::SystemError err)
|
||||||
|
{
|
||||||
|
std::cout << "vk::SystemError: " << err.what() << std::endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
catch (std::runtime_error err)
|
||||||
|
{
|
||||||
|
std::cout << "std::runtime_error: " << err.what() << std::endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
std::cout << "unknown error\n";
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
45
samples/InitTexture/CMakeLists.txt
Normal file
45
samples/InitTexture/CMakeLists.txt
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# Copyright(c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.2)
|
||||||
|
|
||||||
|
project(InitTexture)
|
||||||
|
|
||||||
|
set(HEADERS
|
||||||
|
../utils/geometries.hpp
|
||||||
|
../utils/math.hpp
|
||||||
|
../utils/shaders.hpp
|
||||||
|
../utils/utils.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
InitTexture.cpp
|
||||||
|
../utils/math.cpp
|
||||||
|
../utils/shaders.cpp
|
||||||
|
../utils/utils.cpp
|
||||||
|
../../glslang/StandAlone/ResourceLimits.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
source_group(headers FILES ${HEADERS})
|
||||||
|
source_group(sources FILES ${SOURCES})
|
||||||
|
|
||||||
|
add_executable(InitTexture
|
||||||
|
${HEADERS}
|
||||||
|
${SOURCES}
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(InitTexture PROPERTIES FOLDER "Samples")
|
||||||
|
target_include_directories(InitTexture PUBLIC ${CMAKE_SOURCE_DIR}/glslang)
|
||||||
|
target_link_libraries(InitTexture PUBLIC glslang SPIRV "$ENV{VULKAN_SDK}/Lib/vulkan-1.lib"
|
||||||
|
)
|
166
samples/InitTexture/InitTexture.cpp
Normal file
166
samples/InitTexture/InitTexture.cpp
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
// Copyright(c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
// VulkanHpp Samples : InitTexture
|
||||||
|
// Initialize texture
|
||||||
|
|
||||||
|
#include "../utils/geometries.hpp"
|
||||||
|
#include "../utils/math.hpp"
|
||||||
|
#include "../utils/shaders.hpp"
|
||||||
|
#include "../utils/utils.hpp"
|
||||||
|
#include "vulkan/vulkan.hpp"
|
||||||
|
#include "SPIRV/GlslangToSpv.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
static char const* AppName = "InitTexture";
|
||||||
|
static char const* EngineName = "Vulkan.hpp";
|
||||||
|
|
||||||
|
int main(int /*argc*/, char ** /*argv*/)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName, vk::su::getInstanceExtensions());
|
||||||
|
#if !defined(NDEBUG)
|
||||||
|
vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
|
||||||
|
assert(!physicalDevices.empty());
|
||||||
|
|
||||||
|
vk::su::SurfaceData surfaceData(instance, AppName, AppName, vk::Extent2D(50, 50));
|
||||||
|
|
||||||
|
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex = vk::su::findGraphicsAndPresentQueueFamilyIndex(physicalDevices[0], surfaceData.surface);
|
||||||
|
vk::UniqueDevice device = vk::su::createDevice(physicalDevices[0], graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions());
|
||||||
|
|
||||||
|
vk::UniqueCommandPool commandPool = vk::su::createCommandPool(device, graphicsAndPresentQueueFamilyIndex.first);
|
||||||
|
std::vector<vk::UniqueCommandBuffer> commandBuffers = device->allocateCommandBuffersUnique(vk::CommandBufferAllocateInfo(commandPool.get(), vk::CommandBufferLevel::ePrimary, 1));
|
||||||
|
|
||||||
|
vk::Queue graphicsQueue = device->getQueue(graphicsAndPresentQueueFamilyIndex.first, 0);
|
||||||
|
vk::Queue presentQueue = device->getQueue(graphicsAndPresentQueueFamilyIndex.second, 0);
|
||||||
|
|
||||||
|
/* VULKAN_KEY_START */
|
||||||
|
|
||||||
|
vk::Format format = vk::Format::eR8G8B8A8Unorm;
|
||||||
|
vk::FormatProperties formatProperties = physicalDevices[0].getFormatProperties(format);
|
||||||
|
|
||||||
|
// See if we can use a linear tiled image for a texture, if not, we will need a staging buffer for the texture data
|
||||||
|
bool needsStaging = !(formatProperties.linearTilingFeatures & vk::FormatFeatureFlagBits::eSampledImage);
|
||||||
|
|
||||||
|
vk::UniqueImage image = device->createImageUnique(vk::ImageCreateInfo(vk::ImageCreateFlags(), vk::ImageType::e2D, format, vk::Extent3D(surfaceData.extent, 1), 1, 1,
|
||||||
|
vk::SampleCountFlagBits::e1, needsStaging ? vk::ImageTiling::eOptimal : vk::ImageTiling::eLinear,
|
||||||
|
vk::ImageUsageFlagBits::eSampled | (needsStaging ? vk::ImageUsageFlagBits::eTransferDst : vk::ImageUsageFlagBits()),
|
||||||
|
vk::SharingMode::eExclusive, 0, nullptr, needsStaging ? vk::ImageLayout::eUndefined : vk::ImageLayout::ePreinitialized));
|
||||||
|
|
||||||
|
vk::MemoryRequirements memoryRequirements = device->getImageMemoryRequirements(image.get());
|
||||||
|
uint32_t memoryTypeIndex = vk::su::findMemoryType(physicalDevices[0].getMemoryProperties(), memoryRequirements.memoryTypeBits,
|
||||||
|
needsStaging ? vk::MemoryPropertyFlags() : (vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent));
|
||||||
|
|
||||||
|
// allocate memory
|
||||||
|
vk::UniqueDeviceMemory imageMemory = device->allocateMemoryUnique(vk::MemoryAllocateInfo(memoryRequirements.size, memoryTypeIndex));
|
||||||
|
|
||||||
|
// bind memory
|
||||||
|
device->bindImageMemory(image.get(), imageMemory.get(), 0);
|
||||||
|
|
||||||
|
vk::UniqueBuffer textureBuffer;
|
||||||
|
vk::UniqueDeviceMemory textureBufferMemory;
|
||||||
|
if (needsStaging)
|
||||||
|
{
|
||||||
|
// Need a staging buffer to map and copy texture into
|
||||||
|
textureBuffer = device->createBufferUnique(vk::BufferCreateInfo(vk::BufferCreateFlags(), surfaceData.extent.width * surfaceData.extent.height * 4, vk::BufferUsageFlagBits::eTransferSrc));
|
||||||
|
|
||||||
|
memoryRequirements = device->getBufferMemoryRequirements(textureBuffer.get());
|
||||||
|
memoryTypeIndex = vk::su::findMemoryType(physicalDevices[0].getMemoryProperties(), memoryRequirements.memoryTypeBits, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||||
|
|
||||||
|
// allocate memory
|
||||||
|
textureBufferMemory = device->allocateMemoryUnique(vk::MemoryAllocateInfo(memoryRequirements.size, memoryTypeIndex));
|
||||||
|
|
||||||
|
// bind memory
|
||||||
|
device->bindBufferMemory(textureBuffer.get(), textureBufferMemory.get(), 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vk::SubresourceLayout subresourceLayout = device->getImageSubresourceLayout(image.get(), vk::ImageSubresource(vk::ImageAspectFlagBits::eColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
void* data = device->mapMemory(needsStaging ? textureBufferMemory.get() : imageMemory.get(), 0, memoryRequirements.size, vk::MemoryMapFlags());
|
||||||
|
|
||||||
|
// Checkerboard of 16x16 pixel squares
|
||||||
|
unsigned char *pImageMemory = static_cast<unsigned char*>(data);
|
||||||
|
for (uint32_t row = 0; row < surfaceData.extent.height; row++)
|
||||||
|
{
|
||||||
|
for (uint32_t col = 0; col < surfaceData.extent.width; col++)
|
||||||
|
{
|
||||||
|
unsigned char rgb = (((row & 0x10) == 0) ^ ((col & 0x10) == 0)) * 255;
|
||||||
|
pImageMemory[0] = rgb;
|
||||||
|
pImageMemory[1] = rgb;
|
||||||
|
pImageMemory[2] = rgb;
|
||||||
|
pImageMemory[3] = 255;
|
||||||
|
pImageMemory += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
device->unmapMemory(needsStaging ? textureBufferMemory.get() : imageMemory.get());
|
||||||
|
|
||||||
|
commandBuffers[0]->begin(vk::CommandBufferBeginInfo());
|
||||||
|
if (needsStaging)
|
||||||
|
{
|
||||||
|
// Since we're going to blit to the texture image, set its layout to eTransferDstOptimal
|
||||||
|
vk::su::setImageLayout(commandBuffers[0], image.get(), vk::ImageAspectFlagBits::eColor, vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer);
|
||||||
|
vk::BufferImageCopy copyRegion(0, surfaceData.extent.width, surfaceData.extent.height, vk::ImageSubresourceLayers(vk::ImageAspectFlagBits::eColor, 0, 0, 1), vk::Offset3D(0, 0, 0), vk::Extent3D(surfaceData.extent, 1));
|
||||||
|
commandBuffers[0]->copyBufferToImage(textureBuffer.get(), image.get(), vk::ImageLayout::eTransferDstOptimal, copyRegion);
|
||||||
|
// Set the layout for the texture image from eTransferDstOptimal to SHADER_READ_ONLY
|
||||||
|
vk::su::setImageLayout(commandBuffers[0], image.get(), vk::ImageAspectFlagBits::eColor, vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eFragmentShader);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we can use the linear tiled image as a texture, just do it
|
||||||
|
vk::su::setImageLayout(commandBuffers[0], image.get(), vk::ImageAspectFlagBits::eColor, vk::ImageLayout::ePreinitialized, vk::ImageLayout::eShaderReadOnlyOptimal, vk::PipelineStageFlagBits::eHost, vk::PipelineStageFlagBits::eFragmentShader);
|
||||||
|
}
|
||||||
|
|
||||||
|
commandBuffers[0]->end();
|
||||||
|
vk::su::submitAndWait(device, graphicsQueue, commandBuffers[0]);
|
||||||
|
|
||||||
|
vk::UniqueSampler sampler = device->createSamplerUnique(vk::SamplerCreateInfo(vk::SamplerCreateFlags(), vk::Filter::eNearest, vk::Filter::eNearest, vk::SamplerMipmapMode::eNearest,
|
||||||
|
vk::SamplerAddressMode::eClampToEdge, vk::SamplerAddressMode::eClampToEdge, vk::SamplerAddressMode::eClampToEdge, 0.0f, false, 1.0f, false, vk::CompareOp::eNever, 0.0f, 0.0f,
|
||||||
|
vk::BorderColor::eFloatOpaqueWhite));
|
||||||
|
|
||||||
|
vk::ComponentMapping componentMapping(vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eG, vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eA);
|
||||||
|
vk::ImageViewCreateInfo imageViewCreateInfo(vk::ImageViewCreateFlags(), image.get(), vk::ImageViewType::e2D, format, componentMapping, vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1));
|
||||||
|
vk::UniqueImageView imageView = device->createImageViewUnique(imageViewCreateInfo);
|
||||||
|
|
||||||
|
/* VULKAN_KEY_END */
|
||||||
|
|
||||||
|
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||||
|
DestroyWindow(surfaceData.window);
|
||||||
|
#else
|
||||||
|
#pragma error "unhandled platform"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
catch (vk::SystemError err)
|
||||||
|
{
|
||||||
|
std::cout << "vk::SystemError: " << err.what() << std::endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
catch (std::runtime_error err)
|
||||||
|
{
|
||||||
|
std::cout << "std::runtime_error: " << err.what() << std::endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
std::cout << "unknown error\n";
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
45
samples/InputAttachment/CMakeLists.txt
Normal file
45
samples/InputAttachment/CMakeLists.txt
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# Copyright(c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.2)
|
||||||
|
|
||||||
|
project(InputAttachment)
|
||||||
|
|
||||||
|
set(HEADERS
|
||||||
|
../utils/geometries.hpp
|
||||||
|
../utils/math.hpp
|
||||||
|
../utils/shaders.hpp
|
||||||
|
../utils/utils.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
InputAttachment.cpp
|
||||||
|
../utils/math.cpp
|
||||||
|
../utils/shaders.cpp
|
||||||
|
../utils/utils.cpp
|
||||||
|
../../glslang/StandAlone/ResourceLimits.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
source_group(headers FILES ${HEADERS})
|
||||||
|
source_group(sources FILES ${SOURCES})
|
||||||
|
|
||||||
|
add_executable(InputAttachment
|
||||||
|
${HEADERS}
|
||||||
|
${SOURCES}
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(InputAttachment PROPERTIES FOLDER "Samples")
|
||||||
|
target_include_directories(InputAttachment PUBLIC ${CMAKE_SOURCE_DIR}/glslang)
|
||||||
|
target_link_libraries(InputAttachment PUBLIC glslang SPIRV "$ENV{VULKAN_SDK}/Lib/vulkan-1.lib"
|
||||||
|
)
|
211
samples/InputAttachment/InputAttachment.cpp
Normal file
211
samples/InputAttachment/InputAttachment.cpp
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
// Copyright(c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
// VulkanHpp Samples : InputAttachment
|
||||||
|
// Use an input attachment to draw a yellow triangle
|
||||||
|
|
||||||
|
#include "../utils/geometries.hpp"
|
||||||
|
#include "../utils/math.hpp"
|
||||||
|
#include "../utils/shaders.hpp"
|
||||||
|
#include "../utils/utils.hpp"
|
||||||
|
#include "vulkan/vulkan.hpp"
|
||||||
|
#include "SPIRV/GlslangToSpv.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
static char const* AppName = "InputAttachment";
|
||||||
|
static char const* EngineName = "Vulkan.hpp";
|
||||||
|
|
||||||
|
static std::string vertexShaderText = R"(
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
vec2 vertices[3];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vertices[0] = vec2(-1.0f, -1.0f);
|
||||||
|
vertices[1] = vec2( 1.0f, -1.0f);
|
||||||
|
vertices[2] = vec2( 0.0f, 1.0f);
|
||||||
|
|
||||||
|
gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
// Use subpassLoad to read from input attachment
|
||||||
|
static const char *fragmentShaderText = R"(
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout (input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput inputAttachment;
|
||||||
|
|
||||||
|
layout (location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
outColor = subpassLoad(inputAttachment);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
int main(int /*argc*/, char ** /*argv*/)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName, vk::su::getInstanceExtensions());
|
||||||
|
#if !defined(NDEBUG)
|
||||||
|
vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices();
|
||||||
|
assert(!physicalDevices.empty());
|
||||||
|
|
||||||
|
vk::FormatProperties formatProperties = physicalDevices[0].getFormatProperties(vk::Format::eR8G8B8A8Unorm);
|
||||||
|
if (!(formatProperties.optimalTilingFeatures & vk::FormatFeatureFlagBits::eColorAttachment))
|
||||||
|
{
|
||||||
|
std::cout << "vk::Format::eR8G8B8A8Unorm format unsupported for input attachment\n";
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::su::SurfaceData surfaceData(instance, AppName, AppName, vk::Extent2D(500, 500));
|
||||||
|
|
||||||
|
std::pair<uint32_t, uint32_t> graphicsAndPresentQueueFamilyIndex = vk::su::findGraphicsAndPresentQueueFamilyIndex(physicalDevices[0], surfaceData.surface);
|
||||||
|
vk::UniqueDevice device = vk::su::createDevice(physicalDevices[0], graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions());
|
||||||
|
|
||||||
|
vk::UniqueCommandPool commandPool = vk::su::createCommandPool(device, graphicsAndPresentQueueFamilyIndex.first);
|
||||||
|
std::vector<vk::UniqueCommandBuffer> commandBuffers = device->allocateCommandBuffersUnique(vk::CommandBufferAllocateInfo(commandPool.get(), vk::CommandBufferLevel::ePrimary, 1));
|
||||||
|
|
||||||
|
vk::Queue graphicsQueue = device->getQueue(graphicsAndPresentQueueFamilyIndex.first, 0);
|
||||||
|
vk::Queue presentQueue = device->getQueue(graphicsAndPresentQueueFamilyIndex.second, 0);
|
||||||
|
|
||||||
|
vk::su::SwapChainData swapChainData(physicalDevices[0], device, surfaceData.surface, surfaceData.extent, vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferSrc,
|
||||||
|
graphicsAndPresentQueueFamilyIndex.first, graphicsAndPresentQueueFamilyIndex.second);
|
||||||
|
|
||||||
|
/* VULKAN_KEY_START */
|
||||||
|
|
||||||
|
// Create a framebuffer with 2 attachments, one the color attachment the shaders render into, and the other an input attachment which
|
||||||
|
// will be cleared to yellow, and then used by the shaders to color the drawn triangle. Final result should be a yellow triangle
|
||||||
|
|
||||||
|
// Create the image that will be used as the input attachment
|
||||||
|
// The image for the color attachment is the presentable image already created as part of the SwapChainData
|
||||||
|
vk::UniqueImage inputImage = device->createImageUnique(vk::ImageCreateInfo(vk::ImageCreateFlags(), vk::ImageType::e2D, swapChainData.colorFormat, vk::Extent3D(surfaceData.extent, 1), 1, 1,
|
||||||
|
vk::SampleCountFlagBits::e1, vk::ImageTiling::eOptimal, vk::ImageUsageFlagBits::eInputAttachment | vk::ImageUsageFlagBits::eTransferDst));
|
||||||
|
|
||||||
|
vk::MemoryRequirements memoryRequirements = device->getImageMemoryRequirements(inputImage.get());
|
||||||
|
uint32_t memoryTypeIndex = vk::su::findMemoryType(physicalDevices[0].getMemoryProperties(), memoryRequirements.memoryTypeBits, vk::MemoryPropertyFlags());
|
||||||
|
vk::UniqueDeviceMemory inputMemory = device->allocateMemoryUnique(vk::MemoryAllocateInfo(memoryRequirements.size, memoryTypeIndex));
|
||||||
|
device->bindImageMemory(inputImage.get(), inputMemory.get(), 0);
|
||||||
|
|
||||||
|
// Set the image layout to TRANSFER_DST_OPTIMAL to be ready for clear
|
||||||
|
commandBuffers[0]->begin(vk::CommandBufferBeginInfo());
|
||||||
|
vk::su::setImageLayout(commandBuffers[0], inputImage.get(), vk::ImageAspectFlagBits::eColor, vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal,
|
||||||
|
vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer);
|
||||||
|
|
||||||
|
commandBuffers[0]->clearColorImage(inputImage.get(), vk::ImageLayout::eTransferDstOptimal, vk::ClearColorValue(std::array<float, 4>({ {1.0f, 1.0f, 0.0f, 0.0f} })),
|
||||||
|
vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS));
|
||||||
|
|
||||||
|
// Set the image layout to SHADER_READONLY_OPTIMAL for use by the shaders
|
||||||
|
vk::su::setImageLayout(commandBuffers[0], inputImage.get(), vk::ImageAspectFlagBits::eColor, vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal,
|
||||||
|
vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eFragmentShader);
|
||||||
|
|
||||||
|
vk::ComponentMapping componentMapping(vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eG, vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eA);
|
||||||
|
vk::ImageViewCreateInfo imageViewCreateInfo(vk::ImageViewCreateFlags(), inputImage.get(), vk::ImageViewType::e2D, swapChainData.colorFormat, componentMapping, vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1));
|
||||||
|
vk::UniqueImageView inputAttachmentView = device->createImageViewUnique(imageViewCreateInfo);
|
||||||
|
|
||||||
|
vk::DescriptorSetLayoutBinding layoutBinding(0, vk::DescriptorType::eInputAttachment, 1, vk::ShaderStageFlagBits::eFragment);
|
||||||
|
vk::UniqueDescriptorSetLayout descriptorSetLayout = device->createDescriptorSetLayoutUnique(vk::DescriptorSetLayoutCreateInfo(vk::DescriptorSetLayoutCreateFlags(), 1, &layoutBinding));
|
||||||
|
|
||||||
|
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(vk::PipelineLayoutCreateInfo(vk::PipelineLayoutCreateFlags(), 1, &descriptorSetLayout.get()));
|
||||||
|
|
||||||
|
vk::AttachmentDescription attachments[2] =
|
||||||
|
{
|
||||||
|
// First attachment is the color attachment - clear at the beginning of the renderpass and transition layout to PRESENT_SRC_KHR at the end of renderpass
|
||||||
|
vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), swapChainData.colorFormat, vk::SampleCountFlagBits::e1, vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore,
|
||||||
|
vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eUndefined, vk::ImageLayout::ePresentSrcKHR),
|
||||||
|
// Second attachment is input attachment. Once cleared it should have width*height yellow pixels.
|
||||||
|
// Doing a subpassLoad in the fragment shader should give the shader the color at the fragments x,y location from the input attachment
|
||||||
|
vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), swapChainData.colorFormat, vk::SampleCountFlagBits::e1, vk::AttachmentLoadOp::eLoad, vk::AttachmentStoreOp::eDontCare,
|
||||||
|
vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eShaderReadOnlyOptimal, vk::ImageLayout::eShaderReadOnlyOptimal)
|
||||||
|
};
|
||||||
|
vk::AttachmentReference colorReference(0, vk::ImageLayout::eColorAttachmentOptimal);
|
||||||
|
vk::AttachmentReference inputReference(1, vk::ImageLayout::eShaderReadOnlyOptimal);
|
||||||
|
vk::SubpassDescription subPass(vk::SubpassDescriptionFlags(), vk::PipelineBindPoint::eGraphics, 1, &inputReference, 1, &colorReference);
|
||||||
|
vk::UniqueRenderPass renderPass = device->createRenderPassUnique(vk::RenderPassCreateInfo(vk::RenderPassCreateFlags(), 2, attachments, 1, &subPass));
|
||||||
|
|
||||||
|
glslang::InitializeProcess();
|
||||||
|
vk::UniqueShaderModule vertexShaderModule = vk::su::createShaderModule(device, vk::ShaderStageFlagBits::eVertex, vertexShaderText);
|
||||||
|
vk::UniqueShaderModule fragmentShaderModule = vk::su::createShaderModule(device, vk::ShaderStageFlagBits::eFragment, fragmentShaderText);
|
||||||
|
glslang::FinalizeProcess();
|
||||||
|
|
||||||
|
std::vector<vk::UniqueFramebuffer> framebuffers = vk::su::createFramebuffers(device, renderPass, swapChainData.imageViews, inputAttachmentView, surfaceData.extent);
|
||||||
|
|
||||||
|
vk::DescriptorPoolSize poolSize(vk::DescriptorType::eInputAttachment, 1);
|
||||||
|
vk::UniqueDescriptorPool descriptorPool = device->createDescriptorPoolUnique(vk::DescriptorPoolCreateInfo(vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, 1, 1, &poolSize));
|
||||||
|
|
||||||
|
std::vector<vk::UniqueDescriptorSet> descriptorSets = device->allocateDescriptorSetsUnique(vk::DescriptorSetAllocateInfo(descriptorPool.get(), 1, &descriptorSetLayout.get()));
|
||||||
|
|
||||||
|
vk::DescriptorImageInfo inputImageInfo(nullptr, inputAttachmentView.get(), vk::ImageLayout::eShaderReadOnlyOptimal);
|
||||||
|
vk::WriteDescriptorSet writeDescriptorSet(descriptorSets[0].get(), 0, 0, 1, vk::DescriptorType::eInputAttachment, &inputImageInfo);
|
||||||
|
device->updateDescriptorSets(vk::ArrayProxy<const vk::WriteDescriptorSet>(1, &writeDescriptorSet), nullptr);
|
||||||
|
|
||||||
|
vk::UniquePipelineCache pipelineCache = device->createPipelineCacheUnique(vk::PipelineCacheCreateInfo());
|
||||||
|
vk::UniquePipeline graphicsPipeline = vk::su::createGraphicsPipeline(device, pipelineCache, vertexShaderModule, fragmentShaderModule, 0, pipelineLayout, renderPass);
|
||||||
|
|
||||||
|
vk::UniqueSemaphore imageAcquiredSemaphore = device->createSemaphoreUnique(vk::SemaphoreCreateInfo());
|
||||||
|
|
||||||
|
vk::ResultValue<uint32_t> result = device->acquireNextImage2KHR(vk::AcquireNextImageInfoKHR(swapChainData.swapChain.get(), UINT64_MAX, imageAcquiredSemaphore.get()));
|
||||||
|
assert(result.result == vk::Result::eSuccess);
|
||||||
|
uint32_t currentBuffer = result.value;
|
||||||
|
|
||||||
|
vk::ClearValue clearValue;
|
||||||
|
clearValue.color = vk::ClearColorValue(std::array<float, 4>({ 0.2f, 0.2f, 0.2f, 0.2f }));
|
||||||
|
commandBuffers[0]->beginRenderPass(vk::RenderPassBeginInfo(renderPass.get(), framebuffers[currentBuffer].get(), vk::Rect2D(vk::Offset2D(0, 0), surfaceData.extent), 1, &clearValue), vk::SubpassContents::eInline);
|
||||||
|
commandBuffers[0]->bindPipeline(vk::PipelineBindPoint::eGraphics, graphicsPipeline.get());
|
||||||
|
commandBuffers[0]->bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, descriptorSets[0].get(), nullptr);
|
||||||
|
|
||||||
|
vk::Viewport viewport(0.0f, 0.0f, static_cast<float>(surfaceData.extent.width), static_cast<float>(surfaceData.extent.height), 0.0f, 1.0f);
|
||||||
|
commandBuffers[0]->setViewport(0, viewport);
|
||||||
|
|
||||||
|
vk::Rect2D scissor(vk::Offset2D(0, 0), surfaceData.extent);
|
||||||
|
commandBuffers[0]->setScissor(0, scissor);
|
||||||
|
|
||||||
|
commandBuffers[0]->draw(3, 1, 0, 0);
|
||||||
|
commandBuffers[0]->endRenderPass();
|
||||||
|
commandBuffers[0]->end();
|
||||||
|
|
||||||
|
/* VULKAN_KEY_END */
|
||||||
|
|
||||||
|
vk::su::submitAndWait(device, graphicsQueue, commandBuffers[0]);
|
||||||
|
|
||||||
|
presentQueue.presentKHR(vk::PresentInfoKHR(0, nullptr, 1, &swapChainData.swapChain.get(), ¤tBuffer));
|
||||||
|
Sleep(1000);
|
||||||
|
|
||||||
|
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||||
|
DestroyWindow(surfaceData.window);
|
||||||
|
#else
|
||||||
|
#pragma error "unhandled platform"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
catch (vk::SystemError err)
|
||||||
|
{
|
||||||
|
std::cout << "vk::SystemError: " << err.what() << std::endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
catch (std::runtime_error err)
|
||||||
|
{
|
||||||
|
std::cout << "std::runtime_error: " << err.what() << std::endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
std::cout << "unknown error\n";
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
@ -19,6 +19,13 @@ struct VertexPC
|
|||||||
float r, g, b, a; // Color
|
float r, g, b, a; // Color
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VertexPT
|
||||||
|
{
|
||||||
|
float x, y, z, w; // Position data
|
||||||
|
float u, v; // texture u,v
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static const VertexPC coloredCubeData[] =
|
static const VertexPC coloredCubeData[] =
|
||||||
{
|
{
|
||||||
// red face
|
// red face
|
||||||
@ -65,3 +72,49 @@ static const VertexPC coloredCubeData[] =
|
|||||||
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f },
|
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const VertexPT texturedCubeData[] =
|
||||||
|
{
|
||||||
|
// left face
|
||||||
|
{ -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f },
|
||||||
|
{ -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f },
|
||||||
|
{ -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f },
|
||||||
|
{ -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f },
|
||||||
|
{ -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f },
|
||||||
|
{ -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f },
|
||||||
|
// front face
|
||||||
|
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f },
|
||||||
|
{ 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f },
|
||||||
|
{ 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f },
|
||||||
|
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f },
|
||||||
|
{ 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f },
|
||||||
|
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
|
||||||
|
// top face
|
||||||
|
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
|
||||||
|
{ 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f },
|
||||||
|
{ 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f },
|
||||||
|
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
|
||||||
|
{ -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f },
|
||||||
|
{ 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f },
|
||||||
|
// bottom face
|
||||||
|
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f },
|
||||||
|
{ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f },
|
||||||
|
{ -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f },
|
||||||
|
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f },
|
||||||
|
{ 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f },
|
||||||
|
{ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f },
|
||||||
|
// right face
|
||||||
|
{ 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
|
||||||
|
{ 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f },
|
||||||
|
{ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f },
|
||||||
|
{ 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f },
|
||||||
|
{ 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
|
||||||
|
{ 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f },
|
||||||
|
// back face
|
||||||
|
{ -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f },
|
||||||
|
{ 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f },
|
||||||
|
{ -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f },
|
||||||
|
{ -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f },
|
||||||
|
{ 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f },
|
||||||
|
{ 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f },
|
||||||
|
};
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "shaders.hpp"
|
#include "shaders.hpp"
|
||||||
#include "vulkan/vulkan.hpp"
|
#include "vulkan/vulkan.hpp"
|
||||||
|
#include "glslang/StandAlone/ResourceLimits.h"
|
||||||
#include "SPIRV/GlslangToSpv.h"
|
#include "SPIRV/GlslangToSpv.h"
|
||||||
|
|
||||||
namespace vk
|
namespace vk
|
||||||
@ -38,102 +39,6 @@ namespace vk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(TBuiltInResource & resource)
|
|
||||||
{
|
|
||||||
resource.maxLights = 32;
|
|
||||||
resource.maxClipPlanes = 6;
|
|
||||||
resource.maxTextureUnits = 32;
|
|
||||||
resource.maxTextureCoords = 32;
|
|
||||||
resource.maxVertexAttribs = 64;
|
|
||||||
resource.maxVertexUniformComponents = 4096;
|
|
||||||
resource.maxVaryingFloats = 64;
|
|
||||||
resource.maxVertexTextureImageUnits = 32;
|
|
||||||
resource.maxCombinedTextureImageUnits = 80;
|
|
||||||
resource.maxTextureImageUnits = 32;
|
|
||||||
resource.maxFragmentUniformComponents = 4096;
|
|
||||||
resource.maxDrawBuffers = 32;
|
|
||||||
resource.maxVertexUniformVectors = 128;
|
|
||||||
resource.maxVaryingVectors = 8;
|
|
||||||
resource.maxFragmentUniformVectors = 16;
|
|
||||||
resource.maxVertexOutputVectors = 16;
|
|
||||||
resource.maxFragmentInputVectors = 15;
|
|
||||||
resource.minProgramTexelOffset = -8;
|
|
||||||
resource.maxProgramTexelOffset = 7;
|
|
||||||
resource.maxClipDistances = 8;
|
|
||||||
resource.maxComputeWorkGroupCountX = 65535;
|
|
||||||
resource.maxComputeWorkGroupCountY = 65535;
|
|
||||||
resource.maxComputeWorkGroupCountZ = 65535;
|
|
||||||
resource.maxComputeWorkGroupSizeX = 1024;
|
|
||||||
resource.maxComputeWorkGroupSizeY = 1024;
|
|
||||||
resource.maxComputeWorkGroupSizeZ = 64;
|
|
||||||
resource.maxComputeUniformComponents = 1024;
|
|
||||||
resource.maxComputeTextureImageUnits = 16;
|
|
||||||
resource.maxComputeImageUniforms = 8;
|
|
||||||
resource.maxComputeAtomicCounters = 8;
|
|
||||||
resource.maxComputeAtomicCounterBuffers = 1;
|
|
||||||
resource.maxVaryingComponents = 60;
|
|
||||||
resource.maxVertexOutputComponents = 64;
|
|
||||||
resource.maxGeometryInputComponents = 64;
|
|
||||||
resource.maxGeometryOutputComponents = 128;
|
|
||||||
resource.maxFragmentInputComponents = 128;
|
|
||||||
resource.maxImageUnits = 8;
|
|
||||||
resource.maxCombinedImageUnitsAndFragmentOutputs = 8;
|
|
||||||
resource.maxCombinedShaderOutputResources = 8;
|
|
||||||
resource.maxImageSamples = 0;
|
|
||||||
resource.maxVertexImageUniforms = 0;
|
|
||||||
resource.maxTessControlImageUniforms = 0;
|
|
||||||
resource.maxTessEvaluationImageUniforms = 0;
|
|
||||||
resource.maxGeometryImageUniforms = 0;
|
|
||||||
resource.maxFragmentImageUniforms = 8;
|
|
||||||
resource.maxCombinedImageUniforms = 8;
|
|
||||||
resource.maxGeometryTextureImageUnits = 16;
|
|
||||||
resource.maxGeometryOutputVertices = 256;
|
|
||||||
resource.maxGeometryTotalOutputComponents = 1024;
|
|
||||||
resource.maxGeometryUniformComponents = 1024;
|
|
||||||
resource.maxGeometryVaryingComponents = 64;
|
|
||||||
resource.maxTessControlInputComponents = 128;
|
|
||||||
resource.maxTessControlOutputComponents = 128;
|
|
||||||
resource.maxTessControlTextureImageUnits = 16;
|
|
||||||
resource.maxTessControlUniformComponents = 1024;
|
|
||||||
resource.maxTessControlTotalOutputComponents = 4096;
|
|
||||||
resource.maxTessEvaluationInputComponents = 128;
|
|
||||||
resource.maxTessEvaluationOutputComponents = 128;
|
|
||||||
resource.maxTessEvaluationTextureImageUnits = 16;
|
|
||||||
resource.maxTessEvaluationUniformComponents = 1024;
|
|
||||||
resource.maxTessPatchComponents = 120;
|
|
||||||
resource.maxPatchVertices = 32;
|
|
||||||
resource.maxTessGenLevel = 64;
|
|
||||||
resource.maxViewports = 16;
|
|
||||||
resource.maxVertexAtomicCounters = 0;
|
|
||||||
resource.maxTessControlAtomicCounters = 0;
|
|
||||||
resource.maxTessEvaluationAtomicCounters = 0;
|
|
||||||
resource.maxGeometryAtomicCounters = 0;
|
|
||||||
resource.maxFragmentAtomicCounters = 8;
|
|
||||||
resource.maxCombinedAtomicCounters = 8;
|
|
||||||
resource.maxAtomicCounterBindings = 1;
|
|
||||||
resource.maxVertexAtomicCounterBuffers = 0;
|
|
||||||
resource.maxTessControlAtomicCounterBuffers = 0;
|
|
||||||
resource.maxTessEvaluationAtomicCounterBuffers = 0;
|
|
||||||
resource.maxGeometryAtomicCounterBuffers = 0;
|
|
||||||
resource.maxFragmentAtomicCounterBuffers = 1;
|
|
||||||
resource.maxCombinedAtomicCounterBuffers = 1;
|
|
||||||
resource.maxAtomicCounterBufferSize = 16384;
|
|
||||||
resource.maxTransformFeedbackBuffers = 4;
|
|
||||||
resource.maxTransformFeedbackInterleavedComponents = 64;
|
|
||||||
resource.maxCullDistances = 8;
|
|
||||||
resource.maxCombinedClipAndCullDistances = 8;
|
|
||||||
resource.maxSamples = 4;
|
|
||||||
resource.limits.nonInductiveForLoops = 1;
|
|
||||||
resource.limits.whileLoops = 1;
|
|
||||||
resource.limits.doWhileLoops = 1;
|
|
||||||
resource.limits.generalUniformIndexing = 1;
|
|
||||||
resource.limits.generalAttributeMatrixVectorIndexing = 1;
|
|
||||||
resource.limits.generalVaryingIndexing = 1;
|
|
||||||
resource.limits.generalSamplerIndexing = 1;
|
|
||||||
resource.limits.generalVariableIndexing = 1;
|
|
||||||
resource.limits.generalConstantMatrixVectorIndexing = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GLSLtoSPV(const vk::ShaderStageFlagBits shaderType, std::string const& glslShader, std::vector<unsigned int> &spvShader)
|
bool GLSLtoSPV(const vk::ShaderStageFlagBits shaderType, std::string const& glslShader, std::vector<unsigned int> &spvShader)
|
||||||
{
|
{
|
||||||
EShLanguage stage = translateShaderStage(shaderType);
|
EShLanguage stage = translateShaderStage(shaderType);
|
||||||
@ -144,13 +49,10 @@ namespace vk
|
|||||||
glslang::TShader shader(stage);
|
glslang::TShader shader(stage);
|
||||||
shader.setStrings(shaderStrings, 1);
|
shader.setStrings(shaderStrings, 1);
|
||||||
|
|
||||||
TBuiltInResource resource;
|
|
||||||
init(resource);
|
|
||||||
|
|
||||||
// Enable SPIR-V and Vulkan rules when parsing GLSL
|
// Enable SPIR-V and Vulkan rules when parsing GLSL
|
||||||
EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules);
|
EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules);
|
||||||
|
|
||||||
if (!shader.parse(&resource, 100, false, messages))
|
if (!shader.parse(&glslang::DefaultTBuiltInResource, 100, false, messages))
|
||||||
{
|
{
|
||||||
puts(shader.getInfoLog());
|
puts(shader.getInfoLog());
|
||||||
puts(shader.getInfoDebugLog());
|
puts(shader.getInfoDebugLog());
|
||||||
|
@ -52,6 +52,31 @@ void main()
|
|||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
// vertex shader with (P)osition and (T)exCoord in and (T)exCoord out
|
||||||
|
const std::string vertexShaderText_PT_T = R"(
|
||||||
|
#version 400
|
||||||
|
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
#extension GL_ARB_shading_language_420pack : enable
|
||||||
|
|
||||||
|
layout (std140, binding = 0) uniform buffer
|
||||||
|
{
|
||||||
|
mat4 mvp;
|
||||||
|
} uniformBuffer;
|
||||||
|
|
||||||
|
layout (location = 0) in vec4 pos;
|
||||||
|
layout (location = 1) in vec2 inTexCoord;
|
||||||
|
|
||||||
|
layout (location = 0) out vec2 outTexCoord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
outTexCoord = inTexCoord;
|
||||||
|
gl_Position = uniformBuffer.mvp * pos;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
|
||||||
// fragment shader with (C)olor in and (C)olor out
|
// fragment shader with (C)olor in and (C)olor out
|
||||||
const std::string fragmentShaderText_C_C = R"(
|
const std::string fragmentShaderText_C_C = R"(
|
||||||
#version 400
|
#version 400
|
||||||
@ -69,3 +94,22 @@ void main()
|
|||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
// fragment shader with (T)exCoord in and (C)olor out
|
||||||
|
const std::string fragmentShaderText_T_C = R"(
|
||||||
|
#version 400
|
||||||
|
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
#extension GL_ARB_shading_language_420pack : enable
|
||||||
|
|
||||||
|
layout (binding = 1) uniform sampler2D tex;
|
||||||
|
|
||||||
|
layout (location = 0) in vec2 inTexCoord;
|
||||||
|
|
||||||
|
layout (location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
outColor = texture(tex, inTexCoord);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
@ -130,13 +130,20 @@ namespace vk
|
|||||||
vk::PipelineShaderStageCreateInfo(vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eFragment, fragmentShaderModule.get(), "main")
|
vk::PipelineShaderStageCreateInfo(vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eFragment, fragmentShaderModule.get(), "main")
|
||||||
};
|
};
|
||||||
|
|
||||||
vk::VertexInputBindingDescription vertexInputBindingDescription(0, vertexStride);
|
vk::PipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo;
|
||||||
vk::VertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
|
if (0 < vertexStride)
|
||||||
{
|
{
|
||||||
vk::VertexInputAttributeDescription(0, 0, vk::Format::eR32G32B32A32Sfloat, 0),
|
vk::VertexInputBindingDescription vertexInputBindingDescription(0, vertexStride);
|
||||||
vk::VertexInputAttributeDescription(1, 0, vk::Format::eR32G32B32A32Sfloat, 16)
|
vk::VertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
|
||||||
};
|
{
|
||||||
vk::PipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo(vk::PipelineVertexInputStateCreateFlags(), 1, &vertexInputBindingDescription, 2, vertexInputAttributeDescriptions);
|
vk::VertexInputAttributeDescription(0, 0, vk::Format::eR32G32B32A32Sfloat, 0),
|
||||||
|
vk::VertexInputAttributeDescription(1, 0, vk::Format::eR32G32B32A32Sfloat, 16)
|
||||||
|
};
|
||||||
|
pipelineVertexInputStateCreateInfo.vertexBindingDescriptionCount = 1;
|
||||||
|
pipelineVertexInputStateCreateInfo.pVertexBindingDescriptions = &vertexInputBindingDescription;
|
||||||
|
pipelineVertexInputStateCreateInfo.vertexAttributeDescriptionCount = 2;
|
||||||
|
pipelineVertexInputStateCreateInfo.pVertexAttributeDescriptions = vertexInputAttributeDescriptions;
|
||||||
|
}
|
||||||
|
|
||||||
vk::PipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo(vk::PipelineInputAssemblyStateCreateFlags(), vk::PrimitiveTopology::eTriangleList);
|
vk::PipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo(vk::PipelineInputAssemblyStateCreateFlags(), vk::PrimitiveTopology::eTriangleList);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user