/
Pipeline.cpp
178 lines (153 loc) · 6.2 KB
/
Pipeline.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#include "Pipeline.h"
#include "Device.h"
#include "RenderTarget.h"
#include "Texture.h"
namespace Immortal
{
namespace Vulkan
{
Pipeline::Pipeline(Device *device, std::shared_ptr<Shader::Super> &shader) :
device{ device },
Super{ shader }
{
configuration = std::make_unique<Configuration>();
CleanUpObject(configuration.get());
}
Pipeline::~Pipeline()
{
}
void Pipeline::Set(std::shared_ptr<Buffer::Super> &buffer)
{
if (buffer->GetType() == Buffer::Type::Vertex)
{
desc.vertexBuffers.emplace_back(buffer);
INITVertex();
}
if (buffer->GetType() == Buffer::Type::Index)
{
desc.indexBuffer = buffer;
}
}
void Pipeline::Set(const InputElementDescription &description)
{
Super::Set(description);
auto size = desc.layout.Size();
auto &inputAttributeDescription = configuration->inputAttributeDescriptions;
inputAttributeDescription.resize(size);
for (int i = 0; i < size; i++)
{
inputAttributeDescription[i].binding = 0;
inputAttributeDescription[i].location = i;
inputAttributeDescription[i].format = desc.layout[i].BaseType<VkFormat>();
inputAttributeDescription[i].offset = desc.layout[i].Offset();
}
configuration->vertexInputBidings.emplace_back(VkVertexInputBindingDescription{
0,
desc.layout.Stride(),
VK_VERTEX_INPUT_RATE_VERTEX
});
INITLayout();
}
void Pipeline::Create(std::shared_ptr<RenderTarget::Super> &superTarget)
{
auto target = std::dynamic_pointer_cast<RenderTarget>(superTarget);
auto state = &configuration->state;
auto attachment = &configuration->attament;
state->rasterization.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
state->rasterization.polygonMode = VK_POLYGON_MODE_FILL;
state->rasterization.cullMode = VK_CULL_MODE_FRONT_BIT;
state->rasterization.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
state->rasterization.flags = 0;
state->rasterization.depthClampEnable = VK_FALSE;
state->rasterization.lineWidth = 1.0f;
std::vector<VkPipelineColorBlendAttachmentState> colorBlends;
colorBlends.resize(target->ColorAttachmentCount());
for (auto &colorBlend : colorBlends)
{
colorBlend.colorWriteMask = 0xf;
colorBlend.blendEnable = VK_TRUE;
}
state->colorBlend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
state->colorBlend.attachmentCount = U32(colorBlends.size());
state->colorBlend.pAttachments = colorBlends.data();
state->colorBlend.blendConstants[0] = 1.0f;
state->colorBlend.blendConstants[1] = 1.0f;
state->colorBlend.blendConstants[2] = 1.0f;
state->colorBlend.blendConstants[3] = 1.0f;
state->depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
state->depthStencil.depthTestEnable = VK_TRUE;
state->depthStencil.depthWriteEnable = VK_TRUE;
state->depthStencil.depthCompareOp = VK_COMPARE_OP_GREATER;
state->depthStencil.front = state->depthStencil.back;
state->depthStencil.back.compareOp = VK_COMPARE_OP_ALWAYS;
state->viewport.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
state->viewport.viewportCount = 1;
state->viewport.scissorCount = 1;
state->viewport.flags = 0;
state->multiSample.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
state->multiSample.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
state->multiSample.flags = 0;
std::array<VkDynamicState, 2> dynamic{
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR,
//VK_DYNAMIC_STATE_LINE_WIDTH,
//VK_DYNAMIC_STATE_DEPTH_BIAS,
//VK_DYNAMIC_STATE_BLEND_CONSTANTS,
//VK_DYNAMIC_STATE_DEPTH_BOUNDS,
//VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
//VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
//VK_DYNAMIC_STATE_STENCIL_REFERENCE
};
state->dynamic.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
state->dynamic.dynamicStateCount = dynamic.size();
state->dynamic.pDynamicStates = dynamic.data();
if (!desc.shader->IsGraphics())
{
bindPoint = VK_PIPELINE_BIND_POINT_COMPUTE;
}
auto shader = std::dynamic_pointer_cast<Shader>(desc.shader);
descriptorSet = shader->Get<VkDescriptorSet>();
VkGraphicsPipelineCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.renderPass = target->GetRenderPass();
createInfo.flags = 0;
createInfo.layout = shader->Get<PipelineLayout&>();
createInfo.pInputAssemblyState = &state->inputAssembly;
createInfo.pVertexInputState = &state->vertexInput;
createInfo.pRasterizationState = &state->rasterization;
createInfo.pDepthStencilState = &state->depthStencil;
createInfo.pViewportState = &state->viewport;
createInfo.pMultisampleState = &state->multiSample;
createInfo.pDynamicState = &state->dynamic;
createInfo.pColorBlendState = &state->colorBlend;
auto &stages = shader->Stages();
createInfo.pStages = stages.data();
createInfo.stageCount = stages.size();
Check(device->CreatePipelines(cache, 1, &createInfo, nullptr, &handle));
shader->Swap(writeDescriptors);
shader->Swap(uniforms);
if (Ready())
{
device->UpdateDescriptorSets(writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
}
}
void Pipeline::Bind(std::shared_ptr<SuperTexture> &superTexture, uint32_t slot)
{
for (auto &writeDescriptor : writeDescriptors)
{
if (writeDescriptor.descriptorType <= VK_DESCRIPTOR_TYPE_STORAGE_IMAGE &&
writeDescriptor.dstBinding == slot)
{
auto texture = std::dynamic_pointer_cast<Texture>(superTexture);
writeDescriptor.pImageInfo = texture->DescriptorInfo();
break;
}
}
if (Ready())
{
device->UpdateDescriptorSets(writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
}
}
}
}