From 8bb03259280c974d98bcd7633ff5f5d8368b2c57 Mon Sep 17 00:00:00 2001
From: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Date: Mon, 20 Nov 2017 14:11:09 +0100
Subject: [PATCH] [dxvk] Implemented graphics pipeline creation

---
 src/dxvk/dxvk_compute.cpp  | 11 +----------
 src/dxvk/dxvk_context.cpp  |  7 ++++++-
 src/dxvk/dxvk_context.h    |  2 +-
 src/dxvk/dxvk_graphics.cpp | 39 ++++++++++++++++++++++++++++++++++++++
 src/dxvk/dxvk_graphics.h   | 23 ++++++++++++++++++++++
 5 files changed, 70 insertions(+), 12 deletions(-)

diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp
index f503fa7f4..ba353468d 100644
--- a/src/dxvk/dxvk_compute.cpp
+++ b/src/dxvk/dxvk_compute.cpp
@@ -40,20 +40,11 @@ namespace dxvk {
       throw DxvkError("DxvkComputePipeline::DxvkComputePipeline: Failed to create pipeline layout");
     }
     
-    VkPipelineShaderStageCreateInfo sinfo;
-    sinfo.sType               = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
-    sinfo.pNext               = nullptr;
-    sinfo.flags               = 0;
-    sinfo.stage               = VK_SHADER_STAGE_COMPUTE_BIT;
-    sinfo.module              = m_shader->module();
-    sinfo.pName               = "main";
-    sinfo.pSpecializationInfo = nullptr;
-    
     VkComputePipelineCreateInfo info;
     info.sType                = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
     info.pNext                = nullptr;
     info.flags                = 0;
-    info.stage                = sinfo;
+    info.stage                = m_shader->stageInfo();
     info.layout               = m_pipelineLayout;
     info.basePipelineHandle   = VK_NULL_HANDLE;
     info.basePipelineIndex    = 0;
diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp
index e33265995..4b311ec32 100644
--- a/src/dxvk/dxvk_context.cpp
+++ b/src/dxvk/dxvk_context.cpp
@@ -131,6 +131,8 @@ namespace dxvk {
           uint32_t firstInstance) {
     TRACE(this, vertexCount, instanceCount,
       firstVertex, firstInstance);
+    
+    this->commitGraphicsState();
   }
   
   
@@ -142,6 +144,8 @@ namespace dxvk {
           uint32_t firstInstance) {
     TRACE(this, indexCount, instanceCount,
       firstIndex, vertexOffset, firstInstance);
+    
+    this->commitGraphicsState();
   }
   
   
@@ -259,6 +263,7 @@ namespace dxvk {
       
       m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,
         m_state.activeGraphicsPipeline->getPipelineHandle(gpState));
+      m_cmd->trackResource(m_state.activeGraphicsPipeline);
     }
   }
   
@@ -295,7 +300,7 @@ namespace dxvk {
   }
   
   
-  void DxvkContext::flushGraphicsState() {
+  void DxvkContext::commitGraphicsState() {
     this->renderPassBegin();
     this->bindGraphicsPipeline();
     this->bindDynamicState();
diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h
index 25ee68707..c3ff84894 100644
--- a/src/dxvk/dxvk_context.h
+++ b/src/dxvk/dxvk_context.h
@@ -184,7 +184,7 @@ namespace dxvk {
     void bindIndexBuffer();
     void bindVertexBuffers();
     
-    void flushGraphicsState();
+    void commitGraphicsState();
     
     DxvkShaderStageState* getShaderStage(
             VkShaderStageFlagBits     stage);
diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp
index ddc0b2ffd..7991bc719 100644
--- a/src/dxvk/dxvk_graphics.cpp
+++ b/src/dxvk/dxvk_graphics.cpp
@@ -47,12 +47,43 @@ namespace dxvk {
       const Rc<DxvkShader>&   fs)
   : m_vkd(vkd), m_vs(vs), m_tcs(tcs),
     m_tes(tes), m_gs(gs), m_fs(fs) {
+    TRACE(this, vs, tcs, tes, gs, fs);
     
+    std::vector<VkDescriptorSetLayoutBinding> bindings;
+    
+    VkDescriptorSetLayoutCreateInfo dlayout;
+    dlayout.sType        = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    dlayout.pNext        = nullptr;
+    dlayout.flags        = 0;
+    dlayout.bindingCount = bindings.size();
+    dlayout.pBindings    = bindings.data();
+    
+    if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(),
+          &dlayout, nullptr, &m_descriptorSetLayout) != VK_SUCCESS)
+      throw DxvkError("DxvkComputePipeline::DxvkComputePipeline: Failed to create descriptor set layout");
+    
+    VkPipelineLayoutCreateInfo playout;
+    playout.sType                  = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    playout.pNext                  = nullptr;
+    playout.flags                  = 0;
+    playout.setLayoutCount         = 1;
+    playout.pSetLayouts            = &m_descriptorSetLayout;
+    playout.pushConstantRangeCount = 0;
+    playout.pPushConstantRanges    = nullptr;
+    
+    if (m_vkd->vkCreatePipelineLayout(m_vkd->device(),
+          &playout, nullptr, &m_pipelineLayout) != VK_SUCCESS) {
+      this->destroyObjects();
+      throw DxvkError("DxvkComputePipeline::DxvkComputePipeline: Failed to create pipeline layout");
+    }
   }
   
   
   DxvkGraphicsPipeline::~DxvkGraphicsPipeline() {
+    TRACE(this);
     
+    this->destroyPipelines();
+    this->destroyObjects();
   }
   
   
@@ -140,4 +171,12 @@ namespace dxvk {
       m_vkd->vkDestroyDescriptorSetLayout(m_vkd->device(), m_descriptorSetLayout, nullptr);
   }
   
+  
+  void DxvkGraphicsPipeline::destroyPipelines() {
+    for (const auto& pair : m_pipelines) {
+      m_vkd->vkDestroyPipeline(
+        m_vkd->device(), pair.second, nullptr);
+    }
+  }
+  
 }
\ No newline at end of file
diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h
index 0d85e65c8..b77930553 100644
--- a/src/dxvk/dxvk_graphics.h
+++ b/src/dxvk/dxvk_graphics.h
@@ -56,10 +56,32 @@ namespace dxvk {
       const Rc<DxvkShader>&   fs);
     ~DxvkGraphicsPipeline();
     
+    /**
+     * \brief Descriptor set layout
+     * 
+     * The descriptor set layout for this pipeline.
+     * Use this to allocate new descriptor sets.
+     * \returns The descriptor set layout
+     */
     VkDescriptorSetLayout descriptorSetLayout() const {
       return m_descriptorSetLayout;
     }
     
+    /**
+     * \brief Pipeline layout layout
+     * 
+     * The pipeline layout for this pipeline.
+     * Use this to bind descriptor sets.
+     * \returns The descriptor set layout
+     */
+    VkPipelineLayout pipelineLayout() const {
+      return m_pipelineLayout;
+    }
+    
+    /**
+     * \brief Pipeline handle
+     * \returns Pipeline handle
+     */
     VkPipeline getPipelineHandle(
       const DxvkGraphicsPipelineStateInfo& state);
     
@@ -85,6 +107,7 @@ namespace dxvk {
       const DxvkGraphicsPipelineStateInfo& state) const;
     
     void destroyObjects();
+    void destroyPipelines();
     
   };