| // Copyright 2020 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "drawSizeTest.h" |
| |
| namespace vkbench { |
| void DrawSizeTest::Initialize() { |
| CreateRenderPass(); |
| CreateGraphicsPipeline(); |
| CreateFrameBuffers(); |
| // Create a cmdBuffer with draw call. |
| cmd_buffers_ = vk->GetDevice().allocateCommandBuffers( |
| {vk->GetCommandPool(), vk::CommandBufferLevel::ePrimary, 1}); |
| for (const auto& buffer : cmd_buffers_) { |
| buffer.begin({}); |
| vk::ClearValue clear_color(std::array<float, 4>{0.f, 0.f, 0.f}); |
| vk::RenderPassBeginInfo render_pass_info; |
| render_pass_info.setFramebuffer(frame_buffer_) |
| .setRenderPass(render_pass_) |
| .setClearValueCount(1) |
| .setPClearValues(&clear_color) |
| .setRenderArea(vk::Rect2D({}, img_size_)); |
| buffer.beginRenderPass(render_pass_info, vk::SubpassContents::eInline); |
| buffer.bindPipeline(vk::PipelineBindPoint::eGraphics, graphics_pipeline_); |
| buffer.draw(3, 1, 0, 0); |
| buffer.endRenderPass(); |
| buffer.end(); |
| } |
| |
| vk::SubmitInfo info; |
| info.setCommandBufferCount(1).setPCommandBuffers(cmd_buffers_.data()); |
| smt_infos_.push_back(info); |
| } |
| |
| void DrawSizeTest::Run() { |
| vk->GetGFXQueue().submit(smt_infos_, {}); |
| vk->GetGFXQueue().waitIdle(); |
| } |
| |
| void DrawSizeTest::Destroy() { |
| vk::Device device = vk->GetDevice(); |
| device.destroyImageView(img_view_); |
| delete img_; |
| |
| device.destroyFramebuffer(frame_buffer_); |
| device.destroyRenderPass(render_pass_); |
| device.destroyPipeline(graphics_pipeline_); |
| device.destroyPipelineLayout(pipeline_layout_); |
| device.freeCommandBuffers(vk->GetCommandPool(), cmd_buffers_); |
| } |
| |
| void DrawSizeTest::CreateRenderPass() { |
| vk::AttachmentDescription att_description; |
| att_description.setSamples(vk::SampleCountFlagBits::e1) |
| .setFormat(img_format_) |
| .setLoadOp(vk::AttachmentLoadOp::eClear) |
| .setStoreOp(vk::AttachmentStoreOp::eStore) |
| .setInitialLayout(vk::ImageLayout::eUndefined) |
| .setFinalLayout(vk::ImageLayout::eGeneral); |
| |
| vk::AttachmentReference att_reference; |
| att_reference.setAttachment(0).setLayout( |
| vk::ImageLayout::eColorAttachmentOptimal); |
| vk::SubpassDescription subpass; |
| subpass.setPipelineBindPoint(vk::PipelineBindPoint::eGraphics) |
| .setColorAttachmentCount(1) |
| .setPColorAttachments(&att_reference); |
| |
| vk::RenderPassCreateInfo render_pass_info; |
| render_pass_info.setAttachmentCount(1) |
| .setPAttachments(&att_description) |
| .setSubpassCount(1) |
| .setPSubpasses(&subpass); |
| render_pass_ = vk->GetDevice().createRenderPass(render_pass_info); |
| } |
| |
| void DrawSizeTest::CreateGraphicsPipeline() { |
| std::string vert_shader_code = readFile("shaders/drawSizeTest.vert.spv"); |
| std::string frag_shader_code = readFile("shaders/drawSizeTest.frag.spv"); |
| vk::Device device = vk->GetDevice(); |
| |
| vk::ShaderModule vert_shader_module = |
| CreateShaderModule(device, vert_shader_code); |
| DEFER(device.destroyShaderModule(vert_shader_module)); |
| vk::ShaderModule frag_shader_module = |
| CreateShaderModule(device, frag_shader_code); |
| DEFER(device.destroyShaderModule(frag_shader_module)); |
| vk::PipelineShaderStageCreateInfo shader_stages[] = { |
| {{}, vk::ShaderStageFlagBits::eVertex, vert_shader_module, "main"}, |
| {{}, vk::ShaderStageFlagBits::eFragment, frag_shader_module, "main"}}; |
| |
| vk::PipelineVertexInputStateCreateInfo vertex_input; |
| vk::PipelineInputAssemblyStateCreateInfo input_assembly; |
| input_assembly.setTopology(vk::PrimitiveTopology::eTriangleList); |
| |
| vk::Viewport viewport; |
| viewport.setWidth(img_size_.width).setHeight(img_size_.height).setMaxDepth(1); |
| vk::Rect2D scissor; |
| scissor.setOffset({0, 0}).setExtent(img_size_); |
| vk::PipelineViewportStateCreateInfo viewport_state; |
| viewport_state.setViewportCount(1) |
| .setPViewports(&viewport) |
| .setScissorCount(1) |
| .setPScissors(&scissor); |
| |
| vk::PipelineRasterizationStateCreateInfo rasterizer; |
| rasterizer.setLineWidth(1); |
| vk::PipelineMultisampleStateCreateInfo multisampling; |
| multisampling.setRasterizationSamples(vk::SampleCountFlagBits::e1); |
| vk::PipelineColorBlendAttachmentState color_attachment; |
| color_attachment.setBlendEnable(false).setColorWriteMask( |
| vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | |
| vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA); |
| vk::PipelineColorBlendStateCreateInfo color_info; |
| color_info.setAttachmentCount(1).setPAttachments(&color_attachment); |
| |
| vk::PipelineLayoutCreateInfo layout_info; |
| pipeline_layout_ = device.createPipelineLayout(layout_info); |
| |
| vk::GraphicsPipelineCreateInfo pipelineInfo; |
| pipelineInfo.setStageCount(2) |
| .setPStages(shader_stages) |
| .setPVertexInputState(&vertex_input) |
| .setPInputAssemblyState(&input_assembly) |
| .setPViewportState(&viewport_state) |
| .setPRasterizationState(&rasterizer) |
| .setPMultisampleState(&multisampling) |
| .setPColorBlendState(&color_info) |
| .setLayout(pipeline_layout_) |
| .setRenderPass(render_pass_); |
| |
| graphics_pipeline_ = |
| (vk::Pipeline &&) device.createGraphicsPipeline({}, pipelineInfo); |
| } |
| |
| void DrawSizeTest::CreateFrameBuffers() { |
| const vk::Device device = vk->GetDevice(); |
| |
| img_ = vk->AllocateImage(img_size_, img_format_, |
| vk::ImageUsageFlagBits::eColorAttachment | |
| vk::ImageUsageFlagBits::eTransferSrc, |
| vk::MemoryPropertyFlagBits::eDeviceLocal); |
| |
| vk::ImageViewCreateInfo img_view_create_info; |
| img_view_create_info.setViewType(vk::ImageViewType::e2D) |
| .setFormat(img_format_) |
| .setImage(img_->GetImage()); |
| img_view_create_info.subresourceRange |
| .setAspectMask(vk::ImageAspectFlagBits::eColor) |
| .setBaseMipLevel(0) |
| .setLevelCount(1) |
| .setBaseArrayLayer(0) |
| .setLayerCount(1); |
| img_view_ = device.createImageView(img_view_create_info); |
| |
| vk::FramebufferCreateInfo frame_buffer_info; |
| frame_buffer_info.setRenderPass(render_pass_) |
| .setAttachmentCount(1) |
| .setPAttachments(&img_view_) |
| .setWidth(img_size_.width) |
| .setHeight(img_size_.height) |
| .setLayers(1); |
| frame_buffer_ = device.createFramebuffer(frame_buffer_info); |
| } |
| |
| void DrawSizeTest::SaveImage(std::string filename) const { |
| const vk::Device device = vk->GetDevice(); |
| vkImage* dest = vk->GetReadableImage(img_, img_size_, img_format_); |
| DEFER(delete dest); |
| vk::SubresourceLayout sub_resource_layout = device.getImageSubresourceLayout( |
| dest->GetImage(), {vk::ImageAspectFlagBits::eColor, 0, 0}); |
| const char* data = |
| (const char*)device.mapMemory(dest->GetMemory(), 0, VK_WHOLE_SIZE); |
| data += sub_resource_layout.offset; |
| SavePPM(filename, data, img_size_.width, img_size_.height, |
| sub_resource_layout.rowPitch); |
| |
| DEBUG("Saved image to %s", filename.c_str()); |
| } |
| |
| } // namespace vkbench |