387 lines
14 KiB
C++
387 lines
14 KiB
C++
// AMD AMDUtils code
|
|
//
|
|
// Copyright(c) 2018 Advanced Micro Devices, Inc.All rights reserved.
|
|
//
|
|
// Vulkan Samples
|
|
//
|
|
// Copyright (C) 2015-2016 Valve Corporation
|
|
// Copyright (C) 2015-2016 LunarG, Inc.
|
|
// Copyright (C) 2015-2016 Google, Inc.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files(the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions :
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
// THE SOFTWARE.
|
|
|
|
|
|
#include "gltfbboxpassvk.h"
|
|
|
|
#include "devicevk.h"
|
|
#include "staticbufferpoolvk.h"
|
|
#include "dynamicbufferringvk.h"
|
|
#include "resourceviewheapsvk.h"
|
|
#include "uploadheapvk.h"
|
|
#include "shadercompilerhelper.h"
|
|
#include "camera.h"
|
|
#include "gltfhelpers.h"
|
|
#include "gltfhelpers_vulkan.h"
|
|
|
|
|
|
void GltfBBoxPassVK::OnCreate(
|
|
DeviceVK* pDevice,
|
|
VkRenderPass renderPass,
|
|
UploadHeapVK* pUploadHeap,
|
|
ResourceViewHeapsVK *pHeaps,
|
|
DynamicBufferRingVK *pDynamicBufferRing,
|
|
StaticBufferPoolVK *pStaticBufferPool,
|
|
GLTFCommon *pGLTFData) {
|
|
VkResult res;
|
|
|
|
m_pGLTFData = pGLTFData;
|
|
m_pDynamicBufferRing = pDynamicBufferRing;
|
|
m_pResourceViewHeaps = pHeaps;
|
|
m_pStaticBufferPool = pStaticBufferPool;
|
|
|
|
// set indices
|
|
{
|
|
short indices[] = {
|
|
0,1, 1,2, 2,3, 3,0,
|
|
4,5, 5,6, 6,7, 7,4,
|
|
0,4,
|
|
1,5,
|
|
2,6,
|
|
3,7
|
|
};
|
|
m_NumIndices = _countof(indices);
|
|
|
|
m_indexType = VK_INDEX_TYPE_UINT16;
|
|
|
|
void *pDest;
|
|
m_pStaticBufferPool->AllocIndexBuffer(m_NumIndices, sizeof(short), &pDest, &m_IBV);
|
|
memcpy(pDest, indices, sizeof(short)*m_NumIndices);
|
|
}
|
|
|
|
// set vertices
|
|
{
|
|
float vertices[] = {
|
|
-1, -1, 1, 1,
|
|
1, -1, 1, 1,
|
|
1, 1, 1, 1,
|
|
-1, 1, 1, 1,
|
|
-1, -1, -1, 1,
|
|
1, -1, -1, 1,
|
|
1, 1, -1, 1,
|
|
-1, 1, -1, 1,
|
|
};
|
|
|
|
void *pDest;
|
|
m_pStaticBufferPool->AllocVertexBuffer(8, 4 * sizeof(float), &pDest, &m_VBV);
|
|
memcpy(pDest, vertices, sizeof(float) * 4 * 8);
|
|
}
|
|
|
|
// the vertex shader
|
|
static const char* vertexShader =
|
|
"#version 400\n"
|
|
"#extension GL_ARB_separate_shader_objects : enable\n"
|
|
"#extension GL_ARB_shading_language_420pack : enable\n"
|
|
"layout (std140, binding = 0) uniform _cbPerObject\n"
|
|
"{\n"
|
|
" mat4 u_mWorldViewProj;\n"
|
|
" vec4 u_Center;\n"
|
|
" vec4 u_Radius;\n"
|
|
" vec4 u_Color;\n"
|
|
"} cbPerObject;\n"
|
|
"layout(location = 0) in vec4 position; \n"
|
|
"layout (location = 0) out vec4 outColor;\n"
|
|
"void main() {\n"
|
|
" outColor = cbPerObject.u_Color;\n"
|
|
" gl_Position = cbPerObject.u_mWorldViewProj * (cbPerObject.u_Center + position * vec4(cbPerObject.u_Radius.xyz,1.0f));\n"
|
|
"}\n";
|
|
|
|
// the pixel shader
|
|
static const char* pixelShader =
|
|
"#version 400\n"
|
|
"#extension GL_ARB_separate_shader_objects : enable\n"
|
|
"#extension GL_ARB_shading_language_420pack : enable\n"
|
|
"layout (location = 0) in vec4 inColor;\n"
|
|
"layout (location = 0) out vec4 outColor;\n"
|
|
"void main() {\n"
|
|
" outColor = inColor;\n"
|
|
"}";
|
|
|
|
/////////////////////////////////////////////
|
|
// Compile and create shaders
|
|
|
|
init_glslang();
|
|
|
|
std::map<std::string, std::string> attributeDefines;
|
|
|
|
VkPipelineShaderStageCreateInfo m_vertexShader;
|
|
res = VKCompile(pDevice->GetDevice(), SST_GLSL, VK_SHADER_STAGE_VERTEX_BIT, vertexShader, "main", attributeDefines, &m_vertexShader);
|
|
assert(res == VK_SUCCESS);
|
|
|
|
VkPipelineShaderStageCreateInfo m_fragmentShader;
|
|
res = VKCompile(pDevice->GetDevice(), SST_GLSL, VK_SHADER_STAGE_FRAGMENT_BIT, pixelShader, "main", attributeDefines, &m_fragmentShader);
|
|
assert(res == VK_SUCCESS);
|
|
|
|
finalize_glslang();
|
|
|
|
std::vector<VkPipelineShaderStageCreateInfo> shaderStages = { m_vertexShader, m_fragmentShader };
|
|
|
|
/////////////////////////////////////////////
|
|
// Create descriptor set and the pipeline layout
|
|
|
|
std::vector<VkDescriptorSetLayoutBinding> layout_bindings(1);
|
|
layout_bindings[0].binding = 0;
|
|
layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
|
layout_bindings[0].descriptorCount = 1;
|
|
layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
layout_bindings[0].pImmutableSamplers = NULL;
|
|
|
|
m_pResourceViewHeaps->AllocDescriptor(&layout_bindings, &m_descriptorSetLayout, &m_descriptorSet);
|
|
|
|
VkWriteDescriptorSet writes[1];
|
|
writes[0] = {};
|
|
writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
writes[0].pNext = NULL;
|
|
writes[0].dstSet = m_descriptorSet;
|
|
writes[0].descriptorCount = 1;
|
|
writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
|
writes[0].pBufferInfo = &m_pDynamicBufferRing->GetMainBuffer(sizeof(per_object));
|
|
writes[0].dstArrayElement = 0;
|
|
writes[0].dstBinding = 0;
|
|
|
|
vkUpdateDescriptorSets(pDevice->GetDevice(), 1, writes, 0, NULL);
|
|
|
|
std::vector<VkDescriptorSetLayout> descriptorSetLayout = { m_descriptorSetLayout };
|
|
|
|
/* Now use the descriptor layout to create a pipeline layout */
|
|
VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = {};
|
|
pPipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
|
pPipelineLayoutCreateInfo.pNext = NULL;
|
|
pPipelineLayoutCreateInfo.pushConstantRangeCount = 0;
|
|
pPipelineLayoutCreateInfo.pPushConstantRanges = NULL;
|
|
pPipelineLayoutCreateInfo.setLayoutCount = (uint32_t)descriptorSetLayout.size();
|
|
pPipelineLayoutCreateInfo.pSetLayouts = descriptorSetLayout.data();
|
|
|
|
res = vkCreatePipelineLayout(pDevice->GetDevice(), &pPipelineLayoutCreateInfo, NULL, &m_pipelineLayout);
|
|
assert(res == VK_SUCCESS);
|
|
|
|
/////////////////////////////////////////////
|
|
// Create pipeline
|
|
|
|
// Create the input attribute description / input layout(in DX12 jargon)
|
|
|
|
VkVertexInputBindingDescription vi_binding = {};
|
|
vi_binding.binding = 0;
|
|
vi_binding.stride = sizeof(float) * 4;
|
|
vi_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
|
|
|
std::vector<VkVertexInputAttributeDescription> vi_attrs(1);
|
|
// Position
|
|
vi_attrs[0].location = 0;
|
|
vi_attrs[0].binding = 0;
|
|
vi_attrs[0].format = VK_FORMAT_R32G32B32A32_SFLOAT;
|
|
vi_attrs[0].offset = 0;
|
|
|
|
VkPipelineVertexInputStateCreateInfo vi = {};
|
|
vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
|
vi.pNext = NULL;
|
|
vi.flags = 0;
|
|
vi.vertexBindingDescriptionCount = 1;
|
|
vi.pVertexBindingDescriptions = &vi_binding;
|
|
vi.vertexAttributeDescriptionCount = (uint32_t)vi_attrs.size();
|
|
vi.pVertexAttributeDescriptions = vi_attrs.data();
|
|
|
|
// input assembly state
|
|
|
|
VkPipelineInputAssemblyStateCreateInfo ia = {};
|
|
ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
|
ia.pNext = NULL;
|
|
ia.flags = 0;
|
|
ia.primitiveRestartEnable = VK_FALSE;
|
|
ia.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
|
|
|
// rasterizer state
|
|
|
|
VkPipelineRasterizationStateCreateInfo rs = {};
|
|
rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
|
rs.pNext = NULL;
|
|
rs.flags = 0;
|
|
rs.polygonMode = VK_POLYGON_MODE_LINE;
|
|
rs.cullMode = VK_CULL_MODE_NONE;
|
|
rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
|
rs.depthClampEnable = VK_FALSE;
|
|
rs.rasterizerDiscardEnable = VK_FALSE;
|
|
rs.depthBiasEnable = VK_FALSE;
|
|
rs.depthBiasConstantFactor = 0;
|
|
rs.depthBiasClamp = 0;
|
|
rs.depthBiasSlopeFactor = 0;
|
|
rs.lineWidth = 1.0f;
|
|
|
|
VkPipelineColorBlendAttachmentState att_state[1];
|
|
att_state[0].colorWriteMask = 0xf;
|
|
att_state[0].blendEnable = VK_TRUE;
|
|
att_state[0].alphaBlendOp = VK_BLEND_OP_ADD;
|
|
att_state[0].colorBlendOp = VK_BLEND_OP_ADD;
|
|
att_state[0].srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
|
att_state[0].dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
|
att_state[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
|
att_state[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
|
|
|
// Color blend state
|
|
|
|
VkPipelineColorBlendStateCreateInfo cb = {};
|
|
cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
|
cb.flags = 0;
|
|
cb.pNext = NULL;
|
|
cb.attachmentCount = 1;
|
|
cb.pAttachments = att_state;
|
|
cb.logicOpEnable = VK_FALSE;
|
|
cb.logicOp = VK_LOGIC_OP_NO_OP;
|
|
cb.blendConstants[0] = 1.0f;
|
|
cb.blendConstants[1] = 1.0f;
|
|
cb.blendConstants[2] = 1.0f;
|
|
cb.blendConstants[3] = 1.0f;
|
|
|
|
std::vector<VkDynamicState> dynamicStateEnables = {
|
|
VK_DYNAMIC_STATE_VIEWPORT,
|
|
VK_DYNAMIC_STATE_SCISSOR
|
|
};
|
|
VkPipelineDynamicStateCreateInfo dynamicState = {};
|
|
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
|
dynamicState.pNext = NULL;
|
|
dynamicState.pDynamicStates = dynamicStateEnables.data();
|
|
dynamicState.dynamicStateCount = (uint32_t)dynamicStateEnables.size();
|
|
|
|
// view port state
|
|
|
|
VkPipelineViewportStateCreateInfo vp = {};
|
|
vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
|
vp.pNext = NULL;
|
|
vp.flags = 0;
|
|
vp.viewportCount = 1;
|
|
vp.scissorCount = 1;
|
|
vp.pScissors = NULL;
|
|
vp.pViewports = NULL;
|
|
|
|
// depth stencil state
|
|
|
|
VkPipelineDepthStencilStateCreateInfo ds = {};
|
|
ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
|
ds.pNext = NULL;
|
|
ds.flags = 0;
|
|
ds.depthTestEnable = true;
|
|
ds.depthWriteEnable = true;
|
|
ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
|
|
ds.depthBoundsTestEnable = VK_FALSE;
|
|
ds.stencilTestEnable = VK_FALSE;
|
|
ds.back.failOp = VK_STENCIL_OP_KEEP;
|
|
ds.back.passOp = VK_STENCIL_OP_KEEP;
|
|
ds.back.compareOp = VK_COMPARE_OP_ALWAYS;
|
|
ds.back.compareMask = 0;
|
|
ds.back.reference = 0;
|
|
ds.back.depthFailOp = VK_STENCIL_OP_KEEP;
|
|
ds.back.writeMask = 0;
|
|
ds.minDepthBounds = 0;
|
|
ds.maxDepthBounds = 0;
|
|
ds.stencilTestEnable = VK_FALSE;
|
|
ds.front = ds.back;
|
|
|
|
// multi sample state
|
|
|
|
VkPipelineMultisampleStateCreateInfo ms;
|
|
ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
|
ms.pNext = NULL;
|
|
ms.flags = 0;
|
|
ms.pSampleMask = NULL;
|
|
ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
|
ms.sampleShadingEnable = VK_FALSE;
|
|
ms.alphaToCoverageEnable = VK_FALSE;
|
|
ms.alphaToOneEnable = VK_FALSE;
|
|
ms.minSampleShading = 0.0;
|
|
|
|
// create pipeline cache
|
|
|
|
VkPipelineCacheCreateInfo pipelineCache;
|
|
pipelineCache.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
|
|
pipelineCache.pNext = NULL;
|
|
pipelineCache.initialDataSize = 0;
|
|
pipelineCache.pInitialData = NULL;
|
|
pipelineCache.flags = 0;
|
|
res = vkCreatePipelineCache(pDevice->GetDevice(), &pipelineCache, NULL, &m_pipelineCache);
|
|
assert(res == VK_SUCCESS);
|
|
|
|
// create pipeline
|
|
|
|
VkGraphicsPipelineCreateInfo pipeline = {};
|
|
pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
|
pipeline.pNext = NULL;
|
|
pipeline.layout = m_pipelineLayout;
|
|
pipeline.basePipelineHandle = VK_NULL_HANDLE;
|
|
pipeline.basePipelineIndex = 0;
|
|
pipeline.flags = 0;
|
|
pipeline.pVertexInputState = &vi;
|
|
pipeline.pInputAssemblyState = &ia;
|
|
pipeline.pRasterizationState = &rs;
|
|
pipeline.pColorBlendState = &cb;
|
|
pipeline.pTessellationState = NULL;
|
|
pipeline.pMultisampleState = &ms;
|
|
pipeline.pDynamicState = &dynamicState;
|
|
pipeline.pViewportState = &vp;
|
|
pipeline.pDepthStencilState = &ds;
|
|
pipeline.pStages = shaderStages.data();
|
|
pipeline.stageCount = (uint32_t)shaderStages.size();
|
|
pipeline.renderPass = renderPass;
|
|
pipeline.subpass = 0;
|
|
|
|
res = vkCreateGraphicsPipelines(pDevice->GetDevice(), m_pipelineCache, 1, &pipeline, NULL, &m_pipeline);
|
|
assert(res == VK_SUCCESS);
|
|
|
|
}
|
|
|
|
void GltfBBoxPassVK::OnDestroy() {
|
|
}
|
|
|
|
void GltfBBoxPassVK::DrawMesh(VkCommandBuffer cmd_buf, int meshIndex, const glm::mat4x4& worldMatrix) {
|
|
vkCmdBindVertexBuffers(cmd_buf, 0, 1, &m_VBV.buffer, &m_VBV.offset);
|
|
vkCmdBindIndexBuffer(cmd_buf, m_IBV.buffer, m_IBV.offset, m_indexType);
|
|
|
|
vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline);
|
|
|
|
VkDescriptorSet descritorSets[1] = { m_descriptorSet };
|
|
|
|
glm::mat4x4 mWorldViewProj = worldMatrix * m_Camera;
|
|
|
|
tfMesh *pMesh = &m_pGLTFData->m_meshes[meshIndex];
|
|
for (unsigned int p = 0; p < pMesh->m_pPrimitives.size(); p++) {
|
|
// Set per Object constants
|
|
//
|
|
per_object *cbPerObject;
|
|
VkDescriptorBufferInfo perObjectDesc;
|
|
m_pDynamicBufferRing->AllocConstantBuffer(sizeof(per_object), (void **)&cbPerObject, &perObjectDesc);
|
|
cbPerObject->mWorldViewProj = mWorldViewProj;
|
|
cbPerObject->vCenter = pMesh->m_pPrimitives[p].m_center;
|
|
cbPerObject->vRadius = pMesh->m_pPrimitives[p].m_radius;
|
|
cbPerObject->vColor = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
|
|
|
uint32_t uniformOffsets[1] = { (uint32_t)perObjectDesc.offset };
|
|
vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, descritorSets, 1, uniformOffsets);
|
|
|
|
vkCmdDrawIndexed(cmd_buf, m_NumIndices, 1, 0, 0, 0);
|
|
}
|
|
|
|
}
|
|
|