From 560f7da9e73f92f49c5ec7c37ec6725f0ec4a3f2 Mon Sep 17 00:00:00 2001 From: kearwood Date: Thu, 7 Jul 2022 19:29:50 -0700 Subject: [PATCH] Implemented automatic binding of push constants at runtime using SPIRV-Reflection. Replaced GL uniforms with Vulkan push constants. --- kraken/KRAmbientZone.cpp | 2 +- kraken/KRAudioSource.cpp | 2 +- kraken/KRBone.cpp | 2 +- kraken/KRCamera.cpp | 10 +- kraken/KRCollider.cpp | 2 +- kraken/KRDirectionalLight.cpp | 2 +- kraken/KRLight.cpp | 10 +- kraken/KRMaterial.cpp | 8 +- kraken/KRParticleSystemNewtonian.cpp | 2 +- kraken/KRPipeline.cpp | 382 +++++++---------------- kraken/KRPipeline.h | 21 +- kraken/KRPointLight.cpp | 2 +- kraken/KRReverbZone.cpp | 2 +- kraken/KRScene.cpp | 2 +- kraken/KRSprite.cpp | 2 +- standard_assets/shaders/vulkan_test.vert | 6 + 16 files changed, 148 insertions(+), 309 deletions(-) diff --git a/kraken/KRAmbientZone.cpp b/kraken/KRAmbientZone.cpp index e71d56c..d9f249c 100755 --- a/kraken/KRAmbientZone.cpp +++ b/kraken/KRAmbientZone.cpp @@ -145,7 +145,7 @@ void KRAmbientZone::render(RenderInfo& ri) info.vertexAttributes = sphereModel->getVertexAttributes(); KRPipeline *pPipeline = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pPipeline->bind(*ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); + pPipeline->bind(ri.commandBuffer, *ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); sphereModel->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f); } // sphereModel diff --git a/kraken/KRAudioSource.cpp b/kraken/KRAudioSource.cpp index 6067774..fa0bcdd 100755 --- a/kraken/KRAudioSource.cpp +++ b/kraken/KRAudioSource.cpp @@ -211,7 +211,7 @@ void KRAudioSource::render(RenderInfo& ri) info.vertexAttributes = sphereModel->getVertexAttributes(); KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->bind(*ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); sphereModel->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f); } // sphereModels.size() diff --git a/kraken/KRBone.cpp b/kraken/KRBone.cpp index 423cdbe..195e192 100755 --- a/kraken/KRBone.cpp +++ b/kraken/KRBone.cpp @@ -95,7 +95,7 @@ void KRBone::render(RenderInfo& ri) info.vertexAttributes = sphereModel->getVertexAttributes(); KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->bind(*ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); sphereModel->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f); } // sphereModel diff --git a/kraken/KRCamera.cpp b/kraken/KRCamera.cpp index 07c77f9..2e4f5ce 100755 --- a/kraken/KRCamera.cpp +++ b/kraken/KRCamera.cpp @@ -231,7 +231,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS info.vertexAttributes = sphereMesh->getVertexAttributes(); info.modelFormat = sphereMesh->getModelFormat(); KRPipeline* testPipeline = m_pContext->getPipelineManager()->getPipeline(compositeSurface, info); - testPipeline->bind(commandBuffer); + testPipeline->bind(commandBuffer, *this, m_viewport, Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_OPAQUE, Vector3::Zero(), 0.0f, Vector4::Zero()); sphereMesh->renderNoMaterials(commandBuffer, info.renderPass, "Vulkan Test", "vulkan_test", 1.0); } @@ -260,7 +260,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS info.cullMode = PipelineInfo::CullMode::kCullNone; KRPipeline* pPipeline = getContext().getPipelineManager()->getPipeline(compositeSurface, info); - pPipeline->bind(*this, m_viewport, Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_OPAQUE, Vector3::Zero(), 0.0f, Vector4::Zero()); + pPipeline->bind(commandBuffer, *this, m_viewport, Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_OPAQUE, Vector3::Zero(), 0.0f, Vector4::Zero()); getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture, 0.0f, KRTexture::TEXTURE_USAGE_SKY_CUBE); @@ -354,7 +354,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS Matrix4 matModel = Matrix4(); matModel.scale((*itr).first.size() * 0.5f); matModel.translate((*itr).first.center()); - pVisShader->bind(*this, m_viewport, matModel, nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, Vector3::Zero(), 0.0f, Vector4::Zero()); + pVisShader->bind(commandBuffer, *this, m_viewport, matModel, nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, Vector3::Zero(), 0.0f, Vector4::Zero()); vkCmdDraw(commandBuffer, 14, 1, 0, 0); } } @@ -572,7 +572,7 @@ void KRCamera::renderPost(VkCommandBuffer& commandBuffer, KRSurface& surface) KRPipeline *postShader = m_pContext->getPipelineManager()->getPipeline(surface, info); - postShader->bind(*this, m_viewport, Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, Vector3::Zero(), 0.0f, m_fade_color); + postShader->bind(commandBuffer, *this, m_viewport, Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, Vector3::Zero(), 0.0f, m_fade_color); m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 0, compositeDepthTexture); m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 1, compositeColorTexture); @@ -747,7 +747,7 @@ void KRCamera::renderPost(VkCommandBuffer& commandBuffer, KRSurface& surface) info.vertexAttributes = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); info.modelFormat = KRMesh::model_format_t::KRENGINE_MODEL_FORMAT_TRIANGLES; KRPipeline *fontShader = m_pContext->getPipelineManager()->getPipeline(surface, info); - fontShader->bind(*this, m_viewport, Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, Vector3::Zero(), 0.0f, Vector4::Zero()); + fontShader->bind(commandBuffer, *this, m_viewport, Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, Vector3::Zero(), 0.0f, Vector4::Zero()); m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font"), 0.0f, KRTexture::TEXTURE_USAGE_UI); diff --git a/kraken/KRCollider.cpp b/kraken/KRCollider.cpp index 7e95d09..28fa53d 100755 --- a/kraken/KRCollider.cpp +++ b/kraken/KRCollider.cpp @@ -219,7 +219,7 @@ void KRCollider::render(RenderInfo& ri) KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->bind(*ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); m_model->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f); diff --git a/kraken/KRDirectionalLight.cpp b/kraken/KRDirectionalLight.cpp index dbb7b71..484bac6 100755 --- a/kraken/KRDirectionalLight.cpp +++ b/kraken/KRDirectionalLight.cpp @@ -152,7 +152,7 @@ void KRDirectionalLight::render(RenderInfo& ri) { info.modelFormat = KRMesh::model_format_t::KRENGINE_MODEL_FORMAT_STRIP; KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->bind(*ri.camera, ri.viewport, getModelMatrix(), nullptr, &this_light, nullptr, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), nullptr, &this_light, nullptr, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); pShader->setUniform(KRPipeline::KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE, light_direction_view_space); pShader->setUniform(KRPipeline::KRENGINE_UNIFORM_LIGHT_COLOR, m_color); diff --git a/kraken/KRLight.cpp b/kraken/KRLight.cpp index 6346912..b62ec30 100755 --- a/kraken/KRLight.cpp +++ b/kraken/KRLight.cpp @@ -270,7 +270,7 @@ void KRLight::render(RenderInfo& ri) { info.modelFormat = KRMesh::model_format_t::KRENGINE_MODEL_FORMAT_TRIANGLES; KRPipeline *pParticleShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info); - pParticleShader->bind(*ri.camera, ri.viewport, particleModelMatrix, &this_point_light, &this_directional_light, &this_spot_light, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); + pParticleShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, particleModelMatrix, &this_point_light, &this_directional_light, &this_spot_light, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); pParticleShader->setUniform(KRPipeline::KRENGINE_UNIFORM_LIGHT_COLOR, m_color * ri.camera->settings.dust_particle_intensity * m_dust_particle_intensity * m_intensity); pParticleShader->setUniform(KRPipeline::KRENGINE_UNIFORM_PARTICLE_ORIGIN, Matrix4::DotWDiv(Matrix4::Invert(particleModelMatrix), Vector3::Zero())); pParticleShader->setUniform(KRPipeline::KRENGINE_UNIFORM_FLARE_SIZE, m_dust_particle_size); @@ -320,7 +320,7 @@ void KRLight::render(RenderInfo& ri) { KRPipeline *pFogShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info); - pFogShader->bind(*ri.camera, ri.viewport, Matrix4(), &this_point_light, &this_directional_light, &this_spot_light, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE, Vector3::Zero(), 0.0f, Vector4::Zero()); + pFogShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, Matrix4(), &this_point_light, &this_directional_light, &this_spot_light, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE, Vector3::Zero(), 0.0f, Vector4::Zero()); int slice_count = (int)(ri.camera->settings.volumetric_environment_quality * 495.0) + 5; @@ -367,7 +367,7 @@ void KRLight::render(RenderInfo& ri) { info.vertexAttributes = sphereModel->getVertexAttributes(); KRPipeline* pPipeline = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pPipeline->bind(*info.pCamera, ri.viewport, occlusion_test_sphere_matrix, info.point_lights, info.directional_lights, info.spot_lights, info.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); + pPipeline->bind(ri.commandBuffer, *info.pCamera, ri.viewport, occlusion_test_sphere_matrix, info.point_lights, info.directional_lights, info.spot_lights, info.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); GLDEBUG(glGenQueriesEXT(1, &m_occlusionQuery)); #if TARGET_OS_IPHONE || defined(ANDROID) @@ -422,7 +422,7 @@ void KRLight::render(RenderInfo& ri) { KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->bind(*ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); pShader->setUniform(KRPipeline::KRENGINE_UNIFORM_MATERIAL_ALPHA, 1.0f); pShader->setUniform(KRPipeline::KRENGINE_UNIFORM_FLARE_SIZE, m_flareSize); @@ -534,7 +534,7 @@ void KRLight::renderShadowBuffers(RenderInfo& ri) info.cullMode = PipelineInfo::CullMode::kCullNone; // Disabling culling, which eliminates some self-cast shadow artifacts KRPipeline *shadowShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info); - shadowShader->bind(*ri.camera, m_shadowViewports[iShadow], Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_SHADOWMAP, Vector3::Zero(), 0.0f, Vector4::Zero()); + shadowShader->bind(ri.commandBuffer, *ri.camera, m_shadowViewports[iShadow], Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_SHADOWMAP, Vector3::Zero(), 0.0f, Vector4::Zero()); getScene().render(ri.commandBuffer, *ri.surface, ri.camera, m_shadowViewports[iShadow].getVisibleBounds(), m_shadowViewports[iShadow], KRNode::RENDER_PASS_SHADOWMAP, true); } diff --git a/kraken/KRMaterial.cpp b/kraken/KRMaterial.cpp index d7bd422..c50eb07 100755 --- a/kraken/KRMaterial.cpp +++ b/kraken/KRMaterial.cpp @@ -349,10 +349,10 @@ bool KRMaterial::bind(const KRNode::RenderInfo& ri, const std::vector info.renderPass = ri.renderPass; KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->bind(*ri.camera, ri.viewport, matModel, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, rim_color, rim_power, Vector4::Zero()); + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, matModel, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, rim_color, rim_power, Vector4::Zero()); // Bind bones - if(pShader->m_uniforms[KRPipeline::KRENGINE_UNIFORM_BONE_TRANSFORMS] != -1) { + if(pShader->m_pushConstantOffset[KRPipeline::KRENGINE_UNIFORM_BONE_TRANSFORMS] != -1) { float bone_mats[256 * 16]; float *bone_mat_component = bone_mats; for(int bone_index=0; bone_index < bones.size(); bone_index++) { @@ -379,8 +379,8 @@ bool KRMaterial::bind(const KRNode::RenderInfo& ri, const std::vector *bone_mat_component++ = t[i]; } } - if(pShader->m_uniforms[KRPipeline::KRENGINE_UNIFORM_BONE_TRANSFORMS] != -1) { - glUniformMatrix4fv(pShader->m_uniforms[KRPipeline::KRENGINE_UNIFORM_BONE_TRANSFORMS], (GLsizei)bones.size(), GL_FALSE, bone_mats); + if(pShader->m_pushConstantOffset[KRPipeline::KRENGINE_UNIFORM_BONE_TRANSFORMS] != -1) { + glUniformMatrix4fv(pShader->m_pushConstantOffset[KRPipeline::KRENGINE_UNIFORM_BONE_TRANSFORMS], (GLsizei)bones.size(), GL_FALSE, bone_mats); } } diff --git a/kraken/KRParticleSystemNewtonian.cpp b/kraken/KRParticleSystemNewtonian.cpp index 7f55376..6a0f789 100755 --- a/kraken/KRParticleSystemNewtonian.cpp +++ b/kraken/KRParticleSystemNewtonian.cpp @@ -105,7 +105,7 @@ void KRParticleSystemNewtonian::render(RenderInfo& ri) { KRPipeline *pParticleShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info); - pParticleShader->bind(*ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); + pParticleShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); pParticleShader->setUniform(KRPipeline::KRENGINE_UNIFORM_FLARE_SIZE, 1.0f); KRDataBlock index_data; diff --git a/kraken/KRPipeline.cpp b/kraken/KRPipeline.cpp index 6a41db4..a7b0ae4 100644 --- a/kraken/KRPipeline.cpp +++ b/kraken/KRPipeline.cpp @@ -112,10 +112,15 @@ const char *KRPipeline::KRENGINE_UNIFORM_NAMES[] = { KRPipeline::KRPipeline(KRContext& context, KRSurface& surface, const PipelineInfo& info, const char* szKey, const std::vector& shaders, uint32_t vertexAttributes, KRMesh::model_format_t modelFormat) : KRContextObject(context) - , m_iProgram(0) // not used for Vulkan + , m_pushConstantBuffer(nullptr) + , m_pushConstantBufferSize(0) { + memset(m_pushConstantSize, 0, KRENGINE_NUM_UNIFORMS); + memset(m_pushConstantOffset, 0, KRENGINE_NUM_UNIFORMS * sizeof(int)); + m_pipelineLayout = nullptr; m_graphicsPipeline = nullptr; + m_pushConstantsLayout = nullptr; std::unique_ptr& device = surface.getDevice(); // TODO - Handle device removal @@ -182,6 +187,29 @@ KRPipeline::KRPipeline(KRContext& context, KRSurface& surface, const PipelineInf } } + for(int i=0; ipush_constant_block_count; i++) { + const SpvReflectBlockVariable& block = reflection->push_constant_blocks[i]; + if (stricmp(block.name, "constants") == 0) { + if (block.size > 0) { + m_pushConstantBuffer = (__uint8_t*)malloc(block.size); + memset(m_pushConstantBuffer, 0, block.size); + m_pushConstantBufferSize = block.size; + + // Get push constant offsets + for (int iUniform = 0; iUniform < KRENGINE_NUM_UNIFORMS; iUniform++) { + for (int iMember = 0; iMember < block.member_count; iMember++) { + const SpvReflectBlockVariable& member = block.members[iMember]; + if (stricmp(KRENGINE_UNIFORM_NAMES[iUniform], member.name) == 0) + { + m_pushConstantOffset[iUniform] = member.offset; + m_pushConstantSize[iUniform] = member.size; + } + } + } + } + } + } + } else if (shader->getSubExtension().compare("frag") == 0) { stageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; @@ -341,6 +369,27 @@ KRPipeline::KRPipeline(KRContext& context, KRSurface& surface, const PipelineInf // failed! TODO - Error handling } + if (m_pushConstantBuffer) { + VkPipelineLayoutCreateInfo pushConstantsLayoutInfo{}; + pushConstantsLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pushConstantsLayoutInfo.setLayoutCount = 0; + pushConstantsLayoutInfo.pSetLayouts = nullptr; + pushConstantsLayoutInfo.pushConstantRangeCount = 0; + pushConstantsLayoutInfo.pPushConstantRanges = nullptr; + + // TODO - We need to support push constants for other shader stages + VkPushConstantRange push_constant{}; + push_constant.offset = 0; + push_constant.size = m_pushConstantBufferSize; + push_constant.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + pushConstantsLayoutInfo.pPushConstantRanges = &push_constant; + pushConstantsLayoutInfo.pushConstantRangeCount = 1; + + if (vkCreatePipelineLayout(device->m_logicalDevice, &pushConstantsLayoutInfo, nullptr, &m_pushConstantsLayout) != VK_SUCCESS) { + // failed! TODO - Error handling + } + } + VkPipelineDepthStencilStateCreateInfo depthStencil{}; depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; switch (info.rasterMode) { @@ -404,114 +453,6 @@ KRPipeline::KRPipeline(KRContext& context, KRSurface& surface, const PipelineInf } } -KRPipeline::KRPipeline(KRContext &context, char *szKey, std::string options, std::string vertShaderSource, const std::string fragShaderSource) : KRContextObject(context) -{ - strcpy(m_szKey, szKey); - m_iProgram = 0; - - - GLuint vertexShader = 0, fragShader = 0; - - const GLchar *vertSource[2] = {options.c_str(), vertShaderSource.c_str()}; - const GLchar *fragSource[2] = {options.c_str(), fragShaderSource.c_str()}; - - // Create shader program. - GLDEBUG(m_iProgram = glCreateProgram()); - - // Create and compile vertex shader. - GLDEBUG(vertexShader = glCreateShader(GL_VERTEX_SHADER)); - GLDEBUG(glShaderSource(vertexShader, 2, vertSource, NULL)); - GLDEBUG(glCompileShader(vertexShader)); - - // Report any compile issues to stderr - GLint logLength = 0; - GLDEBUG(glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &logLength)); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength + 1); - assert(log != NULL); - log[0] = '\0'; // In case glGetShaderInfoLog fails - GLDEBUG(glGetShaderInfoLog(vertexShader, logLength, &logLength, log)); - log[logLength] = '\0'; - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "KREngine - Failed to compile vertex shader: %s\nShader compile log:\n%s", szKey, log); - free(log); - } - - - // Create and compile vertex shader. - GLDEBUG(fragShader = glCreateShader(GL_FRAGMENT_SHADER)); - GLDEBUG(glShaderSource(fragShader, 2, fragSource, NULL)); - GLDEBUG(glCompileShader(fragShader)); - - // Report any compile issues to stderr - logLength = 0; // In case glGetShaderiv fails - GLDEBUG(glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength)); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength + 1); - assert(log != NULL); - log[0] = '\0'; // In case glGetShaderInfoLog fails - GLDEBUG(glGetShaderInfoLog(fragShader, logLength, &logLength, log)); - log[logLength] = '\0'; - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "KREngine - Failed to compile fragment shader: %s\nShader compile log:\n%s", szKey, log); - free(log); - } - - // Attach vertex shader to program. - GLDEBUG(glAttachShader(m_iProgram, vertexShader)); - - // Attach fragment shader to program. - GLDEBUG(glAttachShader(m_iProgram, fragShader)); - - // Bind attribute locations. - // This needs to be done prior to linking. - GLDEBUG(glBindAttribLocation(m_iProgram, KRMesh::KRENGINE_ATTRIB_VERTEX, "vertex_position")); - GLDEBUG(glBindAttribLocation(m_iProgram, KRMesh::KRENGINE_ATTRIB_NORMAL, "vertex_normal")); - GLDEBUG(glBindAttribLocation(m_iProgram, KRMesh::KRENGINE_ATTRIB_TANGENT, "vertex_tangent")); - GLDEBUG(glBindAttribLocation(m_iProgram, KRMesh::KRENGINE_ATTRIB_TEXUVA, "vertex_uv")); - GLDEBUG(glBindAttribLocation(m_iProgram, KRMesh::KRENGINE_ATTRIB_TEXUVB, "vertex_lightmap_uv")); - GLDEBUG(glBindAttribLocation(m_iProgram, KRMesh::KRENGINE_ATTRIB_BONEINDEXES, "bone_indexes")); - GLDEBUG(glBindAttribLocation(m_iProgram, KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS, "bone_weights")); - - // Link program. - GLDEBUG(glLinkProgram(m_iProgram)); - - GLint link_success = GL_FALSE; - GLDEBUG(glGetProgramiv(m_iProgram, GL_LINK_STATUS, &link_success)); - - if(link_success != GL_TRUE) { - // Report any linking issues to stderr - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "KREngine - Failed to link shader program: %s", szKey); - logLength = 0; // In case glGetProgramiv fails - GLDEBUG(glGetProgramiv(m_iProgram, GL_INFO_LOG_LENGTH, &logLength)); - if (logLength > 0) - { - GLchar *log = (GLchar *)malloc(logLength + 1); - assert(log != NULL); - log[0] = '\0'; // In case glGetProgramInfoLog fails - GLDEBUG(glGetProgramInfoLog(m_iProgram, logLength, &logLength, log)); - log[logLength] = '\0'; - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Program link log:\n%s", log); - free(log); - } - GLDEBUG(glDeleteProgram(m_iProgram)); - m_iProgram = 0; - } else { - - // Get uniform locations - for(int i=0; i < KRENGINE_NUM_UNIFORMS; i++ ){ - GLDEBUG(m_uniforms[i] = glGetUniformLocation(m_iProgram, KRENGINE_UNIFORM_NAMES[i])); - m_uniform_value_index[i] = -1; - } - } - - // Release vertex and fragment shaders. - if (vertexShader) { - GLDEBUG(glDeleteShader(vertexShader)); - } - if (fragShader) { - GLDEBUG(glDeleteShader(fragShader)); - } -} - KRPipeline::~KRPipeline() { if (m_graphicsPipeline) { // TODO: vkDestroyPipeline(device, m_graphicsPipeline, nullptr); @@ -519,144 +460,68 @@ KRPipeline::~KRPipeline() { if (m_pipelineLayout) { // TODO: vkDestroyPipelineLayout(device, m_pipelineLayout, nullptr); } + if (m_pushConstantsLayout) { + // TODO: vkDestroyPipelineLayout(device, m_pushConstantsLayout, nullptr); + } - if(m_iProgram) { - GLDEBUG(glDeleteProgram(m_iProgram)); - if(getContext().getPipelineManager()->m_active_pipeline == this) { - getContext().getPipelineManager()->m_active_pipeline = NULL; - } - } + if(getContext().getPipelineManager()->m_active_pipeline == this) { + getContext().getPipelineManager()->m_active_pipeline = NULL; + } + if (m_pushConstantBuffer) { + delete m_pushConstantBuffer; + m_pushConstantBuffer = nullptr; + } } void KRPipeline::setUniform(int location, float value) { - if(m_uniforms[location] != -1) { - int value_index = m_uniform_value_index[location]; - bool needs_update = true; - if(value_index == -1) { - m_uniform_value_index[location] = (int)m_uniform_value_float.size(); - m_uniform_value_float.push_back(value); - } else if(m_uniform_value_float[value_index] == value) { - needs_update = false; - } else { - m_uniform_value_float[value_index] = value; - } - if(needs_update) { - GLDEBUG(glUniform1f(m_uniforms[location], value)); - } - } + if (m_pushConstantSize[location] == sizeof(value)) { + float* constant = (float*)(m_pushConstantBuffer + m_pushConstantOffset[location]); + *constant = value; + } } + void KRPipeline::setUniform(int location, int value) { - if(m_uniforms[location] != -1) { - int value_index = m_uniform_value_index[location]; - bool needs_update = true; - if(value_index == -1) { - m_uniform_value_index[location] = (int)m_uniform_value_int.size(); - m_uniform_value_int.push_back(value); - } else if(m_uniform_value_int[value_index] == value) { - needs_update = false; - } else { - m_uniform_value_int[value_index] = value; - } - if(needs_update) { - GLDEBUG(glUniform1i(m_uniforms[location], value)); - } - } + if (m_pushConstantSize[location] == sizeof(value)) { + int* constant = (int*)(m_pushConstantBuffer + m_pushConstantOffset[location]); + *constant = value; + } } void KRPipeline::setUniform(int location, const Vector2 &value) { - if(m_uniforms[location] != -1) { - int value_index = m_uniform_value_index[location]; - bool needs_update = true; - if(value_index == -1) { - m_uniform_value_index[location] = (int)m_uniform_value_vector2.size(); - m_uniform_value_vector2.push_back(value); - } else if(m_uniform_value_vector2[value_index] == value) { - needs_update = false; - } else { - m_uniform_value_vector2[value_index] = value; - } - if(needs_update) { - GLDEBUG(glUniform2f(m_uniforms[location], value.x, value.y)); - } - } + if (m_pushConstantSize[location] == sizeof(value)) { + Vector2* constant = (Vector2*)(m_pushConstantBuffer + m_pushConstantOffset[location]); + *constant = value; + } } void KRPipeline::setUniform(int location, const Vector3 &value) { - if(m_uniforms[location] != -1) { - int value_index = m_uniform_value_index[location]; - bool needs_update = true; - if(value_index == -1) { - m_uniform_value_index[location] = (int)m_uniform_value_vector3.size(); - m_uniform_value_vector3.push_back(value); - } else if(m_uniform_value_vector3[value_index] == value) { - needs_update = false; - } else { - m_uniform_value_vector3[value_index] = value; - } - if(needs_update) { - GLDEBUG(glUniform3f(m_uniforms[location], value.x, value.y, value.z)); - } - } + if (m_pushConstantSize[location] == sizeof(value)) { + Vector3* constant = (Vector3*)(m_pushConstantBuffer + m_pushConstantOffset[location]); + *constant = value; + } } + void KRPipeline::setUniform(int location, const Vector4 &value) { - if(m_uniforms[location] != -1) { - int value_index = m_uniform_value_index[location]; - bool needs_update = true; - if(value_index == -1) { - m_uniform_value_index[location] = (int)m_uniform_value_vector4.size(); - m_uniform_value_vector4.push_back(value); - } else if(m_uniform_value_vector4[value_index] == value) { - needs_update = false; - } else { - m_uniform_value_vector4[value_index] = value; - } - if(needs_update) { - GLDEBUG(glUniform4f(m_uniforms[location], value.x, value.y, value.z, value.w)); - } - } + if (m_pushConstantSize[location] == sizeof(value)) { + Vector4* constant = (Vector4*)(m_pushConstantBuffer + m_pushConstantOffset[location]); + *constant = value; + } } void KRPipeline::setUniform(int location, const Matrix4 &value) { - if(m_uniforms[location] != -1) { - int value_index = m_uniform_value_index[location]; - bool needs_update = true; - if(value_index == -1) { - m_uniform_value_index[location] = (int)m_uniform_value_mat4.size(); - m_uniform_value_mat4.push_back(value); - } else if(m_uniform_value_mat4[value_index] == value) { - needs_update = false; - } else { - m_uniform_value_mat4[value_index] = value; - } - if(needs_update) { - GLDEBUG(glUniformMatrix4fv(m_uniforms[location], 1, GL_FALSE, value.c)); - } - } + if (m_pushConstantSize[location] == sizeof(value)) { + Matrix4* constant = (Matrix4*)(m_pushConstantBuffer + m_pushConstantOffset[location]); + *constant = value; + } } -void KRPipeline::bind(VkCommandBuffer& commandBuffer) +bool KRPipeline::bind(VkCommandBuffer& commandBuffer, KRCamera &camera, const KRViewport &viewport, const Matrix4 &matModel, const std::vector *point_lights, const std::vector *directional_lights, const std::vector *spot_lights, const KRNode::RenderPass &renderPass, const Vector3 &rim_color, float rim_power, const Vector4 &fade_color) { - vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline); -} - -bool KRPipeline::bind(KRCamera &camera, const KRViewport &viewport, const Matrix4 &matModel, const std::vector *point_lights, const std::vector *directional_lights, const std::vector *spot_lights, const KRNode::RenderPass &renderPass, const Vector3 &rim_color, float rim_power, const Vector4 &fade_color) { - if(m_iProgram == 0) { - return false; - } - - bool shander_changed = false; - if(getContext().getPipelineManager()->m_active_pipeline != this) { - getContext().getPipelineManager()->m_active_pipeline = this; - GLDEBUG(glUseProgram(m_iProgram)); - shander_changed = true; - } - - setUniform(KRENGINE_UNIFORM_ABSOLUTE_TIME, getContext().getAbsoluteTime()); int light_directional_count = 0; @@ -671,7 +536,7 @@ bool KRPipeline::bind(KRCamera &camera, const KRViewport &viewport, const Matrix KRDirectionalLight* directional_light = (*light_itr); if (light_directional_count == 0) { int cShadowBuffers = directional_light->getShadowBufferCount(); - if (m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE1] != -1 && cShadowBuffers > 0) { + if (m_pushConstantSize[KRENGINE_UNIFORM_SHADOWTEXTURE1] && cShadowBuffers > 0) { if (m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 3, directional_light->getShadowTextures()[0])) { GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); @@ -681,7 +546,7 @@ bool KRPipeline::bind(KRCamera &camera, const KRViewport &viewport, const Matrix m_pContext->getTextureManager()->_setWrapModeT(3, GL_CLAMP_TO_EDGE); } - if (m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE2] != -1 && cShadowBuffers > 1 && camera.settings.m_cShadowBuffers > 1) { + if (m_pushConstantSize[KRENGINE_UNIFORM_SHADOWTEXTURE2] && cShadowBuffers > 1 && camera.settings.m_cShadowBuffers > 1) { if (m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 4, directional_light->getShadowTextures()[1])) { GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); @@ -690,7 +555,7 @@ bool KRPipeline::bind(KRCamera &camera, const KRViewport &viewport, const Matrix m_pContext->getTextureManager()->_setWrapModeT(4, GL_CLAMP_TO_EDGE); } - if (m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE3] != -1 && cShadowBuffers > 2 && camera.settings.m_cShadowBuffers > 2) { + if (m_pushConstantSize[KRENGINE_UNIFORM_SHADOWTEXTURE3] && cShadowBuffers > 2 && camera.settings.m_cShadowBuffers > 2) { if (m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 5, directional_light->getShadowTextures()[2])) { GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); @@ -706,7 +571,7 @@ bool KRPipeline::bind(KRCamera &camera, const KRViewport &viewport, const Matrix setUniform(KRENGINE_UNIFORM_SHADOWMVP1 + iShadow, matModel * directional_light->getShadowViewports()[iShadow].getViewProjectionMatrix() * matBias); } - if (m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE] != -1) { + if (m_pushConstantSize[KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE]) { Matrix4 inverseModelMatrix = matModel; inverseModelMatrix.invert(); @@ -724,41 +589,39 @@ bool KRPipeline::bind(KRCamera &camera, const KRViewport &viewport, const Matrix //light_point_count = point_lights.size(); //light_spot_count = spot_lights.size(); } - - - if(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE] != -1) { + if(m_pushConstantSize[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE]) { Matrix4 inverseModelMatrix = matModel; inverseModelMatrix.invert(); - if(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE] != -1) { + if(m_pushConstantSize[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE]) { // Transform location of camera to object space for calculation of specular halfVec Vector3 cameraPosObject = Matrix4::Dot(inverseModelMatrix, viewport.getCameraPosition()); setUniform(KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE, cameraPosObject); } } - if(m_uniforms[KRENGINE_UNIFORM_MVP] != -1 || m_uniforms[KRPipeline::KRENGINE_UNIFORM_INVMVP] != -1) { + if(m_pushConstantSize[KRENGINE_UNIFORM_MVP] || m_pushConstantSize[KRPipeline::KRENGINE_UNIFORM_INVMVP]) { // Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram Matrix4 mvpMatrix = matModel * viewport.getViewProjectionMatrix(); setUniform(KRENGINE_UNIFORM_MVP, mvpMatrix); - if(m_uniforms[KRPipeline::KRENGINE_UNIFORM_INVMVP] != -1) { + if(m_pushConstantSize[KRPipeline::KRENGINE_UNIFORM_INVMVP]) { setUniform(KRPipeline::KRENGINE_UNIFORM_INVMVP, Matrix4::Invert(mvpMatrix)); } } - if(m_uniforms[KRPipeline::KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN] != -1 || m_uniforms[KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE] != -1 || m_uniforms[KRPipeline::KRENGINE_UNIFORM_MODEL_VIEW] != -1) { + if(m_pushConstantSize[KRPipeline::KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN] || m_pushConstantSize[KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE] || m_pushConstantSize[KRPipeline::KRENGINE_UNIFORM_MODEL_VIEW]) { Matrix4 matModelView = matModel * viewport.getViewMatrix(); setUniform(KRENGINE_UNIFORM_MODEL_VIEW, matModelView); - if(m_uniforms[KRPipeline::KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN] != -1) { + if(m_pushConstantSize[KRPipeline::KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN]) { Vector3 view_space_model_origin = Matrix4::Dot(matModelView, Vector3::Zero()); // Origin point of model space is the light source position. No perspective, so no w divide required setUniform(KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN, view_space_model_origin); } - if(m_uniforms[KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE] != -1) { + if(m_pushConstantSize[KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE]) { Matrix4 matModelViewInverseTranspose = matModelView; matModelViewInverseTranspose.transpose(); matModelViewInverseTranspose.invert(); @@ -766,18 +629,18 @@ bool KRPipeline::bind(KRCamera &camera, const KRViewport &viewport, const Matrix } } - if(m_uniforms[KRENGINE_UNIFORM_MODEL_INVERSE_TRANSPOSE] != -1) { + if(m_pushConstantSize[KRENGINE_UNIFORM_MODEL_INVERSE_TRANSPOSE]) { Matrix4 matModelInverseTranspose = matModel; matModelInverseTranspose.transpose(); matModelInverseTranspose.invert(); setUniform(KRENGINE_UNIFORM_MODEL_INVERSE_TRANSPOSE, matModelInverseTranspose); } - if(m_uniforms[KRPipeline::KRENGINE_UNIFORM_INVP] != -1) { + if(m_pushConstantSize[KRPipeline::KRENGINE_UNIFORM_INVP]) { setUniform(KRENGINE_UNIFORM_INVP, viewport.getInverseProjectionMatrix()); } - if(m_uniforms[KRPipeline::KRENGINE_UNIFORM_INVMVP_NO_TRANSLATE] != -1) { + if(m_pushConstantSize[KRPipeline::KRENGINE_UNIFORM_INVMVP_NO_TRANSLATE]) { Matrix4 matInvMVPNoTranslate = matModel * viewport.getViewMatrix();; // Remove the translation matInvMVPNoTranslate.getPointer()[3] = 0; @@ -793,11 +656,11 @@ bool KRPipeline::bind(KRCamera &camera, const KRViewport &viewport, const Matrix } setUniform(KRENGINE_UNIFORM_MODEL_MATRIX, matModel); - if(m_uniforms[KRENGINE_UNIFORM_PROJECTION_MATRIX] != -1) { + if(m_pushConstantSize[KRENGINE_UNIFORM_PROJECTION_MATRIX]) { setUniform(KRENGINE_UNIFORM_PROJECTION_MATRIX, viewport.getProjectionMatrix()); } - if(m_uniforms[KRENGINE_UNIFORM_VIEWPORT] != -1) { + if(m_pushConstantSize[KRENGINE_UNIFORM_VIEWPORT]) { setUniform(KRENGINE_UNIFORM_VIEWPORT, Vector4::Create( (float)0.0, (float)0.0, @@ -807,7 +670,7 @@ bool KRPipeline::bind(KRCamera &camera, const KRViewport &viewport, const Matrix ); } - if(m_uniforms[KRENGINE_UNIFORM_VIEWPORT_DOWNSAMPLE] != -1) { + if(m_pushConstantSize[KRENGINE_UNIFORM_VIEWPORT_DOWNSAMPLE]) { setUniform(KRENGINE_UNIFORM_VIEWPORT_DOWNSAMPLE, camera.getDownsample()); } @@ -824,13 +687,13 @@ bool KRPipeline::bind(KRCamera &camera, const KRViewport &viewport, const Matrix setUniform(KRENGINE_UNIFORM_FOG_DENSITY, camera.settings.fog_density); setUniform(KRENGINE_UNIFORM_FOG_COLOR, camera.settings.fog_color); - if(m_uniforms[KRENGINE_UNIFORM_FOG_SCALE] != -1) { + if(m_pushConstantSize[KRENGINE_UNIFORM_FOG_SCALE]) { setUniform(KRENGINE_UNIFORM_FOG_SCALE, 1.0f / (camera.settings.fog_far - camera.settings.fog_near)); } - if(m_uniforms[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_EXPONENTIAL] != -1) { + if(m_pushConstantSize[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_EXPONENTIAL]) { setUniform(KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_EXPONENTIAL, -camera.settings.fog_density * 1.442695f); // -fog_density / log(2) } - if(m_uniforms[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_SQUARED] != -1) { + if(m_pushConstantSize[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_SQUARED]) { setUniform(KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_SQUARED, (float)(-camera.settings.fog_density * camera.settings.fog_density * 1.442695)); // -fog_density * fog_density / log(2) } @@ -855,33 +718,12 @@ bool KRPipeline::bind(KRCamera &camera, const KRViewport &viewport, const Matrix setUniform(KRENGINE_UNIFORM_DEPTH_FRAME, 0); setUniform(KRENGINE_UNIFORM_RENDER_FRAME, 1); setUniform(KRENGINE_UNIFORM_VOLUMETRIC_ENVIRONMENT_FRAME, 2); - -#if defined(DEBUG) - if(shander_changed) { // FINDME!! KIP!! HACK!! - GLint logLength; - - GLint validate_status = GL_FALSE; - GLDEBUG(glValidateProgram(m_iProgram)); - GLDEBUG(glGetProgramiv(m_iProgram, GL_VALIDATE_STATUS, &validate_status)); - if(validate_status != GL_TRUE) { - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "KREngine - Failed to validate shader program: %s", m_szKey); - logLength = 0; // In case glGetProgramiv fails - GLDEBUG(glGetProgramiv(m_iProgram, GL_INFO_LOG_LENGTH, &logLength)); - if (logLength > 0) - { - GLchar *log = (GLchar *)malloc(logLength + 1); - assert(log != NULL); - log[0] = '\0'; // In case glGetProgramInfoLog fails - GLDEBUG(glGetProgramInfoLog(m_iProgram, logLength, &logLength, log)); - log[logLength] = '\0'; - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Program validate log:\n%s", log); - free(log); - - } - return false; - } + + if(m_pushConstantBuffer) { + vkCmdPushConstants(commandBuffer, m_pushConstantsLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, m_pushConstantBufferSize, m_pushConstantBuffer); } -#endif + + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline); return true; } diff --git a/kraken/KRPipeline.h b/kraken/KRPipeline.h index d3e3dbf..3a17700 100644 --- a/kraken/KRPipeline.h +++ b/kraken/KRPipeline.h @@ -205,12 +205,10 @@ class KRPipeline : public KRContextObject { public: KRPipeline(KRContext& context, KRSurface& surface, const PipelineInfo& info, const char* szKey, const std::vector& shaders, uint32_t vertexAttributes, KRMesh::model_format_t modelFormat); - KRPipeline(KRContext &context, char *szKey, std::string options, std::string vertShaderSource, const std::string fragShaderSource); virtual ~KRPipeline(); const char *getKey() const; - bool bind(KRCamera &camera, const KRViewport &viewport, const Matrix4 &matModel, const std::vector *point_lights, const std::vector *directional_lights, const std::vector*spot_lights, const KRNode::RenderPass &renderPass, const Vector3 &rim_color, float rim_power, const Vector4 &fade_color); - void bind(VkCommandBuffer& commandBuffer); + bool bind(VkCommandBuffer& commandBuffer, KRCamera &camera, const KRViewport &viewport, const Matrix4 &matModel, const std::vector *point_lights, const std::vector *directional_lights, const std::vector*spot_lights, const KRNode::RenderPass &renderPass, const Vector3 &rim_color, float rim_power, const Vector4 &fade_color); enum { KRENGINE_UNIFORM_MATERIAL_AMBIENT = 0, @@ -285,17 +283,10 @@ public: }; static const char *KRENGINE_UNIFORM_NAMES[]; - GLint m_uniforms[KRENGINE_NUM_UNIFORMS]; - - int m_uniform_value_index[KRENGINE_NUM_UNIFORMS]; - - std::vector m_uniform_value_float; - std::vector m_uniform_value_int; - std::vector m_uniform_value_vector2; - std::vector m_uniform_value_vector3; - std::vector m_uniform_value_vector4; - std::vector m_uniform_value_mat4; - + int m_pushConstantOffset[KRENGINE_NUM_UNIFORMS]; + __uint8_t m_pushConstantSize[KRENGINE_NUM_UNIFORMS]; + uint8_t* m_pushConstantBuffer; + int m_pushConstantBufferSize; char m_szKey[256]; @@ -309,9 +300,9 @@ public: VkPipeline& getPipeline(); private: - GLuint m_iProgram; VkPipelineLayout m_pipelineLayout; VkPipeline m_graphicsPipeline; + VkPipelineLayout m_pushConstantsLayout; }; diff --git a/kraken/KRPointLight.cpp b/kraken/KRPointLight.cpp index 1ce4622..11b1602 100755 --- a/kraken/KRPointLight.cpp +++ b/kraken/KRPointLight.cpp @@ -110,7 +110,7 @@ void KRPointLight::render(RenderInfo& ri) } KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->bind(*ri.camera, ri.viewport, sphereModelMatrix, &this_light, nullptr, nullptr, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, sphereModelMatrix, &this_light, nullptr, nullptr, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); pShader->setUniform(KRPipeline::KRENGINE_UNIFORM_LIGHT_COLOR, m_color); pShader->setUniform(KRPipeline::KRENGINE_UNIFORM_LIGHT_INTENSITY, m_intensity * 0.01f); diff --git a/kraken/KRReverbZone.cpp b/kraken/KRReverbZone.cpp index 295a60a..80db209 100755 --- a/kraken/KRReverbZone.cpp +++ b/kraken/KRReverbZone.cpp @@ -143,7 +143,7 @@ void KRReverbZone::render(RenderInfo& ri) KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->bind(*ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); sphereModel->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f); } // sphereModel diff --git a/kraken/KRScene.cpp b/kraken/KRScene.cpp index 9305caa..ea35a35 100755 --- a/kraken/KRScene.cpp +++ b/kraken/KRScene.cpp @@ -298,7 +298,7 @@ void KRScene::render(KRNode::RenderInfo& ri, KROctreeNode* pOctreeNode, unordere info.modelFormat = KRMesh::model_format_t::KRENGINE_MODEL_FORMAT_STRIP; KRPipeline* pPipeline = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pPipeline->bind(*info.pCamera, ri.viewport, matModel, info.point_lights, info.directional_lights, info.spot_lights, info.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); + pPipeline->bind(ri.commandBuffer, *info.pCamera, ri.viewport, matModel, info.point_lights, info.directional_lights, info.spot_lights, info.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); vkCmdDraw(ri.commandBuffer, 14, 1, 0, 0); m_pContext->getMeshManager()->log_draw_call(ri.renderPass, "octree", "occlusion_test", 14); diff --git a/kraken/KRSprite.cpp b/kraken/KRSprite.cpp index 32492c9..43d9b66 100755 --- a/kraken/KRSprite.cpp +++ b/kraken/KRSprite.cpp @@ -159,7 +159,7 @@ void KRSprite::render(RenderInfo& ri) { KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->bind(*ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass, Vector3::Zero(), 0.0f, Vector4::Zero()); pShader->setUniform(KRPipeline::KRENGINE_UNIFORM_MATERIAL_ALPHA, m_spriteAlpha); m_pContext->getTextureManager()->selectTexture(0, m_pSpriteTexture, 0.0f, KRTexture::TEXTURE_USAGE_SPRITE); diff --git a/standard_assets/shaders/vulkan_test.vert b/standard_assets/shaders/vulkan_test.vert index b164378..c26d016 100644 --- a/standard_assets/shaders/vulkan_test.vert +++ b/standard_assets/shaders/vulkan_test.vert @@ -9,6 +9,12 @@ layout(location = 1) in vec3 vertex_normal; layout(location = 2) in vec3 vertex_tangent; layout(constant_id = 0) const int QUALITY_LEVEL = 64; // Specialization constant test +layout( push_constant ) uniform constants +{ + vec3 fade_color; + mat4 model_matrix; +} PushConstants; + void main() { gl_Position = vec4(vertex_position * 0.5, 1.0); fragColor = vertex_normal * 0.25 + vec3(0.5, 0.5, 0.5);