diff --git a/apyre/main.cpp b/apyre/main.cpp index 90784c7..e10acc7 100644 --- a/apyre/main.cpp +++ b/apyre/main.cpp @@ -10,7 +10,7 @@ using namespace apr::enum_operations; int main() { //Initialize Apyre. - apr::application application{apr::application_extension::extended_client_area}; + apr::application application{}; //Create a window. //The parameters are pretty simple, the app, the window's title, it's size (width then height), and some additionnal options. diff --git a/captal/CMakeLists.txt b/captal/CMakeLists.txt index 097cc52..dfc85b4 100644 --- a/captal/CMakeLists.txt +++ b/captal/CMakeLists.txt @@ -52,7 +52,7 @@ set(CAPTAL_SOURCES src/captal/components/attachment.hpp src/captal/components/drawable.hpp src/captal/components/camera.hpp - src/captal/components/audio_emiter.hpp + src/captal/components/audio_emitter.hpp src/captal/systems/frame.hpp src/captal/systems/sorting.hpp @@ -166,6 +166,10 @@ if(CAPTAL_BUILD_CAPTAL_EXAMPLES) target_link_libraries(captal_example PRIVATE captal captal_sansation) target_include_directories(captal_example PRIVATE ${GLOBAL_INCLUDES}) + add_executable(captal_example_easy example_easy.cpp) + target_link_libraries(captal_example_easy PRIVATE captal captal_sansation) + target_include_directories(captal_example_easy PRIVATE ${GLOBAL_INCLUDES}) + add_executable(captal_text text.cpp) target_link_libraries(captal_text PRIVATE captal captal_sansation) target_include_directories(captal_text PRIVATE ${GLOBAL_INCLUDES}) diff --git a/captal/example_easy.cpp b/captal/example_easy.cpp new file mode 100644 index 0000000..bcc9f41 --- /dev/null +++ b/captal/example_easy.cpp @@ -0,0 +1,74 @@ +#include +#include +#include + +int main() +{ + //Initialize the engine + cpt::engine engine{"captal_test", cpt::version{0, 1, 0}}; + + //Create the window + cpt::window_ptr window{cpt::make_window("Example", 640, 480)}; + + //Create the render window that targets our window. + //The default video mode is basically double buffering + VSync. + cpt::render_window_ptr target{cpt::make_render_window(window, cpt::video_mode{})}; + + //Create a view on our render window. + //It will use the default engine render layout, + //and it will create the default render technique that uses the default engine's shaders + //It is basically all defaults :) + cpt::view view{target}; + + //"fit" is an helper functions that set the view size, viewport and scissor + //to the dimension of the window or texture. + view.fit(window); + + //A 40x40px sprite, could have been any renderable + cpt::sprite sprite{40, 40, cpt::colors::dodgerblue}; + //Center the sprite + sprite.move_to(cpt::vec3f{300.0f, 220.0f, 0.0f}); + + //We need to ensure that our object are up to date on the GPU + cpt::memory_transfer_info transfer_info{cpt::engine::instance().begin_transfer()}; + + //cpt::view and cpt::basic_renderable have an helper function "upload" + //that record everything that is needed for you. + view.upload(transfer_info); + sprite.upload(transfer_info); + + //Perform the transfer for real. + cpt::engine::instance().submit_transfers(); + + //We need to close the window manually, the close event just tell us that + //the user want to close it, not that the window has been actually closed. + window->on_close().connect([](cpt::window& window, const apr::window_event&) + { + window.close(); + }); + + //The main loop, once the window will be closed a quit event will be generated + //so the engine will return false + while(cpt::engine::instance().run()) + { + //Tell the window to poll all events and send them through signals + window->dispatch_events(); + + //Here we do our rendering, since we never change anything in our scene, + //we never use `cpt::begin_render_options::reset` + auto render_info{target->begin_render(cpt::begin_render_options::none)}; + if(render_info) + { + //Bind the view, only one view can be bound at a time for each render target. + view.bind(*render_info); + + //Bind and draw the sprite, the view must be specified again because + //the renderable needs + sprite.draw(*render_info, view); + } + + //Actually send the work to the GPU + //Since it is a window, it also actually present the next swapchain image to the screen. + target->present(); + } +} diff --git a/captal/main.cpp b/captal/main.cpp index 53e5e9d..5f69191 100644 --- a/captal/main.cpp +++ b/captal/main.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -98,7 +98,7 @@ static entt::entity add_player(entt::registry& world, cpt::physical_world& physi world.emplace(player, cpt::vec3f{320.0f, 240.0f, 0.5f}); //The player will emit sounds when a wall is hit - world.emplace(player, std::make_unique(44100, 2, 100.0f))->set_volume(0.5f); + world.emplace(player, std::make_unique(44100, 2, 100.0f))->set_volume(0.5f); //The player sprite, we use an ellipse. Why ? Because why not ! const auto points{cpt::ellipse(48.0f, 32.0f)}; @@ -274,7 +274,7 @@ static void add_logic(cpt::render_window_ptr target, entt::registry& world, cpt: //Start the sawtooth when we first collide. if(*current_collisions == 1) { - world.get(player)->start(); + world.get(player)->start(); } return true; @@ -287,7 +287,7 @@ static void add_logic(cpt::render_window_ptr target, entt::registry& world, cpt: //Stop the sawtooth when we no longer collide with any wall. if(*current_collisions == 0) { - world.get(player)->stop(); + world.get(player)->stop(); } return true; diff --git a/captal/src/captal/components/audio_emiter.hpp b/captal/src/captal/components/audio_emitter.hpp similarity index 81% rename from captal/src/captal/components/audio_emiter.hpp rename to captal/src/captal/components/audio_emitter.hpp index 660a95b..2603566 100644 --- a/captal/src/captal/components/audio_emiter.hpp +++ b/captal/src/captal/components/audio_emitter.hpp @@ -20,8 +20,8 @@ //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE //SOFTWARE. -#ifndef CAPTAL_COMPONENTS_AUDIO_EMITER_HPP_INCLUDED -#define CAPTAL_COMPONENTS_AUDIO_EMITER_HPP_INCLUDED +#ifndef CAPTAL_COMPONENTS_AUDIO_EMITTER_HPP_INCLUDED +#define CAPTAL_COMPONENTS_AUDIO_EMITTER_HPP_INCLUDED #include "../config.hpp" @@ -32,23 +32,23 @@ namespace cpt::components { -class audio_emiter +class audio_emitter { public: - audio_emiter() = default; + audio_emitter() = default; template - explicit audio_emiter(Args&&... args) noexcept(std::is_nothrow_constructible_v) + explicit audio_emitter(Args&&... args) noexcept(std::is_nothrow_constructible_v) :m_attachment{std::in_place, std::forward(args)...} { } - ~audio_emiter() = default; - audio_emiter(const audio_emiter&) = delete; - audio_emiter& operator=(const audio_emiter&) = delete; - audio_emiter(audio_emiter&&) noexcept = default; - audio_emiter& operator=(audio_emiter&&) noexcept = default; + ~audio_emitter() = default; + audio_emitter(const audio_emitter&) = delete; + audio_emitter& operator=(const audio_emitter&) = delete; + audio_emitter(audio_emitter&&) noexcept = default; + audio_emitter& operator=(audio_emitter&&) noexcept = default; template sound& attach(Args&&... args) noexcept(std::is_nothrow_constructible_v) @@ -76,7 +76,7 @@ class audio_emiter return m_attachment.has_value(); } - void swap(audio_emiter& other) noexcept + void swap(audio_emitter& other) noexcept { m_attachment.swap(other.m_attachment); } diff --git a/captal/src/captal/render_technique.cpp b/captal/src/captal/render_technique.cpp index fdbb9ef..dd16010 100644 --- a/captal/src/captal/render_technique.cpp +++ b/captal/src/captal/render_technique.cpp @@ -162,8 +162,6 @@ render_layout::render_layout(const render_layout_info& view_info, const render_l descriptor_set_ptr render_layout::make_set(std::uint32_t layout_index) { - assert(layout_index < 2 && "cpt::render_layout does not support custom descriptor set layouts yet."); - std::lock_guard lock{m_mutex}; auto& data{m_layout_data[layout_index]}; diff --git a/captal/src/captal/sound.cpp b/captal/src/captal/sound.cpp index cf0d697..978691d 100644 --- a/captal/src/captal/sound.cpp +++ b/captal/src/captal/sound.cpp @@ -1,17 +1,4 @@ -#include "sound.hpp" - -#include "engine.hpp" - -#include - -namespace cpt -{ - -sound::sound(const std::filesystem::path& file, swl::sound_reader_options options) -:sound{swl::open_file(file, options)} -{ - -}//MIT License +//MIT License // //Copyright (c) 2021 Alexy Pellegrini // @@ -33,7 +20,20 @@ sound::sound(const std::filesystem::path& file, swl::sound_reader_options option //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE //SOFTWARE. +#include "sound.hpp" + +#include "engine.hpp" +#include + +namespace cpt +{ + +sound::sound(const std::filesystem::path& file, swl::sound_reader_options options) +:sound{swl::open_file(file, options)} +{ + +} sound::sound(std::span data, swl::sound_reader_options options) :sound{swl::open_file(data, options)} diff --git a/captal/src/captal/systems/audio.hpp b/captal/src/captal/systems/audio.hpp index 0629927..ee720af 100644 --- a/captal/src/captal/systems/audio.hpp +++ b/captal/src/captal/systems/audio.hpp @@ -31,7 +31,7 @@ #include "../components/node.hpp" #include "../components/listener.hpp" -#include "../components/audio_emiter.hpp" +#include "../components/audio_emitter.hpp" namespace cpt::systems { @@ -46,16 +46,16 @@ inline void audio(entt::registry& world) } }; - const auto update_emiters = [](components::audio_emiter& emiter, const components::node& node) + const auto update_emitters = [](components::audio_emitter& emitter, const components::node& node) { - if(node.is_updated() && emiter.has_attachment()) + if(node.is_updated() && emitter.has_attachment()) { - emiter->move_to(node.position()); + emitter->move_to(node.position()); } }; world.view().each(update_listener); - world.view().each(update_emiters); + world.view().each(update_emitters); } } diff --git a/captal/src/captal/text.cpp b/captal/src/captal/text.cpp index e5167e4..e9ca130 100644 --- a/captal/src/captal/text.cpp +++ b/captal/src/captal/text.cpp @@ -967,7 +967,7 @@ const text_drawer::glyph_info& text_drawer::load(cpt::font& font, std::uint64_t //Load the fallback in case the requested codepoint does not have a glyph inside the font if(codepoint != m_fallback) { - return load(font, make_key(m_fallback, font.info().size, outline, adjust, bold, italic)); + return load(font, make_key(m_fallback, font.info().size, outline, adjust, bold, italic), deferred); } else { diff --git a/captal/src/captal/text.hpp b/captal/src/captal/text.hpp index eb74573..608121d 100644 --- a/captal/src/captal/text.hpp +++ b/captal/src/captal/text.hpp @@ -182,12 +182,12 @@ class CAPTAL_API text_drawer m_options = options; } - void set_adjustement(subpixel_adjustment adjustment) noexcept + void set_adjustment(subpixel_adjustment adjustment) noexcept { m_adjustment = adjustment; } - void set_line_adjustement(subpixel_adjustment adjustment) noexcept + void set_line_adjustment(subpixel_adjustment adjustment) noexcept { m_line_adjustment = adjustment; } diff --git a/captal/src/captal/translation.hpp b/captal/src/captal/translation.hpp index 662deb4..25028de 100644 --- a/captal/src/captal/translation.hpp +++ b/captal/src/captal/translation.hpp @@ -1,3 +1,25 @@ +//MIT License +// +//Copyright (c) 2021 Alexy Pellegrini +// +//Permission is hereby granted, free of charge, to any person obtaining a copy +//of this software and associated documentation files (the "Software"), to deal +//in the Software without restriction, including without limitation the rights +//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +//copies of the Software, and to permit persons to whom the Software is +//furnished to do so, subject to the following conditions: +// +//The above copyright notice and this permission notice shall be included in all +//copies or substantial portions of the Software. +// +//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +//SOFTWARE. + #ifndef CAPTAL_TRANSLATION_HPP_INCLUDED #define CAPTAL_TRANSLATION_HPP_INCLUDED @@ -776,28 +798,6 @@ class CAPTAL_API translation_editor return std::hash{}(std::string_view{reinterpret_cast(std::data(value)), std::size(value)}); } }; - //MIT License - // - //Copyright (c) 2021 Alexy Pellegrini - // - //Permission is hereby granted, free of charge, to any person obtaining a copy - //of this software and associated documentation files (the "Software"), to deal - //in the Software without restriction, including without limitation the rights - //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - //copies of the Software, and to permit persons to whom the Software is - //furnished to do so, subject to the following conditions: - // - //The above copyright notice and this permission notice shall be included in all - //copies or substantial portions of the Software. - // - //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - //SOFTWARE. - public: using translation_set_type = std::unordered_map; diff --git a/captal/src/captal/uniform_buffer.cpp b/captal/src/captal/uniform_buffer.cpp index a9e64c6..36ab20e 100644 --- a/captal/src/captal/uniform_buffer.cpp +++ b/captal/src/captal/uniform_buffer.cpp @@ -7,6 +7,13 @@ namespace cpt { +uniform_buffer::uniform_buffer(const buffer_part& part) +:m_parts{buffer_part_info{0, part.size}} +,m_buffer{engine::instance().uniform_pool().allocate(part.size, engine::instance().graphics_device().limits().min_uniform_buffer_alignment)} +{ + +} + uniform_buffer::uniform_buffer(std::span parts) :m_parts{compute_part_info(parts)} ,m_buffer{engine::instance().uniform_pool().allocate(m_parts.back().offset + m_parts.back().size, engine::instance().graphics_device().limits().min_uniform_buffer_alignment)} diff --git a/captal/src/captal/uniform_buffer.hpp b/captal/src/captal/uniform_buffer.hpp index fcbaa9d..8f923fe 100644 --- a/captal/src/captal/uniform_buffer.hpp +++ b/captal/src/captal/uniform_buffer.hpp @@ -69,6 +69,7 @@ class CAPTAL_API uniform_buffer final : public asynchronous_resource public: uniform_buffer() = default; + explicit uniform_buffer(const buffer_part& part); explicit uniform_buffer(std::span parts); ~uniform_buffer() = default; diff --git a/swell/src/swell/sound_file.cpp b/swell/src/swell/sound_file.cpp index 04c7f4a..982c351 100644 --- a/swell/src/swell/sound_file.cpp +++ b/swell/src/swell/sound_file.cpp @@ -37,6 +37,11 @@ static constexpr std::array flac_header{0x66, 0x4c, 0x61, 0x43} audio_file_format file_format(std::span data) noexcept { + if(std::size(data) < 4) + { + return audio_file_format::unknown; + } + const auto header_data{data.subspan(0, 4)}; if(std::equal(std::begin(header_data), std::end(header_data), std::begin(wave_header), std::end(wave_header))) @@ -61,11 +66,7 @@ audio_file_format file_format(std::istream& stream) if(!stream.read(reinterpret_cast(std::data(header_data)), std::size(header_data))) throw std::runtime_error{"Can not detect audio file format from stream."}; - stream.seekg(0, std::ios_base::beg); - const auto output{file_format(header_data)}; - stream.seekg(0, std::ios_base::beg); - - return output; + return file_format(header_data); } audio_file_format file_format(const std::filesystem::path& file) diff --git a/tephra/example.cpp b/tephra/example.cpp index b5ad056..467a846 100644 --- a/tephra/example.cpp +++ b/tephra/example.cpp @@ -122,47 +122,66 @@ static void run() tph::image image{renderer, std::filesystem::path{u8"fronce.jpg"}, tph::image_usage::transfer_source}; //GPU side data - constexpr tph::texture_info texture_info {tph::texture_format::r8g8b8a8_srgb, tph::texture_usage::sampled | tph::texture_usage::transfer_destination}; - constexpr tph::texture_info target_info {color_format, tph::texture_usage::color_attachment | tph::texture_usage::transfer_source}; - constexpr tph::sampling_options sampling_info{tph::filter::linear, tph::filter::linear}; - constexpr tph::buffer_usage buffer_usage {tph::buffer_usage::device_only | tph::buffer_usage::vertex | tph::buffer_usage::uniform | tph::buffer_usage::transfer_destination}; + constexpr tph::texture_info texture_info{tph::texture_format::r8g8b8a8_srgb, tph::texture_usage::sampled | tph::texture_usage::transfer_destination}; + constexpr tph::texture_info target_info {color_format, tph::texture_usage::color_attachment | tph::texture_usage::transfer_source}; + constexpr tph::sampler_info sampler_info{tph::filter::linear, tph::filter::linear}; + constexpr tph::buffer_usage buffer_usage{tph::buffer_usage::device_only | tph::buffer_usage::vertex | tph::buffer_usage::uniform | tph::buffer_usage::transfer_destination}; - tph::buffer buffer {renderer, std::size(vertices) * sizeof(vertex) + sizeof(ubo), buffer_usage}; - tph::texture texture{renderer, static_cast(image.width()), static_cast(image.height()), texture_info, sampling_info}; - tph::texture target {renderer, 640, 480, target_info}; + tph::buffer buffer{renderer, std::size(vertices) * sizeof(vertex) + sizeof(ubo), buffer_usage}; + + tph::texture texture{renderer, static_cast(image.width()), static_cast(image.height()), texture_info}; + tph::sampler sampler{renderer, sampler_info}; + tph::texture_view view{renderer, texture}; + + tph::texture target{renderer, 640, 480, target_info}; + tph::texture_view target_view{renderer, target}; //The descriptor set, to tell the shaders what resources to use - std::vector pool_sizes{}; - pool_sizes.emplace_back(tph::descriptor_type::uniform_buffer, 1); - pool_sizes.emplace_back(tph::descriptor_type::image_sampler, 1); + constexpr std::array pool_sizes + { + tph::descriptor_pool_size{tph::descriptor_type::uniform_buffer, 1}, + tph::descriptor_pool_size{tph::descriptor_type::image_sampler, 1} + }; + tph::descriptor_pool descriptor_pool{renderer, pool_sizes}; tph::descriptor_set descriptor_set{renderer, descriptor_pool, descriptor_set_layout}; - tph::write_descriptor(renderer, descriptor_set, 0, 0, tph::descriptor_type::uniform_buffer, buffer, 0, sizeof(ubo)); - tph::write_descriptor(renderer, descriptor_set, 1, 0, tph::descriptor_type::image_sampler, texture, tph::texture_layout::shader_read_only_optimal); + const std::array writes + { + tph::descriptor_write{descriptor_set, 0, 0, tph::descriptor_type::uniform_buffer, tph::descriptor_buffer_info {buffer, 0, sizeof(ubo)}}, + tph::descriptor_write{descriptor_set, 1, 0, tph::descriptor_type::image_sampler, tph::descriptor_texture_info{&sampler, &view, tph::texture_layout::shader_read_only_optimal}} + }; + + tph::write_descriptors(renderer, writes); //The output tph::image output{renderer, 640, 480, tph::image_usage::transfer_destination}; - const std::array attachments{std::ref(target)}; + const std::array attachments{std::ref(target_view)}; tph::framebuffer framebuffer{renderer, render_pass, attachments, 640, 480, 1}; tph::command_pool command_pool {renderer}; tph::command_buffer command_buffer{tph::cmd::begin(command_pool, tph::command_buffer_level::primary, tph::command_buffer_options::one_time_submit)}; - tph::cmd::copy(command_buffer, staging_buffer, buffer); + tph::cmd::copy(command_buffer, staging_buffer, buffer, tph::buffer_copy{0, 0, std::size(vertices) * sizeof(vertex) + sizeof(ubo)}); - tph::cmd::transition(command_buffer, texture, - tph::resource_access::none, tph::resource_access::transfer_write, - tph::pipeline_stage::top_of_pipe, tph::pipeline_stage::transfer, - tph::texture_layout::undefined, tph::texture_layout::transfer_destination_optimal); + const std::array first_barrier{tph::texture_memory_barrier + { + texture, {}, + tph::resource_access::none, tph::resource_access::transfer_write, + tph::texture_layout::undefined, tph::texture_layout::transfer_destination_optimal + }}; - tph::cmd::copy(command_buffer, image, texture); + const std::array second_barrier{tph::texture_memory_barrier + { + texture, {}, + tph::resource_access::transfer_write, tph::resource_access::shader_read, + tph::texture_layout::transfer_destination_optimal, tph::texture_layout::shader_read_only_optimal + }}; - tph::cmd::transition(command_buffer, texture, - tph::resource_access::transfer_write, tph::resource_access::shader_read, - tph::pipeline_stage::transfer, tph::pipeline_stage::fragment_shader, - tph::texture_layout::transfer_destination_optimal, tph::texture_layout::shader_read_only_optimal); + tph::cmd::pipeline_barrier(command_buffer, tph::pipeline_stage::top_of_pipe, tph::pipeline_stage::transfer, tph::dependency_flags::none, {}, {}, first_barrier); + tph::cmd::copy(command_buffer, image, texture, tph::image_texture_copy{{}, {}, tph::copy_extent{640, 480, 1}}); + tph::cmd::pipeline_barrier(command_buffer, tph::pipeline_stage::transfer, tph::pipeline_stage::fragment_shader, tph::dependency_flags::none, {}, {}, second_barrier); tph::cmd::begin_render_pass(command_buffer, render_pass, framebuffer); tph::cmd::bind_pipeline(command_buffer, pipeline); @@ -171,7 +190,7 @@ static void run() tph::cmd::draw(command_buffer, std::size(vertices), 1, 0, 0); tph::cmd::end_render_pass(command_buffer); - tph::cmd::copy(command_buffer, target, output); + tph::cmd::copy(command_buffer, target, output, tph::image_texture_copy{{}, {}, tph::copy_extent{640, 480, 1}}); tph::cmd::end(command_buffer); diff --git a/tephra/example/libtephra.dll.a b/tephra/example/libtephra.dll.a index ca35cde..cb37380 100644 Binary files a/tephra/example/libtephra.dll.a and b/tephra/example/libtephra.dll.a differ diff --git a/tephra/example/tephra.dll b/tephra/example/tephra.dll index fea3325..6266db8 100644 Binary files a/tephra/example/tephra.dll and b/tephra/example/tephra.dll differ diff --git a/tephra/example/tephra_example.exe b/tephra/example/tephra_example.exe index 57882c7..795dd5c 100644 Binary files a/tephra/example/tephra_example.exe and b/tephra/example/tephra_example.exe differ diff --git a/tephra/example/test.png b/tephra/example/test.png index a25d9d4..df9b467 100644 Binary files a/tephra/example/test.png and b/tephra/example/test.png differ diff --git a/tephra/src/tephra/commands.cpp b/tephra/src/tephra/commands.cpp index fd06d94..c88aaac 100644 --- a/tephra/src/tephra/commands.cpp +++ b/tephra/src/tephra/commands.cpp @@ -420,7 +420,7 @@ void copy(command_buffer& command_buffer, texture& source, buffer& destination, native_region.imageExtent.depth = region.texture_size.depth; vkCmdCopyImageToBuffer(underlying_cast(command_buffer), - underlying_cast(source), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + underlying_cast(source), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, underlying_cast(destination), 1, &native_region); } @@ -459,7 +459,7 @@ void copy(command_buffer& command_buffer, texture& source, buffer& destination, } vkCmdCopyImageToBuffer(underlying_cast(command_buffer), - underlying_cast(source), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + underlying_cast(source), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, underlying_cast(destination), static_cast(std::size(native_regions)), std::data(native_regions)); } @@ -490,7 +490,7 @@ void copy(command_buffer& command_buffer, texture& source, image& destination, c native_region.imageExtent.depth = region.texture_size.depth; vkCmdCopyImageToBuffer(underlying_cast(command_buffer), - underlying_cast(source), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + underlying_cast(source), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, underlying_cast(destination), 1, &native_region); } @@ -528,7 +528,7 @@ void copy(command_buffer& command_buffer, texture& source, image& destination, s } vkCmdCopyImageToBuffer(underlying_cast(command_buffer), - underlying_cast(source), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + underlying_cast(source), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, underlying_cast(destination), static_cast(std::size(native_regions)), std::data(native_regions)); }