lunarg 11
This commit is contained in:
parent
302e7aa753
commit
9477f64d50
4 changed files with 460 additions and 4 deletions
|
|
@ -1,4 +1,9 @@
|
||||||
REM cd build 2>NUL && cd .. || mkdir build
|
REM cd build 2>NUL && cd .. || mkdir build
|
||||||
if not exist build\ mkdir build || goto :EOF
|
if not exist build\ mkdir build || goto :EOF
|
||||||
|
|
||||||
clang++ src/main.cpp -o build/window.exe -O0 -g -gcodeview -lgdi32 -lvulkan-1 -I%VULKAN_SDK%/Include -L%VULKAN_SDK%/Lib -Wl,-pdb=
|
REM clang++ src/main.cpp -o build/window.exe -O0 -g -gcodeview -stdlib=libc++ -lunwind -lgdi32 -lkernel32 -lvulkan-1 -lSPIRV -lSPIRV-Tools -lSPIRV-Tools-diff -lSPIRV-Tools-opt -lSPVRemapper -lglslang -lOSDependent -lGenericCodeGen -lMachineIndependent -lglslang-default-resource-limits -I%VULKAN_SDK%/Include -L%VULKAN_SDK%/Lib -Wl,-pdb= -v
|
||||||
|
|
||||||
|
set VSCMD_SKIP_SENDTELEMETRY=1
|
||||||
|
set VCPKG_KEEP_ENV_VARS=VSCMD_SKIP_SENDTELEMETRY
|
||||||
|
vcvarsall.bat x64 && cl.exe /Fe:build\window.exe /std:c++20 /Od /MDd /EHsc -I%VULKAN_SDK%/Include src/main.cpp user32.lib gdi32.lib kernel32.lib vulkan-1.lib SPIRV.lib SPIRV-Toolsd.lib SPIRV-Tools-diffd.lib SPIRV-Tools-optd.lib SPVRemapperd.lib glslangd.lib OSDependentd.lib GenericCodeGend.lib MachineIndependentd.lib glslang-default-resource-limitsd.lib /link /DEBUG:FULL /IGNORE:4099 /LIBPATH:%VULKAN_SDK%/Lib
|
||||||
|
|
||||||
|
|
|
||||||
427
src/main.cpp
427
src/main.cpp
|
|
@ -7,19 +7,43 @@
|
||||||
#define VK_USE_PLATFORM_WAYLAND_KHR
|
#define VK_USE_PLATFORM_WAYLAND_KHR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define GL_KHR_vulkan_glsl
|
||||||
|
|
||||||
|
/* Number of descriptor sets needs to be the same at alloc, */
|
||||||
|
/* pipeline layout creation, and descriptor set layout creation */
|
||||||
|
#define NUM_DESCRIPTOR_SETS 1
|
||||||
|
|
||||||
|
/* Number of samples needs to be the same at image creation, */
|
||||||
|
/* renderpass creation and pipeline creation. */
|
||||||
|
#define NUM_SAMPLES VK_SAMPLE_COUNT_1_BIT
|
||||||
|
|
||||||
|
/* Number of viewports and number of scissors have to be the same */
|
||||||
|
/* at pipeline creation and in any call to set them dynamically */
|
||||||
|
/* They also have to be the same as each other */
|
||||||
|
#define NUM_VIEWPORTS 1
|
||||||
|
#define NUM_SCISSORS NUM_VIEWPORTS
|
||||||
|
|
||||||
|
#include <excpt.h>
|
||||||
|
//#include <eh.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cwchar>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/ext/matrix_clip_space.hpp>
|
#include <glm/ext/matrix_clip_space.hpp>
|
||||||
#include <glm/ext/matrix_transform.hpp>
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
|
#include <glslang/Include/glslang_c_interface.h>
|
||||||
|
#include <glslang/Public/resource_limits_c.h>
|
||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <winuser.h>
|
#include <winuser.h>
|
||||||
#include <wingdi.h>
|
#include <wingdi.h>
|
||||||
|
#include <fileapi.h>
|
||||||
|
#include <libloaderapi.h>
|
||||||
//LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
//LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
typedef struct StateInfo {
|
typedef struct StateInfo {
|
||||||
|
|
@ -503,7 +527,6 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
|
||||||
|
|
||||||
memoryAllocInfo.allocationSize = memoryRequirements.size;
|
memoryAllocInfo.allocationSize = memoryRequirements.size;
|
||||||
|
|
||||||
uint32_t memoryTypeIndex = 0;
|
|
||||||
VkFlags requirements = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
VkFlags requirements = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
||||||
// Search memtypes to find first index with those properties
|
// Search memtypes to find first index with those properties
|
||||||
for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++) {
|
for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++) {
|
||||||
|
|
@ -516,12 +539,12 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
|
||||||
memoryRequirements.memoryTypeBits >>= 1;
|
memoryRequirements.memoryTypeBits >>= 1;
|
||||||
}
|
}
|
||||||
// No memory types matched, return failure
|
// No memory types matched, return failure
|
||||||
assert(memoryTypeIndex && "No mappable, coherent memory");
|
assert(memoryAllocInfo.memoryTypeIndex && "No mappable, coherent memory");
|
||||||
|
|
||||||
result = vkAllocateMemory(device, &memoryAllocInfo, NULL, &(uniformData.mem));
|
result = vkAllocateMemory(device, &memoryAllocInfo, NULL, &(uniformData.mem));
|
||||||
assert(result == VK_SUCCESS);
|
assert(result == VK_SUCCESS);
|
||||||
|
|
||||||
uint8_t* pData; //VK_WHOLE_SIZE
|
uint8_t* pData; //VK_WHOLE_SIZE = through buffer end
|
||||||
result = vkMapMemory(device, uniformData.mem, 0, memoryRequirements.size, 0, (void **)&pData);
|
result = vkMapMemory(device, uniformData.mem, 0, memoryRequirements.size, 0, (void **)&pData);
|
||||||
assert(result == VK_SUCCESS);
|
assert(result == VK_SUCCESS);
|
||||||
|
|
||||||
|
|
@ -532,10 +555,401 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
|
||||||
result = vkBindBufferMemory(device, uniformData.buf, uniformData.mem, 0);
|
result = vkBindBufferMemory(device, uniformData.buf, uniformData.mem, 0);
|
||||||
assert(result == VK_SUCCESS);
|
assert(result == VK_SUCCESS);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* typedef struct VkDescriptorBufferInfo {
|
||||||
|
* VkBuffer buffer;
|
||||||
|
* VkDeviceSize offset;
|
||||||
|
* VkDeviceSize range;
|
||||||
|
* } VkDescriptorBufferInfo;
|
||||||
|
*/
|
||||||
uniformData.descriptorBufferInfo.buffer = uniformData.buf;
|
uniformData.descriptorBufferInfo.buffer = uniformData.buf;
|
||||||
uniformData.descriptorBufferInfo.offset = 0;
|
uniformData.descriptorBufferInfo.offset = 0;
|
||||||
uniformData.descriptorBufferInfo.range = sizeof(MVP);
|
uniformData.descriptorBufferInfo.range = sizeof(MVP);
|
||||||
|
|
||||||
|
/* Descriptor set declaration */
|
||||||
|
|
||||||
|
/* Start with just our uniform buffer that has our transformation matrices
|
||||||
|
* (for the vertex shader). The fragment shader we intend to use needs no
|
||||||
|
* external resources, so nothing else is necessary
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Note that when we start using textures, this is where our sampler will
|
||||||
|
* need to be specified
|
||||||
|
*/
|
||||||
|
VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {};
|
||||||
|
descriptorSetLayoutBinding.binding = 0;
|
||||||
|
descriptorSetLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||||
|
descriptorSetLayoutBinding.descriptorCount = 1;
|
||||||
|
descriptorSetLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
|
descriptorSetLayoutBinding.pImmutableSamplers = NULL;
|
||||||
|
|
||||||
|
/* Next take layout bindings and use them to create a descriptor set layout
|
||||||
|
*/
|
||||||
|
std::vector<VkDescriptorSetLayout> descriptorSetLayouts;
|
||||||
|
VkDescriptorSetLayoutCreateInfo descriptorSetInfo = {};
|
||||||
|
descriptorSetInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||||
|
descriptorSetInfo.pNext = NULL;
|
||||||
|
descriptorSetInfo.bindingCount = 1;
|
||||||
|
descriptorSetInfo.pBindings = &descriptorSetLayoutBinding;
|
||||||
|
|
||||||
|
descriptorSetLayouts.resize(NUM_DESCRIPTOR_SETS);
|
||||||
|
result = vkCreateDescriptorSetLayout(device, &descriptorSetInfo, NULL, descriptorSetLayouts.data());
|
||||||
|
assert(result == VK_SUCCESS);
|
||||||
|
|
||||||
|
/* Now use the descriptor layout to create a pipeline layout */
|
||||||
|
//Constant ranges constant to shader not used here
|
||||||
|
VkPipelineLayout pipelineLayout;
|
||||||
|
VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
|
||||||
|
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
|
pipelineLayoutInfo.pNext = NULL;
|
||||||
|
pipelineLayoutInfo.pushConstantRangeCount = 0;
|
||||||
|
pipelineLayoutInfo.pPushConstantRanges = NULL;
|
||||||
|
pipelineLayoutInfo.setLayoutCount = NUM_DESCRIPTOR_SETS;
|
||||||
|
pipelineLayoutInfo.pSetLayouts = descriptorSetLayouts.data();
|
||||||
|
|
||||||
|
result = vkCreatePipelineLayout(device, &pipelineLayoutInfo, NULL, &pipelineLayout);
|
||||||
|
assert(result == VK_SUCCESS);
|
||||||
|
|
||||||
|
|
||||||
|
/* Descriptor set initialization */
|
||||||
|
|
||||||
|
VkDescriptorPoolSize typeCount[1];
|
||||||
|
typeCount[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||||
|
typeCount[0].descriptorCount = 1;
|
||||||
|
|
||||||
|
VkDescriptorPool descriptorPool;
|
||||||
|
VkDescriptorPoolCreateInfo descriptorPoolInfo = {};
|
||||||
|
descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||||
|
descriptorPoolInfo.pNext = NULL;
|
||||||
|
descriptorPoolInfo.maxSets = 1;
|
||||||
|
descriptorPoolInfo.poolSizeCount = 1;
|
||||||
|
descriptorPoolInfo.pPoolSizes = typeCount;
|
||||||
|
|
||||||
|
result = vkCreateDescriptorPool(device, &descriptorPoolInfo, NULL, &descriptorPool);
|
||||||
|
assert(result == VK_SUCCESS);
|
||||||
|
|
||||||
|
std::vector<VkDescriptorSet> descriptorSets;
|
||||||
|
VkDescriptorSetAllocateInfo descriptorSetAllocInfo[1];
|
||||||
|
descriptorSetAllocInfo[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||||
|
descriptorSetAllocInfo[0].pNext = NULL;
|
||||||
|
descriptorSetAllocInfo[0].descriptorPool = descriptorPool;
|
||||||
|
descriptorSetAllocInfo[0].descriptorSetCount = NUM_DESCRIPTOR_SETS;
|
||||||
|
descriptorSetAllocInfo[0].pSetLayouts = descriptorSetLayouts.data();
|
||||||
|
|
||||||
|
descriptorSets.resize(NUM_DESCRIPTOR_SETS);
|
||||||
|
result = vkAllocateDescriptorSets(device, descriptorSetAllocInfo, descriptorSets.data());
|
||||||
|
assert(result == VK_SUCCESS);
|
||||||
|
|
||||||
|
VkWriteDescriptorSet writes[1];
|
||||||
|
writes[0] = {};
|
||||||
|
writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
writes[0].pNext = NULL;
|
||||||
|
writes[0].dstSet = descriptorSets[0];
|
||||||
|
writes[0].descriptorCount = 1;
|
||||||
|
writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||||
|
writes[0].pBufferInfo = &uniformData.descriptorBufferInfo;
|
||||||
|
writes[0].dstArrayElement = 0;
|
||||||
|
writes[0].dstBinding = 0;
|
||||||
|
|
||||||
|
vkUpdateDescriptorSets(device, 1, writes, 0, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
/* Render pass definition */
|
||||||
|
|
||||||
|
// A semaphore (or fence) is required in order to acquire a
|
||||||
|
// swapchain image to prepare it for use in a render pass.
|
||||||
|
// The semaphore is normally used to hold back the rendering
|
||||||
|
// operation until the image is actually available.
|
||||||
|
// But since this sample does not render, the semaphore
|
||||||
|
// ends up being unused.
|
||||||
|
VkSemaphore imageAcquiredSemaphore;
|
||||||
|
VkSemaphoreCreateInfo imageAcquiredSemaphoreInfo;
|
||||||
|
imageAcquiredSemaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
|
imageAcquiredSemaphoreInfo.pNext = NULL;
|
||||||
|
imageAcquiredSemaphoreInfo.flags = 0;
|
||||||
|
|
||||||
|
result = vkCreateSemaphore(device, &imageAcquiredSemaphoreInfo, NULL, &imageAcquiredSemaphore);
|
||||||
|
assert(result == VK_SUCCESS);
|
||||||
|
|
||||||
|
// Acquire the swapchain image in order to set its layout
|
||||||
|
uint32_t currentBuffer;
|
||||||
|
result = vkAcquireNextImageKHR(device, swapchain, UINT64_MAX, imageAcquiredSemaphore, VK_NULL_HANDLE,
|
||||||
|
¤tBuffer);
|
||||||
|
assert(result >= 0);
|
||||||
|
|
||||||
|
// The initial layout for the color and depth attachments will be
|
||||||
|
// LAYOUT_UNDEFINED because at the start of the renderpass, we don't
|
||||||
|
// care about their contents. At the start of the subpass, the color
|
||||||
|
// attachment's layout will be transitioned to LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
||||||
|
// and the depth stencil attachment's layout will be transitioned to
|
||||||
|
// LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL. At the end of the renderpass,
|
||||||
|
// the color attachment's layout will be transitioned to
|
||||||
|
// LAYOUT_PRESENT_SRC_KHR to be ready to present. This is all done as part
|
||||||
|
// of the renderpass, no barriers are necessary.
|
||||||
|
VkAttachmentDescription attachments[1];
|
||||||
|
attachments[0].format = format;
|
||||||
|
attachments[0].samples = NUM_SAMPLES;
|
||||||
|
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
attachments[0].flags = 0;
|
||||||
|
|
||||||
|
// Depth
|
||||||
|
/*
|
||||||
|
* attachments[1].format = info.depth.format;
|
||||||
|
* attachments[1].samples = NUM_SAMPLES;
|
||||||
|
* attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
* attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
* attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
* attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
* attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
* attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
* attachments[1].flags = 0;
|
||||||
|
*/
|
||||||
|
|
||||||
|
VkAttachmentReference color_reference = {};
|
||||||
|
color_reference.attachment = 0;
|
||||||
|
color_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VkAttachmentReference depth_reference = {};
|
||||||
|
* depth_reference.attachment = 1;
|
||||||
|
* depth_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
*/
|
||||||
|
|
||||||
|
VkSubpassDescription subpass = {};
|
||||||
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
|
subpass.flags = 0;
|
||||||
|
subpass.inputAttachmentCount = 0;
|
||||||
|
subpass.pInputAttachments = NULL;
|
||||||
|
subpass.colorAttachmentCount = 1;
|
||||||
|
subpass.pColorAttachments = &color_reference;
|
||||||
|
subpass.pResolveAttachments = NULL;
|
||||||
|
subpass.pDepthStencilAttachment = NULL;//&depth_reference;
|
||||||
|
subpass.preserveAttachmentCount = 0;
|
||||||
|
subpass.pPreserveAttachments = NULL;
|
||||||
|
|
||||||
|
// Subpass dependency to wait for wsi image acquired semaphore before starting layout transition
|
||||||
|
VkSubpassDependency subpassDependency = {};
|
||||||
|
subpassDependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
|
subpassDependency.dstSubpass = 0;
|
||||||
|
subpassDependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
subpassDependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
subpassDependency.srcAccessMask = 0;
|
||||||
|
subpassDependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
subpassDependency.dependencyFlags = 0;
|
||||||
|
|
||||||
|
VkRenderPass renderPass;
|
||||||
|
VkRenderPassCreateInfo renderPassInfo = {};
|
||||||
|
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
|
renderPassInfo.pNext = NULL;
|
||||||
|
renderPassInfo.attachmentCount = 1;
|
||||||
|
renderPassInfo.pAttachments = attachments;
|
||||||
|
renderPassInfo.subpassCount = 1;
|
||||||
|
renderPassInfo.pSubpasses = &subpass;
|
||||||
|
renderPassInfo.dependencyCount = 1;
|
||||||
|
renderPassInfo.pDependencies = &subpassDependency;
|
||||||
|
|
||||||
|
result = vkCreateRenderPass(device, &renderPassInfo, NULL, &renderPass);
|
||||||
|
assert(result == VK_SUCCESS);
|
||||||
|
|
||||||
|
/* Shader assignment and creation */
|
||||||
|
//Creation via runtime GLSL compiling
|
||||||
|
VkShaderModule vertexShader; //<- spirv bytecode
|
||||||
|
VkShaderModule fragmentShader;
|
||||||
|
|
||||||
|
|
||||||
|
HANDLE glslFile = CreateFileW(
|
||||||
|
L"../src/shaderv.vert",
|
||||||
|
GENERIC_READ,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
//FILE* glslFile = fopen(, "r");
|
||||||
|
assert(glslFile);
|
||||||
|
const uint64_t SOURCE_SIZE = 1024 * 1024;
|
||||||
|
char* source = (char*)calloc(SOURCE_SIZE, sizeof(char));
|
||||||
|
DWORD bytesRead = 0;
|
||||||
|
if (!ReadFile(glslFile, source, SOURCE_SIZE, &bytesRead, NULL)) exit(-5);
|
||||||
|
//char bytesReadString[(6* sizeof(char))];
|
||||||
|
//itoa(bytesRead, bytesReadString, 10);
|
||||||
|
//OutputDebugStringA(bytesReadString);
|
||||||
|
OutputDebugStringA("\n");
|
||||||
|
|
||||||
|
glslang_initialize_process();
|
||||||
|
glslang_stage_t stage = GLSLANG_STAGE_VERTEX;
|
||||||
|
|
||||||
|
glslang_input_t input = {
|
||||||
|
.language = GLSLANG_SOURCE_GLSL,
|
||||||
|
.stage = stage,
|
||||||
|
.client = GLSLANG_CLIENT_VULKAN,
|
||||||
|
.client_version = GLSLANG_TARGET_VULKAN_1_1,
|
||||||
|
.target_language = GLSLANG_TARGET_SPV,
|
||||||
|
.target_language_version = GLSLANG_TARGET_SPV_1_3,
|
||||||
|
.code = source,
|
||||||
|
.default_version = 100,
|
||||||
|
.default_profile = GLSLANG_NO_PROFILE,
|
||||||
|
.force_default_version_and_profile = false,
|
||||||
|
.forward_compatible = false,
|
||||||
|
.messages = GLSLANG_MSG_DEFAULT_BIT,
|
||||||
|
.resource = glslang_default_resource()
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
glslang_shader_t* shader = glslang_shader_create(&input);
|
||||||
|
OutputDebugStringA("GLSL parse faild\n");
|
||||||
|
if (!glslang_shader_preprocess(shader, &input)) {
|
||||||
|
OutputDebugStringA("GLSL preprocessing fail\n");
|
||||||
|
OutputDebugStringA(glslang_shader_get_info_log(shader));
|
||||||
|
|
||||||
|
OutputDebugStringA("\n");
|
||||||
|
OutputDebugStringA(glslang_shader_get_info_debug_log(shader));
|
||||||
|
OutputDebugStringA("\n");
|
||||||
|
|
||||||
|
OutputDebugStringA(glslang_shader_get_preprocessed_code(shader));
|
||||||
|
OutputDebugStringA("\n");
|
||||||
|
|
||||||
|
exit(-6);
|
||||||
|
}
|
||||||
|
if (!glslang_shader_parse(shader, &input)) {
|
||||||
|
OutputDebugStringA("GLSL parse fail\n");
|
||||||
|
OutputDebugStringA(glslang_shader_get_info_log(shader));
|
||||||
|
OutputDebugStringA(glslang_shader_get_info_debug_log(shader));
|
||||||
|
OutputDebugStringA("\n");
|
||||||
|
OutputDebugStringA(input.code);
|
||||||
|
exit(-7);
|
||||||
|
}
|
||||||
|
glslang_program_t* program = glslang_program_create();
|
||||||
|
glslang_program_add_shader(program, shader);
|
||||||
|
|
||||||
|
if (!glslang_program_link(program, GLSLANG_MSG_SPV_RULES_BIT | GLSLANG_MSG_VULKAN_RULES_BIT)) {
|
||||||
|
exit(-8);
|
||||||
|
}
|
||||||
|
|
||||||
|
glslang_program_SPIRV_generate(program, stage);
|
||||||
|
std::vector<uint32_t> spirv;
|
||||||
|
size_t programSize = glslang_program_SPIRV_get_size(program);
|
||||||
|
spirv.resize(programSize);
|
||||||
|
glslang_program_SPIRV_get(program, spirv.data());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* const char* spirv_messages = glslang_program_SPIRV_get_messages(program);
|
||||||
|
* if(spirv_messages) {
|
||||||
|
* fprintf(stderr, "SPIRV mes: '%s'", spirv_messages);
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
VkShaderModuleCreateInfo shaderInfo = {};
|
||||||
|
shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||||
|
shaderInfo.codeSize = spirv.size() * sizeof(uint32_t);
|
||||||
|
shaderInfo.pCode = (const uint32_t*)spirv.data();
|
||||||
|
|
||||||
|
result = vkCreateShaderModule(device, &shaderInfo, NULL, &vertexShader);
|
||||||
|
assert(result == VK_SUCCESS);
|
||||||
|
glslang_program_delete(program);
|
||||||
|
glslang_shader_delete(shader);
|
||||||
|
|
||||||
|
glslang_finalize_process();
|
||||||
|
|
||||||
|
//also compile fragment shader
|
||||||
|
CloseHandle(glslFile);
|
||||||
|
glslFile = CreateFileW(
|
||||||
|
L"../src/shaderf.frag",
|
||||||
|
GENERIC_READ,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
assert(glslFile);
|
||||||
|
memset(source, 0, SOURCE_SIZE * sizeof(char));
|
||||||
|
if (!ReadFile(glslFile, source, SOURCE_SIZE, &bytesRead, NULL)) exit(-5);
|
||||||
|
glslang_initialize_process();
|
||||||
|
|
||||||
|
stage = GLSLANG_STAGE_FRAGMENT;
|
||||||
|
input.stage = stage;
|
||||||
|
shader = glslang_shader_create(&input);
|
||||||
|
|
||||||
|
if (!glslang_shader_preprocess(shader, &input)) {
|
||||||
|
OutputDebugStringA("GLSL preprocessing fail\n");
|
||||||
|
OutputDebugStringA(glslang_shader_get_info_log(shader));
|
||||||
|
|
||||||
|
OutputDebugStringA("\n");
|
||||||
|
OutputDebugStringA(glslang_shader_get_info_debug_log(shader));
|
||||||
|
OutputDebugStringA("\n");
|
||||||
|
|
||||||
|
OutputDebugStringA(glslang_shader_get_preprocessed_code(shader));
|
||||||
|
OutputDebugStringA("\n");
|
||||||
|
|
||||||
|
exit(-6);
|
||||||
|
}
|
||||||
|
if (!glslang_shader_parse(shader, &input)) {
|
||||||
|
OutputDebugStringA("GLSL parse fail\n");
|
||||||
|
OutputDebugStringA(glslang_shader_get_info_log(shader));
|
||||||
|
OutputDebugStringA(glslang_shader_get_info_debug_log(shader));
|
||||||
|
OutputDebugStringA("\n");
|
||||||
|
OutputDebugStringA(input.code);
|
||||||
|
exit(-7);
|
||||||
|
};
|
||||||
|
|
||||||
|
program = glslang_program_create();
|
||||||
|
glslang_program_add_shader(program, shader);
|
||||||
|
|
||||||
|
if (!glslang_program_link(program, GLSLANG_MSG_SPV_RULES_BIT | GLSLANG_MSG_VULKAN_RULES_BIT)) {
|
||||||
|
exit(-8);
|
||||||
|
}
|
||||||
|
|
||||||
|
glslang_program_SPIRV_generate(program, stage);
|
||||||
|
programSize = glslang_program_SPIRV_get_size(program);
|
||||||
|
spirv.resize(programSize);
|
||||||
|
glslang_program_SPIRV_get(program, spirv.data());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* const char* spirv_messages = glslang_program_SPIRV_get_messages(program);
|
||||||
|
* if(spirv_messages) {
|
||||||
|
* fprintf(stderr, "SPIRV mes: '%s'", spirv_messages);
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||||
|
shaderInfo.codeSize = spirv.size() * sizeof(uint32_t);
|
||||||
|
shaderInfo.pCode = (const uint32_t*)spirv.data();
|
||||||
|
|
||||||
|
result = vkCreateShaderModule(device, &shaderInfo, NULL, &fragmentShader);
|
||||||
|
assert(result == VK_SUCCESS);
|
||||||
|
glslang_program_delete(program);
|
||||||
|
glslang_shader_delete(shader);
|
||||||
|
|
||||||
|
glslang_finalize_process();
|
||||||
|
CloseHandle(glslFile);
|
||||||
|
free(source);
|
||||||
|
|
||||||
|
//Pipeline setup
|
||||||
|
VkPipelineShaderStageCreateInfo shaderStages[2];
|
||||||
|
shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||||
|
shaderStages[0].pNext = NULL;
|
||||||
|
shaderStages[0].pSpecializationInfo = NULL;
|
||||||
|
shaderStages[0].flags = 0;
|
||||||
|
shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
|
shaderStages[0].pName = "main";
|
||||||
|
shaderStages[0].module = vertexShader;
|
||||||
|
shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||||
|
shaderStages[1].pNext = NULL;
|
||||||
|
shaderStages[1].pSpecializationInfo = NULL;
|
||||||
|
shaderStages[1].flags = 0;
|
||||||
|
shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
shaderStages[1].pName = "main";
|
||||||
|
shaderStages[1].module = fragmentShader;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Window show and event loop
|
//Window show and event loop
|
||||||
|
|
@ -548,6 +962,13 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vkDestroyShaderModule(device, shaderStages[0].module, NULL);
|
||||||
|
vkDestroyShaderModule(device, shaderStages[1].module, NULL);
|
||||||
|
vkDestroyRenderPass(device, renderPass, NULL);
|
||||||
|
vkDestroySemaphore(device, imageAcquiredSemaphore, NULL);
|
||||||
|
vkDestroyDescriptorPool(device, descriptorPool, NULL);
|
||||||
|
for (int i = 0; i < NUM_DESCRIPTOR_SETS; i++) vkDestroyDescriptorSetLayout(device, descriptorSetLayouts[i], NULL);
|
||||||
|
vkDestroyPipelineLayout(device, pipelineLayout, NULL);
|
||||||
vkDestroyBuffer(device, uniformData.buf, NULL);
|
vkDestroyBuffer(device, uniformData.buf, NULL);
|
||||||
vkFreeMemory(device, uniformData.mem, NULL);
|
vkFreeMemory(device, uniformData.mem, NULL);
|
||||||
VkCommandBuffer cmdBufs[1] = {cmd};
|
VkCommandBuffer cmdBufs[1] = {cmd};
|
||||||
|
|
|
||||||
11
src/shaderf.frag
Normal file
11
src/shaderf.frag
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#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 texcoord;
|
||||||
|
layout (location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
outColor = textureLod(tex, texcoord, 0.0);
|
||||||
|
}
|
||||||
19
src/shaderv.vert
Normal file
19
src/shaderv.vert
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#version 400
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
#extension GL_ARB_shading_language_420pack : enable
|
||||||
|
|
||||||
|
//set = desc set layout
|
||||||
|
//binding = desc set binding
|
||||||
|
//var[I] = descriptor set pos in array
|
||||||
|
layout (std140, set = 0, binding = 0) uniform buf {
|
||||||
|
mat4 mvp;
|
||||||
|
} ubuf;
|
||||||
|
|
||||||
|
layout (location = 0) in vec4 pos;
|
||||||
|
layout (location = 1) in vec2 inTexCoords;
|
||||||
|
layout (location = 0) out vec2 texcoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
texcoord = inTexCoords;
|
||||||
|
gl_Position = ubuf.mvp * pos;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue