初めてのVulkanプログラミング step6 レンダーパス

レンダーパスとは、GPU内部で行われる処理の塊です。vulkanにおいてレンダリング処理は、内部でレンダリングパスを実行しています。レンダーパスをあらかじめ定義しておくことにより、ドライバーは、レンダリング開始前に先をみこして処理を最適化することができます。

レンダーパスの構成は、サブパス、実行順序(Dependencies)、次の処理に渡すデータのコレクション(attachment)の三つがあります。
![renderpass.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251306/71479a7e-2798-2fcb-361b-fd20bcc93035.png)

## Attachment
最初は、Atacchimentから作成します。
アタッチメントとは、サブパス間でやりされるでーたのことです。

```cpp
	VkAttachmentDescription attachmentDescription;
	attachmentDescription.flags = 0 ;
	attachmentDescription.format= VK_FORMAT_B8G8R8A8_UNORM;
	attachmentDescription.samples = VK_SAMPLE_COUNT_1_BIT;
	attachmentDescription.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
	attachmentDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
	attachmentDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
	attachmentDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
	attachmentDescription.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
	attachmentDescription.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
```

- format....カラーのフォーマットを提供しています。スワップチェーンと合わせるほうがいいです。

- sampls...サンプリングのカラーです.

- loadOp...データをロードした際にどのような操作を行うか決めています。今回は、動作しないため読み込み時に破棄する

- StoreOP...レンダリング後のデータの操作です。今回は、レンダリング中に生成されレンダーエリア内でメモリーに書き込みます。
- stencilLoadOp　/　stencilStoreOp...ステンシルに関するロード・ストアです。
- initialLayout...どのレイアウトイメージがレンダーパス開始前に保持するか指定します。今回は、未定義で行きます。
- finalLayout...レンダーパスが完了した時に移行するためのレイアウトを指定します。今回は、完了したらスワップチェーンに渡します。

## VkAttachmentReference
この構造体はアタッチメントの参照情報を持っています。全てのサブパスは、一つ以上のアタッチメントを参照します。

```cpp
	VkAttachmentReference attachmentReference;
	attachmentReference.attachment = 0;
	attachmentReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

```
- Attachment... *VkAttachmentDescription*配列のインデクスを指定します。今回は単一なので0を定義しています。
- layout...サブパス中に含めるレイアウトを定義します。

## subpass
subpassは「VkSubpassDescription」で定義される。

```cpp
	VkSubpassDescription subpassDescription;
	subpassDescription.flags = 0;
	subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
	subpassDescription.inputAttachmentCount = 0;
	subpassDescription.pInputAttachments = nullptr;
	subpassDescription.colorAttachmentCount = 1;
	subpassDescription.pColorAttachments = &attachmentReference;
	subpassDescription.pResolveAttachments = nullptr;
	subpassDescription.pDepthStencilAttachment = nullptr;
	subpassDescription.preserveAttachmentCount = 0;
	subpassDescription.pPreserveAttachments = nullptr;
```

-pipelineBindPoint...サブパスがサポートするパイプラインの種類。今回は、GRAPHICS。他には、COMPUTE、計算用途などが和えう
- attachmentCount...レンダーパス中で使用するアタッチメントの数

##RenderPass
サブパスと、アタッチメントを記述しました。よってレンダーパス自体を作成することができます。実際には、実行順序を決める(Dependencies)がありますが、今回は、作りません。一つだけしかないのに順番をきめようがないですから。

VkRenderPassCreateInfo構造体を使ってレンダーパスの情報を格納します。
ここに先ほど作成した。アタッチメント、サブパス、Dependencyを入れます。
**vkCreateRenderPass**関数を使うとレンダーパスは作られます。

```cpp
	VkRenderPassCreateInfo renderPassCreateInfo;
	renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
	renderPassCreateInfo.pNext = nullptr;
	renderPassCreateInfo.flags = 0;
	renderPassCreateInfo.attachmentCount = 1;
	renderPassCreateInfo.pAttachments = &attachmentDescription;
	renderPassCreateInfo.subpassCount = 1;
	renderPassCreateInfo.pSubpasses  = &subpassDescription;
	renderPassCreateInfo.dependencyCount = 0;
	renderPassCreateInfo.pDependencies = nullptr;

	err = vkCreateRenderPass(_device, &renderPassCreateInfo, nullptr, &_renderPass);
	if (VK_SUCCESS != err) {
		assert(0 && "Vulkan ERROR: Create Render Pass failed!!");
		std::exit(-1);
	}
```