X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbackends%2Fvulkan%2Ftexture_backend.cpp;h=dd19c63664b88658fe06917798742bbcbb4fd2f5;hb=7b0a38db12c3d1aacb59520a3f4baa16d9ec0048;hp=06c4a622341955b1064539afe11b369c0620b9e6;hpb=a16145549dc87c3b12671f797bd77b14bcc7786b;p=libs%2Fgl.git diff --git a/source/backends/vulkan/texture_backend.cpp b/source/backends/vulkan/texture_backend.cpp index 06c4a622..dd19c636 100644 --- a/source/backends/vulkan/texture_backend.cpp +++ b/source/backends/vulkan/texture_backend.cpp @@ -56,7 +56,7 @@ void VulkanTexture::allocate() image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - image_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + image_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT; PixelComponents comp = get_components(self.storage_fmt); if(comp==DEPTH_COMPONENT || comp==STENCIL_INDEX) image_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; @@ -73,7 +73,7 @@ void VulkanTexture::allocate() memory_id = device.get_allocator().allocate(handle, DEVICE_MEMORY); // Trigger a layout transition if the image is used before uploading data. - synchronize(-1, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true); + change_layout(0, -1, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true); } VkImageViewCreateInfo view_info = { }; @@ -100,15 +100,78 @@ void VulkanTexture::allocate() set_vulkan_object_names(); } -void VulkanTexture::generate_mipmap() +void VulkanTexture::stage_pixels(void *staging, const void *data, size_t count) { - throw logic_error("VulkanTexture::generate_mipmap is unimplemented"); + const Texture &self = *static_cast(this); + + if(self.swizzle==RGBA_TO_RGB) + { + const uint32_t *src = static_cast(data); + uint32_t *dst = static_cast(staging); + size_t i = 0; + for(; i+3>24)|(src[1]<<8)|0xFF000000; + dst[2] = (src[1]>>16)|(src[2]<<16)|0xFF000000; + dst[3] = (src[2]>>8)|0xFF000000; + src += 3; + dst += 4; + } + + if(i(src); + for(; i(data); + size_t data_size = count*get_pixel_size(self.storage_fmt); + copy(src, src+data_size, static_cast(staging)); + } +} + +void VulkanTexture::generate_mipmap_levels(unsigned n_levels) +{ + TransferQueue &tq = device.get_transfer_queue(); + for(unsigned i=0; i+1(this)->storage_fmt)); + region.srcSubresource.mipLevel = i; + region.srcSubresource.baseArrayLayer = 0; + region.srcSubresource.layerCount = 1; + region.dstSubresource = region.srcSubresource; + ++region.dstSubresource.mipLevel; + + fill_mipmap_blit(i, ®ion); + + vk.CmdBlitImage(cmd_buf, handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, ®ion, VK_FILTER_LINEAR); + }); + } } -void VulkanTexture::synchronize(int layer, unsigned layout, bool discard) const +void VulkanTexture::change_layout(unsigned n_levels, int level, unsigned layout, bool discard) const { unsigned aspect = get_vulkan_aspect(get_components(static_cast(this)->storage_fmt)); - device.get_synchronizer().access(handle, aspect, layer, layout, discard); + if(n_levels>0) + device.get_synchronizer().split_image_mipmap(handle, aspect, n_levels); + device.get_synchronizer().change_image_layout(handle, aspect, level, layout, discard); } void VulkanTexture::set_debug_name(const string &name)