Преглед изворни кода

WIP: Descriptor sets

undefined
Brian Ho пре 6 година
родитељ
комит
e206aaaa08
7 измењених фајлова са 148 додато и 37 уклоњено
  1. 4
    2
      .gitignore
  2. 14
    6
      Makefile
  3. 0
    0
      darken.frag
  4. 26
    0
      darken.vert
  5. 9
    0
      draw.frag
  6. 0
    0
      draw.vert
  7. 95
    29
      subpass.cc

+ 4
- 2
.gitignore Прегледај датотеку

@@ -1,4 +1,6 @@
subpass
subpass.png
subpass.vert.spv
subpass.frag.spv
darken.vert.spv
darken.frag.spv
draw.vert.spv
draw.frag.spv

+ 14
- 6
Makefile Прегледај датотеку

@@ -18,6 +18,8 @@ endif

SUBDIR = "subpass/"
NAME = subpass
FIRST_SUBPASS = draw
SECOND_SUBPASS = darken
CFLAGS = -std=c++17 --sysroot="$(SYSROOT)" -Wall
LDFLAGS = -lvulkan -lpng

@@ -30,8 +32,10 @@ build: check
deploy: check
ifneq ($(target), local)
@echo Deploying to $(SSH_DUT)...
@scp ${NAME}.vert.spv $(SSH_DUT):~/${SUBDIR}${NAME}.vert.spv
@scp ${NAME}.frag.spv $(SSH_DUT):~/${SUBDIR}${NAME}.frag.spv
@scp ${FIRST_SUBPASS}.vert.spv $(SSH_DUT):~/${SUBDIR}${FIRST_SUBPASS}.vert.spv
@scp ${FIRST_SUBPASS}.frag.spv $(SSH_DUT):~/${SUBDIR}${FIRST_SUBPASS}.frag.spv
@scp ${SECOND_SUBPASS}.vert.spv $(SSH_DUT):~/${SUBDIR}${SECOND_SUBPASS}.vert.spv
@scp ${SECOND_SUBPASS}.frag.spv $(SSH_DUT):~/${SUBDIR}${SECOND_SUBPASS}.frag.spv
@scp ${NAME} $(SSH_DUT):~/${SUBDIR}
endif

@@ -47,14 +51,18 @@ else
endif

shaders:
@glslc -c ${NAME}.vert
@glslc -c ${NAME}.frag
@glslc -c ${FIRST_SUBPASS}.vert
@glslc -c ${FIRST_SUBPASS}.frag
@glslc -c ${SECOND_SUBPASS}.vert
@glslc -c ${SECOND_SUBPASS}.frag

clean: check
@rm -f ${NAME} ${NAME}.png ${NAME}.vert.spv ${NAME}.frag.spv
@rm -f ${NAME} ${NAME}.png ${FIRST_SUBPASS}.vert.spv ${FIRST_SUBPASS}.frag.spv \
${SECOND_SUBPASS}.vert.spv ${SECOND_SUBPASS}.frag.spv
ifneq ($(target), local)
@ssh $(SSH_DUT) 'rm -f ~/${SUBDIR}${NAME} ~/${SUBDIR}${NAME}.png \
~/${SUBDIR}${NAME}.vert.spv ~/${SUBDIR}${NAME}.frag.spv'
~/${SUBDIR}${FIRST_SUBPASS}.vert.spv ~/${SUBDIR}${FIRST_SUBPASS}.frag.spv' \
~/${SUBDIR}${SECOND_SUBPASS}.vert.spv ~/${SUBDIR}${SECOND_SUBPASS}.frag.spv'
endif

check:

subpass.frag → darken.frag Прегледај датотеку


+ 26
- 0
darken.vert Прегледај датотеку

@@ -0,0 +1,26 @@
#version 450

layout(location = 0) out vec3 fragColor;

vec3 positions[6] = vec3[](
vec3(-1.0, -1.0, 0.5),
vec3(1.0, -1.0, 0.5),
vec3(-1.0, 1.0, 0.5),
vec3(1.0, -1.0, 0.5),
vec3(1.0, 1.0, 0.5),
vec3(-1.0, 1.0, 0.5)
);

vec3 colors[6] = vec3[](
vec3(1.0, 0.0, 0.0),
vec3(0.0, 1.0, 0.0),
vec3(0.0, 0.0, 1.0),
vec3(1.0, 1.0, 0.0),
vec3(0.0, 1.0, 1.0),
vec3(1.0, 0.0, 1.0)
);

void main() {
gl_Position = vec4(positions[gl_VertexIndex], 1.0);
fragColor = colors[gl_VertexIndex];
}

+ 9
- 0
draw.frag Прегледај датотеку

@@ -0,0 +1,9 @@
#version 450

layout(location = 0) in vec3 fragColor;

layout(location = 0) out vec4 outColor;

void main() {
outColor = vec4(fragColor, 1.0);
}

subpass.vert → draw.vert Прегледај датотеку


+ 95
- 29
subpass.cc Прегледај датотеку

@@ -12,8 +12,10 @@ const uint32_t kWidth = 256;
const uint32_t kHeight = 256;
const VkFormat kVulkanFormat = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
const VkFormat kVulkanDepthFormat = VK_FORMAT_D32_SFLOAT;
const std::string kVertexShaderPath = "subpass.vert.spv";
const std::string kFragmentShaderPath = "subpass.frag.spv";
const std::string kDrawVertexShaderPath = "draw.vert.spv";
const std::string kDrawFragmentShaderPath = "draw.frag.spv";
const std::string kDarkenVertexShaderPath = "darken.vert.spv";
const std::string kDarkenFragmentShaderPath = "darken.frag.spv";

#define ERROR(message) \
std::cerr << message << std::endl; \
@@ -118,6 +120,34 @@ VkDevice CreateVkDevice(VkPhysicalDevice physical_device, uint32_t device_queue_
return device;
}

VkDescriptorPool CreateAttachmentVkDescriptorPool(VkDevice device) {
VkDescriptorPoolSize pool_size = {};
pool_size.type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
pool_size.descriptorCount = 1;

VkDescriptorPoolCreateInfo pool_create_info = {};
pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_create_info.poolSizeCount = 1;
pool_create_info.pPoolSizes = &pool_size;
pool_create_info.maxSets = 1;

VkDescriptorPool pool;
VkResult result = vkCreateDescriptorPool(device, &pool_create_info, nullptr, &pool);
if (result != VK_SUCCESS) {
ERROR("Unable to create descriptor pool: " << result);
}
return pool;
}

VkDescriptorSet CreateAttachmentVkDescriptorSet(VkDevice device, VkDescriptorPool pool) {
std::vector<VkDescriptorSetLayout> layouts(swapChainImages.size(), descriptorSetLayout);
VkDescriptorSetAllocateInfo allocInfo = {};
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.descriptorPool = descriptorPool;
allocInfo.descriptorSetCount = static_cast<uint32_t>(swapChainImages.size());
allocInfo.pSetLayouts = layouts.data();
}

VkQueue GetVkQueue(VkDevice device, uint32_t device_queue_family_index) {
VkQueue queue;
vkGetDeviceQueue(device, device_queue_family_index, /*queueIndex*/ 0, &queue);
@@ -183,29 +213,50 @@ VkRenderPass CreateVkRenderPass(VkDevice device) {
depth_attachment_reference.attachment = 1;
depth_attachment_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

VkSubpassDescription subpass_description = {};
subpass_description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass_description.colorAttachmentCount = 1;
subpass_description.pColorAttachments = &color_attachment_reference;
subpass_description.pDepthStencilAttachment = &depth_attachment_reference;

VkSubpassDependency subpass_dependency = {};
subpass_dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
subpass_dependency.dstSubpass = 0;
subpass_dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpass_dependency.srcAccessMask = 0;
subpass_dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpass_dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
std::array<VkSubpassDescription, 2> subpass_descriptions = {};
VkSubpassDescription* draw_subpass_description = &subpass_descriptions[0];
draw_subpass_description->pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
draw_subpass_description->colorAttachmentCount = 1;
draw_subpass_description->pColorAttachments = &color_attachment_reference;
draw_subpass_description->pDepthStencilAttachment = &depth_attachment_reference;

VkSubpassDescription* darken_subpass_description = &subpass_descriptions[1];
darken_subpass_description->pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
darken_subpass_description->colorAttachmentCount = 1;
darken_subpass_description->pColorAttachments = &color_attachment_reference;
darken_subpass_description->pDepthStencilAttachment = &depth_attachment_reference;
darken_subpass_description->inputAttachmentCount = 1;
darken_subpass_description->pInputAttachments = &color_attachment_reference;

std::array<VkSubpassDependency, 2> subpass_dependencies = {};
VkSubpassDependency* color_subpass_dependency = &subpass_dependencies[0];
color_subpass_dependency->srcSubpass = VK_SUBPASS_EXTERNAL;
color_subpass_dependency->dstSubpass = 0;
color_subpass_dependency->srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
color_subpass_dependency->dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
color_subpass_dependency->srcAccessMask = 0;
color_subpass_dependency->dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
color_subpass_dependency->dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;

VkSubpassDependency* darken_subpass_dependency = &subpass_dependencies[1];
darken_subpass_dependency->srcSubpass = 0;
darken_subpass_dependency->dstSubpass = 1;
darken_subpass_dependency->srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
darken_subpass_dependency->dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
darken_subpass_dependency->srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
darken_subpass_dependency->dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
darken_subpass_dependency->dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;

VkRenderPassCreateInfo render_pass_info = {};
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
render_pass_info.attachmentCount = attachment_descriptions.size();
render_pass_info.pAttachments = attachment_descriptions.data();
render_pass_info.subpassCount = 1;
render_pass_info.pSubpasses = &subpass_description;
render_pass_info.dependencyCount = 1;
render_pass_info.pDependencies = &subpass_dependency;
render_pass_info.subpassCount = subpass_descriptions.size();
render_pass_info.pSubpasses = subpass_descriptions.data();
render_pass_info.dependencyCount = subpass_dependencies.size();
render_pass_info.pDependencies = subpass_dependencies.data();

VkRenderPass render_pass;
VkResult result = vkCreateRenderPass(device, &render_pass_info, nullptr, &render_pass);
@@ -237,10 +288,8 @@ VkShaderModule CreateVkShaderModule(VkDevice device, std::string path) {
return shader_module;
}

VkPipeline CreateVkPipeline(VkDevice device, VkRenderPass render_pass) {
VkShaderModule vertex_shader_module = CreateVkShaderModule(device, kVertexShaderPath);
VkShaderModule fragment_shader_module = CreateVkShaderModule(device, kFragmentShaderPath);

VkPipeline CreateVkPipeline(VkDevice device, VkShaderModule vertex_shader_module,
VkShaderModule fragment_shader_module, VkRenderPass render_pass, uint32_t subpass) {
VkPipelineShaderStageCreateInfo vertex_shader_stage_info = {};
vertex_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
vertex_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT;
@@ -351,7 +400,7 @@ VkPipeline CreateVkPipeline(VkDevice device, VkRenderPass render_pass) {
pipeline_create_info.pDynamicState = nullptr;
pipeline_create_info.layout = pipeline_layout;
pipeline_create_info.renderPass = render_pass;
pipeline_create_info.subpass = 0;
pipeline_create_info.subpass = subpass;
pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE;
pipeline_create_info.basePipelineIndex = -1;

@@ -560,8 +609,8 @@ void WaitForIdle(VkQueue queue) {
}
}

void Draw(VkDevice device, VkQueue queue, VkRenderPass render_pass, VkPipeline pipeline,
VkFramebuffer framebuffer, VkCommandBuffer command_buffer) {
void Draw(VkDevice device, VkQueue queue, VkRenderPass render_pass, VkPipeline draw_pipeline,
VkPipeline darken_pipeline, VkFramebuffer framebuffer, VkCommandBuffer command_buffer) {
BeginCommandBuffer(command_buffer);
VkRenderPassBeginInfo render_pass_begin_info = {};
render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
@@ -584,9 +633,14 @@ void Draw(VkDevice device, VkQueue queue, VkRenderPass render_pass, VkPipeline p
render_pass_begin_info.pClearValues = clear_values.data();
vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE);

vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, draw_pipeline);
vkCmdDraw(command_buffer, 3, 1, 0, 0);
vkCmdDraw(command_buffer, 3, 1, 3, 0);

vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, darken_pipeline);
vkCmdDraw(command_buffer, 6, 1, 0, 0);

vkCmdEndRenderPass(command_buffer);
}

@@ -671,12 +725,24 @@ int main() {
VkPhysicalDevice physical_device = ChooseVkPhysicalDevice(instance);
uint32_t device_queue_family_index = ChooseDeviceQueueFamilyIndex(physical_device);
VkDevice device = CreateVkDevice(physical_device, device_queue_family_index);
VkDescriptorPool descriptor_pool = CreateAttachmentVkDescriptorPool(device);
VkQueue queue = GetVkQueue(device, device_queue_family_index);
VkCommandPool command_pool = CreateVkCommandPool(device, device_queue_family_index);
VkCommandBuffer command_buffer = CreateVkCommandBuffer(device, command_pool);

VkRenderPass render_pass = CreateVkRenderPass(device);
VkPipeline pipeline = CreateVkPipeline(device, render_pass);
VkShaderModule draw_vertex_shader_module =
CreateVkShaderModule(device, kDrawVertexShaderPath);
VkShaderModule draw_fragment_shader_module =
CreateVkShaderModule(device, kDrawFragmentShaderPath);
VkPipeline draw_pipeline = CreateVkPipeline(device, draw_vertex_shader_module,
draw_fragment_shader_module, render_pass, 0 /* subpass */);
VkShaderModule darken_vertex_shader_module =
CreateVkShaderModule(device, kDarkenVertexShaderPath);
VkShaderModule darken_fragment_shader_module =
CreateVkShaderModule(device, kDarkenFragmentShaderPath);
VkPipeline darken_pipeline = CreateVkPipeline(device, darken_vertex_shader_module,
darken_fragment_shader_module, render_pass, 1 /* subpass */);

VkImage render_image = CreateRenderVkImage(device);
AllocateAndBindRenderMemory(physical_device, device, render_image);
@@ -691,7 +757,7 @@ int main() {
VkDeviceMemory scanout_image_memory =
AllocateAndBindScanoutMemory(physical_device, device, scanout_image);

Draw(device, queue, render_pass, pipeline, framebuffer, command_buffer);
Draw(device, queue, render_pass, draw_pipeline, darken_pipeline, framebuffer, command_buffer);
// Since the render target is created with VK_IMAGE_TILING_OPTIMAL, we need to copy it to a linear
// format before scanning out.
BlitToScanoutImage(queue, command_buffer, render_image, scanout_image);

Loading…
Откажи
Сачувај