public VkDescriptorSet GetDescriptorSet(ref VkDescriptorSetCacheKey cacheKey) { if (!_descriptorSets.TryGetValue(cacheKey, out VkDescriptorSet ret)) { ret = CreateNewDescriptorSet(ref cacheKey); // Very efficient cacheKey.ConstantBuffers = (VkConstantBuffer[])cacheKey.ConstantBuffers.Clone(); cacheKey.TextureBindings = (VkShaderTextureBinding[])cacheKey.TextureBindings.Clone(); cacheKey.SamplerStates = (VkSamplerState[])cacheKey.SamplerStates.Clone(); _descriptorSets.Add(cacheKey, ret); } return(ret); }
private void DrawPrimitives(int indexCount, int instanceCount, int startingIndex, int startingVertex) { RenderPassInfo renderPassState = GetCurrentRenderPass(); VkPipelineLayout layout = ShaderResourceBindingSlots.PipelineLayout; VkPipelineCacheKey pipelineCacheKey = new VkPipelineCacheKey(); pipelineCacheKey.RenderPass = renderPassState.Framebuffer.RenderPassClearBuffer; pipelineCacheKey.PipelineLayout = layout; pipelineCacheKey.BlendState = (VkBlendState)BlendState; pipelineCacheKey.Framebuffer = renderPassState.Framebuffer; pipelineCacheKey.DepthStencilState = (VkDepthStencilState)DepthStencilState; pipelineCacheKey.RasterizerState = (VkRasterizerState)RasterizerState; pipelineCacheKey.PrimitiveTopology = _primitiveTopology; pipelineCacheKey.ShaderSet = ShaderSet; pipelineCacheKey.VertexBindings = VertexBuffers; VkPipeline graphicsPipeline = _resourceCache.GetGraphicsPipeline(ref pipelineCacheKey); VkDescriptorSetCacheKey descriptorSetCacheKey = new VkDescriptorSetCacheKey(); descriptorSetCacheKey.ShaderResourceBindingSlots = ShaderResourceBindingSlots; descriptorSetCacheKey.ConstantBuffers = _constantBuffers; descriptorSetCacheKey.TextureBindings = _textureBindings; descriptorSetCacheKey.SamplerStates = _samplerStates; VkDescriptorSet descriptorSet = _resourceCache.GetDescriptorSet(ref descriptorSetCacheKey); VkCommandBuffer cb = GetCommandBuffer(); VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New(); beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit | VkCommandBufferUsageFlags.RenderPassContinue; VkCommandBufferInheritanceInfo inheritanceInfo = VkCommandBufferInheritanceInfo.New(); inheritanceInfo.renderPass = renderPassState.Framebuffer.RenderPassClearBuffer; beginInfo.pInheritanceInfo = &inheritanceInfo; vkBeginCommandBuffer(cb, ref beginInfo); vkCmdBindPipeline(cb, VkPipelineBindPoint.Graphics, graphicsPipeline); vkCmdBindDescriptorSets( cb, VkPipelineBindPoint.Graphics, layout, 0, 1, ref descriptorSet, 0, IntPtr.Zero); int vbCount = ShaderSet.InputLayout.InputDescriptions.Length; StackList <VkBuffer, Size512Bytes> vbs = new StackList <VkBuffer, Size512Bytes>(); for (int vbIndex = 0; vbIndex < vbCount; vbIndex++) { vbs.Add(((VkVertexBuffer)VertexBuffers[vbIndex]).DeviceBuffer); } StackList <VkBuffer, Size512Bytes> offsets = new StackList <VkBuffer, Size512Bytes>(); vkCmdBindVertexBuffers(cb, 0, vbs.Count, (IntPtr)vbs.Data, (IntPtr)offsets.Data); vkCmdBindIndexBuffer(cb, IndexBuffer.DeviceBuffer, 0, IndexBuffer.IndexType); VkViewport viewport = new VkViewport() { x = Viewport.X, y = Viewport.Y, width = Viewport.Width, height = Viewport.Height, minDepth = 0, maxDepth = 1 }; vkCmdSetViewport(cb, 0, 1, ref viewport); vkCmdSetScissor(cb, 0, 1, ref _scissorRect); vkCmdDrawIndexed(cb, (uint)indexCount, (uint)instanceCount, (uint)startingIndex, startingVertex, 0); vkEndCommandBuffer(cb); renderPassState.SecondaryCommandBuffers.Add(cb); }
private VkDescriptorSet CreateNewDescriptorSet(ref VkDescriptorSetCacheKey cacheKey) { { VkDescriptorSetAllocateInfo descriptorSetAI = VkDescriptorSetAllocateInfo.New(); descriptorSetAI.descriptorPool = _descriptorPool; descriptorSetAI.descriptorSetCount = 1; VkDescriptorSetLayout layout = cacheKey.ShaderResourceBindingSlots.DescriptorSetLayout; descriptorSetAI.pSetLayouts = &layout; VkResult result = vkAllocateDescriptorSets(_device, ref descriptorSetAI, out VkDescriptorSet descriptorSet); CheckResult(result); int resourceCount = cacheKey.ShaderResourceBindingSlots.Resources.Length; VkWriteDescriptorSet[] descriptorWrites = new VkWriteDescriptorSet[resourceCount]; VkDescriptorBufferInfo *bufferInfos = stackalloc VkDescriptorBufferInfo[resourceCount]; // TODO: Fix this. VkDescriptorImageInfo * imageInfos = stackalloc VkDescriptorImageInfo[resourceCount]; // TODO: Fix this. for (uint binding = 0; binding < resourceCount; binding++) { descriptorWrites[binding].sType = VkStructureType.WriteDescriptorSet; descriptorWrites[binding].descriptorCount = 1; descriptorWrites[binding].dstBinding = binding; descriptorWrites[binding].dstSet = descriptorSet; ShaderResourceDescription resource = cacheKey.ShaderResourceBindingSlots.Resources[binding]; switch (resource.Type) { case ShaderResourceType.ConstantBuffer: { descriptorWrites[binding].descriptorType = VkDescriptorType.UniformBuffer; VkConstantBuffer cb = cacheKey.ConstantBuffers[binding]; if (cb == null) { throw new VeldridException($"No constant buffer bound to required binding slot {binding}."); } VkDescriptorBufferInfo *cbInfo = &bufferInfos[binding]; cbInfo->buffer = cb.DeviceBuffer; cbInfo->offset = 0; cbInfo->range = (ulong)resource.DataSizeInBytes; descriptorWrites[binding].pBufferInfo = cbInfo; break; } case ShaderResourceType.Texture: { descriptorWrites[binding].descriptorType = VkDescriptorType.SampledImage; VkShaderTextureBinding textureBinding = cacheKey.TextureBindings[binding]; if (textureBinding == null) { throw new VeldridException($"No texture bound to required binding slot {binding}."); } VkDescriptorImageInfo *imageInfo = &imageInfos[binding]; imageInfo->imageLayout = textureBinding.ImageLayout; imageInfo->imageView = textureBinding.ImageView; descriptorWrites[binding].pImageInfo = imageInfo; } break; case ShaderResourceType.Sampler: { descriptorWrites[binding].descriptorType = VkDescriptorType.Sampler; VkSamplerState samplerState = cacheKey.SamplerStates[binding] ?? (VkSamplerState)_defaultSamplerState; VkDescriptorImageInfo *imageInfo = &imageInfos[binding]; imageInfo->sampler = samplerState.Sampler; descriptorWrites[binding].pImageInfo = imageInfo; } break; default: throw Illegal.Value <ShaderResourceType>(); } } vkUpdateDescriptorSets(_device, (uint)resourceCount, ref descriptorWrites[0], 0, null); return(descriptorSet); } }