#include "fiko/render/kare_ubo.hpp" #include #include "fiko/render/vk_kontrol.hpp" #include "fiko/render/vulkan_baglam.hpp" #include "vk_mem_alloc.h" namespace fiko { KareUbo::KareUbo(VulkanBaglam& vb) : vb_(vb) { const VkDevice aygit = vb_.aygit(); VkDescriptorSetLayoutBinding bag{}; bag.binding = 0; bag.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; bag.descriptorCount = 1; bag.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; VkDescriptorSetLayoutCreateInfo dsl{VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO}; dsl.bindingCount = 1; dsl.pBindings = &bag; VK_KONTROL(vkCreateDescriptorSetLayout(aygit, &dsl, nullptr, &dsYerlesim_)); VkDescriptorPoolSize havuz{}; havuz.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; havuz.descriptorCount = 1; VkDescriptorPoolCreateInfo hb{VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO}; hb.maxSets = 1; hb.poolSizeCount = 1; hb.pPoolSizes = &havuz; VK_KONTROL(vkCreateDescriptorPool(aygit, &hb, nullptr, &dsHavuz_)); VkDescriptorSetAllocateInfo da{VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO}; da.descriptorPool = dsHavuz_; da.descriptorSetCount = 1; da.pSetLayouts = &dsYerlesim_; VK_KONTROL(vkAllocateDescriptorSets(aygit, &da, &ds_)); // Cihaz-yerel + TRANSFER_DST — yazim vkCmdUpdateBuffer ile (GPU siralamasi). VkBufferCreateInfo bb{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; bb.size = sizeof(KareVeri); bb.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; VmaAllocationCreateInfo bt{}; bt.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; VK_KONTROL(vmaCreateBuffer(vb_.ayirici(), &bb, &bt, &ubo_, &uboT_, nullptr)); VkDescriptorBufferInfo ubi{ubo_, 0, sizeof(KareVeri)}; VkWriteDescriptorSet yaz{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET}; yaz.dstSet = ds_; yaz.dstBinding = 0; yaz.descriptorCount = 1; yaz.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; yaz.pBufferInfo = &ubi; vkUpdateDescriptorSets(aygit, 1, &yaz, 0, nullptr); } KareUbo::~KareUbo() { const VkDevice aygit = vb_.aygit(); if (dsHavuz_) vkDestroyDescriptorPool(aygit, dsHavuz_, nullptr); if (dsYerlesim_) vkDestroyDescriptorSetLayout(aygit, dsYerlesim_, nullptr); if (ubo_) vmaDestroyBuffer(vb_.ayirici(), ubo_, uboT_); } void KareUbo::yaz(VkCommandBuffer kb, const KareVeri& v) { // Değişmediyse dokunma: ışık/renk sabitken her kare transfer+bariyer yazmayalım. if (sonGecerli_ && std::memcmp(&son_, &v, sizeof(KareVeri)) == 0) return; son_ = v; sonGecerli_ = true; vkCmdUpdateBuffer(kb, ubo_, 0, sizeof(KareVeri), &v); // Transfer → fragment shader okumasi (model.frag) bariyeri. VkBufferMemoryBarrier b{VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER}; b.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; // WRITE_AFTER_WRITE de kapsanmali: UBO TEK tampon, ucusteKare kadar kare ayni anda // ucuyor → bir sonraki karenin vkCmdUpdateBuffer'i (TRANSFER_WRITE) onceki karenin // yazimiyla senkronsuz kaliyordu. Olculdu 07-21 (dogrulama katmani, resize firtinasi): // 10 x SYNC-HAZARD-WRITE-AFTER-WRITE. dst'ye TRANSFER_WRITE + TRANSFER asamasi eklendi. b.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; b.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; b.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; b.buffer = ubo_; b.size = VK_WHOLE_SIZE; vkCmdPipelineBarrier(kb, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &b, 0, nullptr); } } // namespace fiko