import vulkan 
, bitops 
, render_pass

proc create_color_only_render_pass*( device: VkDevice 
                                   , color_format: VkFormat 
                                   ): Render_Pass =
 
 result = A_Render_Pass()
 
 var 
  color_attachment = VkAttachmentDescription( format: color_format
                                            , samples: VK_SAMPLE_COUNT_1_BIT
                                            , loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR
                                            , storeOp: VK_ATTACHMENT_STORE_OP_STORE
                                            , stencilLoadOp: VK_ATTACHMENT_LOAD_OP_DONT_CARE
                                            , stencilStoreOp: VK_ATTACHMENT_STORE_OP_DONT_CARE
                                            , initialLayout: VK_IMAGE_LAYOUT_UNDEFINED
                                            , finalLayout: VK_IMAGE_LAYOUT_PRESENT_SRC_KHR 
                                            )
 
  color_attachment_reference = VkAttachmentReference( attachment: 0
                                                    , layout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
                                                    )
 
  subpass = VkSubpassDescription( pipelineBindPoint: VK_PIPELINE_BIND_POINT_GRAPHICS
                                , colorAttachmentCount: 1
                                , pColorAttachments: addr color_attachment_reference
                                )
 
  render_pass_info = VkRenderPassCreateInfo( sType: VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
                                           , attachmentCount: 1
                                           , pAttachments: addr color_attachment
                                           , subpassCount: 1
                                           , pSubpasses: addr subpass
                                           , dependencyCount: 1
                                           )
 
  dependency = VkSubpassDependency( srcSubpass: VK_SUBPASS_EXTERNAL #External means outside of the render pipeline, in srcPass, it means before the render pipeline
                                  , dstSubpass: 0 #must be higher than srcSubpass
                                  , srcStageMask: VkPipelineStageFlags VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
                                  , srcAccessMask: VkAccessFlags 0
                                  , dstStageMask: VkPipelineStageFlags VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
                                  , dstAccessMask: VkAccessFlags bitor( VK_ACCESS_COLOR_ATTACHMENT_READ_BIT.ord
                                                                      , VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT.ord
                                                                      )
                                  )

 render_pass_info.pDependencies = addr dependency
 
 var 
  res: VkResult = vkCreateRenderPass( device
                                    , addr render_pass_info
                                    , nil
                                    , addr result.vk_handle
                                    )
 
 assert res == VK_SUCCESS
      , "create_color_only_render_pass FAILED: " & $res

proc create_basic_shape_render_pass*( device: VkDevice 
                                    , color_format: VkFormat 
                                    , depth_format: VkFormat 
                                    ): Render_Pass =
 
 result = A_Render_Pass()
 
 var 
  attachments: array[2,VkAttachmentDescription]
  subpass_dependencies: array[2,VkSubpassDependency]
  color_attachment_reference = VkAttachmentReference( attachment: 0
                                                    , layout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
                                                    )
  depth_attachment_reference = VkAttachmentReference( attachment: 1
                                                    , layout: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
                                                    )
 
  subpass = VkSubpassDescription( pipelineBindPoint: VK_PIPELINE_BIND_POINT_GRAPHICS
                                , colorAttachmentCount: 1
                                , pColorAttachments: addr color_attachment_reference
                                , pDepthStencilAttachment: addr depth_attachment_reference           # Reference to the depth attachment in slot 1
                                , inputAttachmentCount: 0                            # Input attachments can be used to sample from contents of a previous subpass
                                , pInputAttachments: nil                         # (Input attachments not used by this example)
                                , preserveAttachmentCount: 0                         # Preserved attachments can be used to loop (and preserve) attachments through subpasses
                                , pPreserveAttachments: nil                      # (Preserve attachments not used by this example)
                                , pResolveAttachments: nil                       # Resolve attachments are resolved at the end of a sub pass and can be used for e.g. multi sampling
                                )

  attachment_description = VkAttachmentDescription( format: color_format
                                                  , samples: VK_SAMPLE_COUNT_1_BIT
                                                  , loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR
                                                  , storeOp: VK_ATTACHMENT_STORE_OP_STORE
                                                  , stencilLoadOp: VK_ATTACHMENT_LOAD_OP_DONT_CARE
                                                  , stencilStoreOp: VK_ATTACHMENT_STORE_OP_DONT_CARE
                                                  , initialLayout: VK_IMAGE_LAYOUT_UNDEFINED
                                                  , finalLayout: VK_IMAGE_LAYOUT_PRESENT_SRC_KHR 
                                                  )
 
 # depth 
 subpass_dependencies[0] = VkSubpassDependency( srcSubpass: VK_SUBPASS_EXTERNAL #External means outside of the render pipeline, in srcPass, it means before the render pipeline
                                  , dstSubpass: 0 #must be higher than srcSubpass
                                  , srcStageMask: VkPipelineStageFlags bitor( VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT.ord
                                                                            ,  VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT.ord
                                                                            )
                                  , dstStageMask: VkPipelineStageFlags bitor( VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT.ord
                                                                            ,  VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT.ord
                                                                            )
                                  , srcAccessMask: VkAccessFlags VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
                                  , dstAccessMask: VkAccessFlags bitor( VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT.ord
                                                                      , VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT.ord
                                                                      )
                                  )
 
 
 subpass_dependencies[1] = VkSubpassDependency( srcSubpass: VK_SUBPASS_EXTERNAL
                                              , dstSubpass: 0
                                              , srcStageMask: VkPipelineStageFlags VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
                                              , dstStageMask: VkPipelineStageFlags VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
                                              , srcAccessMask: VkAccessFlags 0
                                              , dstAccessMask: VkAccessFlags bitor( VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT.ord
                                                                                  , VK_ACCESS_COLOR_ATTACHMENT_READ_BIT.ord
                                                                                  )
                                              , dependencyFlags: VkDependencyFlags 0
                                              )
 
 
 # Color attachment
 attachments[0].format = colorFormat                                  # Use the color format selected by the swapchain
 attachments[0].samples = VK_SAMPLE_COUNT_1_BIT                                 # We don't use multi sampling in this example
 attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR                            # Clear this attachment at the start of the render pass
 attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE                          # Keep its contents after the render pass is finished (for displaying it)
 attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE                 # We don't use stencil, so don't care for load
 attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE               # Same for store
 attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED                       # Layout at render pass start. Initial doesn't matter, so we use undefined
 attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR                   # Layout to which the attachment is transitioned when the render pass is finished
                                                                                # As we want to present the color buffer to the swapchain, we transition to PRESENT_KHR
 # Depth attachment
 attachments[1].format = depthFormat                                           # A proper depth format is selected in the example base
 attachments[1].samples = VK_SAMPLE_COUNT_1_BIT
 attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR                           # Clear depth at start of first subpass
 attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE                     # We don't need depth after render pass has finished (DONT_CARE may result in better performance)
 attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE                # No stencil
 attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE              # No Stencil
 attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED                      # Layout at render pass start. Initial doesn't matter, so we use undefined
 attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL # Transition to depth/stencil attachment
 
 var render_pass_info = VkRenderPassCreateInfo( sType: VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
                                           , attachmentCount: 2
                                           , subpassCount: 1
                                           , pSubpasses: addr subpass
                                           , dependencyCount: 1
                                           , pAttachments: addr attachments[0]
                                           , pDependencies: addr subpass_dependencies[0]
                                           ) 
 render_pass_info.pDependencies = addr subpass_dependencies[0]
  
 var res: VkResult = vkCreateRenderPass( device
                                    , addr render_pass_info
                                    , nil
                                    , addr result.vk_handle
                                    )
 
 assert res == VK_SUCCESS
      , "create_color_only_render_pass FAILED: " & $res