void DXDisplay::setRasterizerState(const std::string id) { if(id != currentRasterizerState_) { ID3D11RasterizerState* rasterizerState = nullptr; if(id != "") rasterizerState = getRasterizerState(id)->rasterizerState; context_->RSSetState(rasterizerState); currentRasterizerState_ = id; } }
void VulkanGraphicsPipelineState::initialize() { Lock(mMutex); GraphicsPipelineState::initialize(); std::pair<VkShaderStageFlagBits, GpuProgram*> stages[] = { { VK_SHADER_STAGE_VERTEX_BIT, mData.vertexProgram.get() }, { VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, mData.hullProgram.get() }, { VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, mData.domainProgram.get() }, { VK_SHADER_STAGE_GEOMETRY_BIT, mData.geometryProgram.get() }, { VK_SHADER_STAGE_FRAGMENT_BIT, mData.fragmentProgram.get() } }; UINT32 stageOutputIdx = 0; UINT32 numStages = sizeof(stages) / sizeof(stages[0]); for(UINT32 i = 0; i < numStages; i++) { VulkanGpuProgram* program = static_cast<VulkanGpuProgram*>(stages[i].second); if (program == nullptr) continue; VkPipelineShaderStageCreateInfo& stageCI = mShaderStageInfos[stageOutputIdx]; stageCI.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; stageCI.pNext = nullptr; stageCI.flags = 0; stageCI.stage = stages[i].first; stageCI.module = VK_NULL_HANDLE; stageCI.pName = program->getProperties().getEntryPoint().c_str(); stageCI.pSpecializationInfo = nullptr; stageOutputIdx++; } UINT32 numUsedStages = stageOutputIdx; bool tesselationEnabled = mData.hullProgram != nullptr && mData.domainProgram != nullptr; mInputAssemblyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; mInputAssemblyInfo.pNext = nullptr; mInputAssemblyInfo.flags = 0; mInputAssemblyInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; // Assigned at runtime mInputAssemblyInfo.primitiveRestartEnable = false; mTesselationInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; mTesselationInfo.pNext = nullptr; mTesselationInfo.flags = 0; mTesselationInfo.patchControlPoints = 3; // Assigned at runtime mViewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; mViewportInfo.pNext = nullptr; mViewportInfo.flags = 0; mViewportInfo.viewportCount = 1; // Spec says this need to be at least 1... mViewportInfo.scissorCount = 1; mViewportInfo.pViewports = nullptr; // Dynamic mViewportInfo.pScissors = nullptr; // Dynamic RasterizerState* rasterizerState = getRasterizerState().get(); if (rasterizerState == nullptr) rasterizerState = RasterizerState::getDefault().get(); BlendState* blendState = getBlendState().get(); if (blendState == nullptr) blendState = BlendState::getDefault().get(); DepthStencilState* depthStencilState = getDepthStencilState().get(); if (depthStencilState == nullptr) depthStencilState = DepthStencilState::getDefault().get(); const RasterizerProperties& rstProps = rasterizerState->getProperties(); const BlendProperties& blendProps = blendState->getProperties(); const DepthStencilProperties dsProps = depthStencilState->getProperties(); mRasterizationInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; mRasterizationInfo.pNext = nullptr; mRasterizationInfo.flags = 0; mRasterizationInfo.depthClampEnable = !rstProps.getDepthClipEnable(); mRasterizationInfo.rasterizerDiscardEnable = VK_FALSE; mRasterizationInfo.polygonMode = VulkanUtility::getPolygonMode(rstProps.getPolygonMode()); mRasterizationInfo.cullMode = VulkanUtility::getCullMode(rstProps.getCullMode()); mRasterizationInfo.frontFace = VK_FRONT_FACE_CLOCKWISE; mRasterizationInfo.depthBiasEnable = rstProps.getDepthBias() != 0.0f; mRasterizationInfo.depthBiasConstantFactor = rstProps.getDepthBias(); mRasterizationInfo.depthBiasSlopeFactor = rstProps.getSlopeScaledDepthBias(); mRasterizationInfo.depthBiasClamp = mRasterizationInfo.depthClampEnable ? rstProps.getDepthBiasClamp() : 0.0f; mRasterizationInfo.lineWidth = 1.0f; mMultiSampleInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; mMultiSampleInfo.pNext = nullptr; mMultiSampleInfo.flags = 0; mMultiSampleInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; // Assigned at runtime mMultiSampleInfo.sampleShadingEnable = VK_FALSE; // When enabled, perform shading per sample instead of per pixel (more expensive, essentially FSAA) mMultiSampleInfo.minSampleShading = 1.0f; // Minimum percent of samples to run full shading for when sampleShadingEnable is enabled (1.0f to run for all) mMultiSampleInfo.pSampleMask = nullptr; // Normally one bit for each sample: e.g. 0x0000000F to enable all samples in a 4-sample setup mMultiSampleInfo.alphaToCoverageEnable = blendProps.getAlphaToCoverageEnabled(); mMultiSampleInfo.alphaToOneEnable = VK_FALSE; VkStencilOpState stencilFrontInfo; stencilFrontInfo.compareOp = VulkanUtility::getCompareOp(dsProps.getStencilFrontCompFunc()); stencilFrontInfo.depthFailOp = VulkanUtility::getStencilOp(dsProps.getStencilFrontZFailOp()); stencilFrontInfo.passOp = VulkanUtility::getStencilOp(dsProps.getStencilFrontPassOp()); stencilFrontInfo.failOp = VulkanUtility::getStencilOp(dsProps.getStencilFrontFailOp()); stencilFrontInfo.reference = 0; // Dynamic stencilFrontInfo.compareMask = (UINT32)dsProps.getStencilReadMask(); stencilFrontInfo.writeMask = (UINT32)dsProps.getStencilWriteMask(); VkStencilOpState stencilBackInfo; stencilBackInfo.compareOp = VulkanUtility::getCompareOp(dsProps.getStencilBackCompFunc()); stencilBackInfo.depthFailOp = VulkanUtility::getStencilOp(dsProps.getStencilBackZFailOp()); stencilBackInfo.passOp = VulkanUtility::getStencilOp(dsProps.getStencilBackPassOp()); stencilBackInfo.failOp = VulkanUtility::getStencilOp(dsProps.getStencilBackFailOp()); stencilBackInfo.reference = 0; // Dynamic stencilBackInfo.compareMask = (UINT32)dsProps.getStencilReadMask(); stencilBackInfo.writeMask = (UINT32)dsProps.getStencilWriteMask(); mDepthStencilInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; mDepthStencilInfo.pNext = nullptr; mDepthStencilInfo.flags = 0; mDepthStencilInfo.depthBoundsTestEnable = false; mDepthStencilInfo.minDepthBounds = 0.0f; mDepthStencilInfo.maxDepthBounds = 1.0f; mDepthStencilInfo.depthTestEnable = dsProps.getDepthReadEnable(); mDepthStencilInfo.depthWriteEnable = dsProps.getDepthWriteEnable(); mDepthStencilInfo.depthCompareOp = VulkanUtility::getCompareOp(dsProps.getDepthComparisonFunc()); mDepthStencilInfo.front = stencilFrontInfo; mDepthStencilInfo.back = stencilBackInfo; mDepthStencilInfo.stencilTestEnable = dsProps.getStencilEnable(); for(UINT32 i = 0; i < BS_MAX_MULTIPLE_RENDER_TARGETS; i++) { UINT32 rtIdx = 0; if (blendProps.getIndependantBlendEnable()) rtIdx = i; VkPipelineColorBlendAttachmentState& blendState = mAttachmentBlendStates[i]; blendState.blendEnable = blendProps.getBlendEnabled(rtIdx); blendState.colorBlendOp = VulkanUtility::getBlendOp(blendProps.getBlendOperation(rtIdx)); blendState.srcColorBlendFactor = VulkanUtility::getBlendFactor(blendProps.getSrcBlend(rtIdx)); blendState.dstColorBlendFactor = VulkanUtility::getBlendFactor(blendProps.getDstBlend(rtIdx)); blendState.alphaBlendOp = VulkanUtility::getBlendOp(blendProps.getAlphaBlendOperation(rtIdx)); blendState.srcAlphaBlendFactor = VulkanUtility::getBlendFactor(blendProps.getAlphaSrcBlend(rtIdx)); blendState.dstAlphaBlendFactor = VulkanUtility::getBlendFactor(blendProps.getAlphaDstBlend(rtIdx)); blendState.colorWriteMask = blendProps.getRenderTargetWriteMask(rtIdx) & 0xF; } mColorBlendStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; mColorBlendStateInfo.pNext = nullptr; mColorBlendStateInfo.flags = 0; mColorBlendStateInfo.logicOpEnable = VK_FALSE; mColorBlendStateInfo.logicOp = VK_LOGIC_OP_NO_OP; mColorBlendStateInfo.attachmentCount = 0; // Assigned at runtime mColorBlendStateInfo.pAttachments = mAttachmentBlendStates; mColorBlendStateInfo.blendConstants[0] = 0.0f; mColorBlendStateInfo.blendConstants[1] = 0.0f; mColorBlendStateInfo.blendConstants[2] = 0.0f; mColorBlendStateInfo.blendConstants[3] = 0.0f; mDynamicStates[0] = VK_DYNAMIC_STATE_VIEWPORT; mDynamicStates[1] = VK_DYNAMIC_STATE_SCISSOR; mDynamicStates[2] = VK_DYNAMIC_STATE_STENCIL_REFERENCE; UINT32 numDynamicStates = sizeof(mDynamicStates) / sizeof(mDynamicStates[0]); assert(numDynamicStates == 3); mDynamicStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; mDynamicStateInfo.pNext = nullptr; mDynamicStateInfo.flags = 0; mDynamicStateInfo.dynamicStateCount = numDynamicStates; mDynamicStateInfo.pDynamicStates = mDynamicStates; mPipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; mPipelineInfo.pNext = nullptr; mPipelineInfo.flags = 0; mPipelineInfo.stageCount = numUsedStages; mPipelineInfo.pStages = mShaderStageInfos; mPipelineInfo.pVertexInputState = nullptr; // Assigned at runtime mPipelineInfo.pInputAssemblyState = &mInputAssemblyInfo; mPipelineInfo.pTessellationState = tesselationEnabled ? &mTesselationInfo : nullptr; mPipelineInfo.pViewportState = &mViewportInfo; mPipelineInfo.pRasterizationState = &mRasterizationInfo; mPipelineInfo.pMultisampleState = &mMultiSampleInfo; mPipelineInfo.pDepthStencilState = nullptr; // Assigned at runtime mPipelineInfo.pColorBlendState = nullptr; // Assigned at runtime mPipelineInfo.pDynamicState = &mDynamicStateInfo; mPipelineInfo.renderPass = VK_NULL_HANDLE; // Assigned at runtime mPipelineInfo.layout = VK_NULL_HANDLE; // Assigned at runtime mPipelineInfo.subpass = 0; mPipelineInfo.basePipelineHandle = VK_NULL_HANDLE; mPipelineInfo.basePipelineIndex = -1; mScissorEnabled = rstProps.getScissorEnable(); if(mData.vertexProgram != nullptr) mVertexDecl = mData.vertexProgram->getInputDeclaration(); VulkanRenderAPI& rapi = static_cast<VulkanRenderAPI&>(RenderAPI::instance()); VulkanDevice* devices[BS_MAX_DEVICES]; VulkanUtility::getDevices(rapi, mDeviceMask, devices); for (UINT32 i = 0; i < BS_MAX_DEVICES; i++) { if (devices[i] == nullptr) continue; mPerDeviceData[i].device = devices[i]; VulkanDescriptorManager& descManager = mPerDeviceData[i].device->getDescriptorManager(); VulkanGpuPipelineParamInfo& vkParamInfo = static_cast<VulkanGpuPipelineParamInfo&>(*mParamInfo); UINT32 numLayouts = vkParamInfo.getNumSets(); VulkanDescriptorLayout** layouts = (VulkanDescriptorLayout**)bs_stack_alloc(sizeof(VulkanDescriptorLayout*) * numLayouts); for (UINT32 j = 0; j < numLayouts; j++) layouts[j] = vkParamInfo.getLayout(i, j); mPerDeviceData[i].pipelineLayout = descManager.getPipelineLayout(layouts, numLayouts); bs_stack_free(layouts); } BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_PipelineState); }
void GLGraphicsContext::updateRasterizerState(const RasterizerState& rasterizerState) { const RasterizerState& newState = rasterizerState; const RasterizerState& currentState = getRasterizerState(); if (newState.getCullMode() != currentState.getCullMode()) { switch (newState.getCullMode()) { case CullMode::NONE: glDisable(GL_CULL_FACE); break; case CullMode::CLOCKWISE: if (currentState.getCullMode() == CullMode::NONE) { glEnable(GL_CULL_FACE); } glCullFace(GL_BACK); break; case CullMode::COUNTERCLOCKWISE: if (currentState.getCullMode() == CullMode::NONE) { glEnable(GL_CULL_FACE); } glCullFace(GL_FRONT); break; } } if (newState.getFillMode() != currentState.getFillMode()) { if (newState.getFillMode() == FillMode::SOLID) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } } if (newState.getDepthBias() != currentState.getDepthBias() || newState.getSlopeScaleDepthBias() != currentState.getSlopeScaleDepthBias()) { glPolygonOffset(newState.getSlopeScaleDepthBias(), newState.getDepthBias()); } if (newState.isScissorTestEnabled() != currentState.isScissorTestEnabled()) { if (newState.isScissorTestEnabled()) { glEnable(GL_SCISSOR_TEST); } else { glDisable(GL_SCISSOR_TEST); } } if (newState.isMSAAEnabled() != currentState.isMSAAEnabled()) { if (newState.isMSAAEnabled()) { glEnable(GL_MULTISAMPLE); } else { glDisable(GL_MULTISAMPLE); } } }