#include "vkn/backend.h" #include "vkn/vulkan_api.h" #include "vkn/thread/command_worker.h" #include "zlog.h" namespace vkn { void VulkanContext::SetScissor(uint32_t x, uint32_t y, uint32_t width, uint32_t height) { VkRect2D scissor = { .offset{ .x = (int32_t)x, .y = (int32_t)y}, .extent {.width = width,.height = height} }; vkCmdSetScissor(command, 0, 1, &scissor); } void VulkanContext::SetViewport(float x, float y, float width, float height, float min_depth, float max_depth) { VkViewport viewport = { .x = x, .y = y, .width = width, .height = height, .minDepth = min_depth, .maxDepth = max_depth }; vkCmdSetViewport(command, 0, 1, &viewport); } void VulkanContext::BindIndexBuffer(BufferDesc desc, uint32_t index_stride) { VkIndexType vk_index_type = (sizeof(uint16_t) == index_stride) ? VK_INDEX_TYPE_UINT16 : ((sizeof(uint8_t) == index_stride) ? VK_INDEX_TYPE_UINT8_EXT : VK_INDEX_TYPE_UINT32); vkCmdBindIndexBuffer(command, (VkBuffer)desc.buffer, 0, vk_index_type); } void VulkanContext::BindVertexBuffer(BufferDesc desc) { VkBuffer vertexBuffers[] = { (VkBuffer)desc.buffer }; VkDeviceSize offsets[] = { 0 }; vkCmdBindVertexBuffers(command, 0, 1, vertexBuffers, offsets); } void VulkanContext::BindVertexBuffers(uint32_t buffer_count, const BufferDesc* descs, const uint32_t* offsets) { VkBuffer vkBuffers[MAX_BUFFER_BIND_NUM] = { 0 }; VkDeviceSize vkOffsets[MAX_BUFFER_BIND_NUM] = { 0 }; for (uint32_t i = 0; i < buffer_count; i++) { vkBuffers[i] = (VkBuffer)descs[i].buffer; vkOffsets[i] = offsets[i]; } vkCmdBindVertexBuffers(command, 0, buffer_count, vkBuffers, vkOffsets); } void VulkanContext::DrawIndexed(uint32_t index_count, uint32_t first_index, uint32_t first_vertex) { vkCmdDrawIndexed(command, index_count, 1, first_index, first_vertex, 0); } void VulkanContext::ExecuteSurfaceBarriers(const ResourceBarrierDesc& desc) { BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); VulkanAPI::Ptr()->ExecuteResourceBarriers(desc); EndRecord(Backend::RenderWorker->GetQueue().Ptr()); } void VulkanContext::BeginRecord(VkCommandBufferUsageFlags flag) { VkCommandBufferBeginInfo beginInfo{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,//sType nullptr, //pNext flag //flags }; vkBeginCommandBuffer(surfaceCommand, &beginInfo); } void VulkanContext::EndRecord(VkQueue queue) { vkEndCommandBuffer(surfaceCommand); VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; // 等待渲染阶段 VkSemaphore waitSemaphores[] = { graphSemaphore ? graphSemaphore : surfaceSemaphore }; VkSemaphore signalSemaphores[] = { presentSemaphore };// 渲染完成信号量 VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &surfaceCommand; submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitStages; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; //zlog::info("-----wait {:#x}", (uintptr_t)waitSemaphores[0]); //zlog::info("+++++sign {:#x}", (uintptr_t)signalSemaphores[0]); vkQueueSubmit(queue, 1, &submitInfo, surfaceFence); graphSemaphore = presentSemaphore; } }