diff --git a/readme.md b/readme.md index 567b0dcd3..14efe8524 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,7 @@ -
Spartan Engine is one of the most advanced one-man game engines out there, pushing the limits of real-time solutions and innovation. What started as a portfolio project has evolved into a cutting-edge platform for developers to explore, learn, and contribute. This isn't an engine for the average user, it's designed for advanced research and experimentation, ideal for industry veterans looking to push boundaries, not to build a game (yet). With a thriving Discord community of over 430 members, including industry veterans, and contribution perks that you won't believe when you see, it's one of the most unique projects you'll ever come across.
+Spartan Engine is one of the most advanced one-man game engines out there, pushing the limits of real-time solutions. What started as a portfolio project has evolved into a cutting-edge platform for developers to explore, learn, and contribute. This isn't an engine for the average user, it's designed for advanced research and experimentation, ideal for industry veterans looking to experiment, not to build a game (yet). With a thriving Discord community of over 440 members, including industry veterans, and contribution perks that you won't believe when you see, it's one of the most unique projects you'll ever come across.
- For occasional updates regarding the project's development, you can follow me on X. diff --git a/runtime/RHI/RHI_Texture.cpp b/runtime/RHI/RHI_Texture.cpp index 40d5778de..f3a5f7ca5 100644 --- a/runtime/RHI/RHI_Texture.cpp +++ b/runtime/RHI/RHI_Texture.cpp @@ -218,11 +218,7 @@ namespace Spartan m_channel_count = rhi_to_format_channel_count(format); m_bits_per_channel = rhi_format_to_bits_per_channel(m_format); - if (!(flags & RHI_Texture_DontPrepareForGpu)) - { - RHI_Texture::RHI_CreateResource(); - m_resource_state = ResourceState::PreparedForGpu; - } + PrepareForGpu(); if (!compressonator::registered) { @@ -292,7 +288,7 @@ namespace Spartan } } - ClearBytes(); + ClearData(); } // write properties @@ -320,7 +316,7 @@ namespace Spartan m_flags |= RHI_Texture_Srv; m_object_name = FileSystem::GetFileNameFromFilePath(file_path); - ClearBytes(); + ClearData(); // load from drive if (FileSystem::IsEngineTextureFile(file_path)) @@ -507,7 +503,7 @@ namespace Spartan } } - void RHI_Texture::ClearBytes() + void RHI_Texture::ClearData() { m_slices.clear(); m_slices.shrink_to_fit(); @@ -518,11 +514,15 @@ namespace Spartan SP_ASSERT_MSG(m_resource_state == ResourceState::Max, "Only unprepared textures can be prepared"); m_resource_state = ResourceState::PreparingForGpu; - SP_ASSERT(m_slices.size() > 0); - SP_ASSERT(m_slices[0].mips.size() > 0); + bool generate_mips_and_compress = !IsCompressedFormat() && // the bistro world loads pre-compressed textures + IsMaterialTexture() && // render targets or textures which are written to in compute passes, don't need mip and compression + !(m_flags & RHI_Texture_DontPrepareForGpu); // some textures delay preperation because the material packs their data in a custom way before preparing them - if (!IsCompressedFormat()) // the bistro world loads compressed textures with mips + if (generate_mips_and_compress) { + SP_ASSERT(m_slices.size() > 0); + SP_ASSERT(m_slices[0].mips.size() > 0); + // generate mip chain uint32_t mip_count = mips::compute_count(m_width, m_height); for (uint32_t mip_index = 1; mip_index < mip_count; mip_index++) @@ -530,10 +530,10 @@ namespace Spartan AllocateMip(); mips::downsample_bilinear( - m_slices[0].mips[mip_index - 1].bytes, // above - m_slices[0].mips[mip_index].bytes, // below - max(1u, m_width >> (mip_index - 1)), // above width - max(1u, m_height >> (mip_index - 1)) // above height + m_slices[0].mips[mip_index - 1].bytes, // larger + m_slices[0].mips[mip_index].bytes, // smaller + max(1u, m_width >> (mip_index - 1)), // larger width + max(1u, m_height >> (mip_index - 1)) // larger height ); } @@ -576,16 +576,26 @@ namespace Spartan } // upload to gpu - SP_ASSERT_MSG(RHI_CreateResource(), "Failed to create GPU resource");; + if (!(m_flags & RHI_Texture_DontPrepareForGpu)) + { + SP_ASSERT(RHI_CreateResource()); + } // clear data if (!(m_flags & RHI_Texture_KeepData)) { - ClearBytes(); + ClearData(); } ComputeMemoryUsage(); - m_resource_state = ResourceState::PreparedForGpu; + if (m_rhi_resource) + { + m_resource_state = ResourceState::PreparedForGpu; + } + else + { + m_resource_state = ResourceState::Max; + } } void RHI_Texture::SaveAsImage(const string& file_path) diff --git a/runtime/RHI/RHI_Texture.h b/runtime/RHI/RHI_Texture.h index 4fd42094d..52fb15615 100644 --- a/runtime/RHI/RHI_Texture.h +++ b/runtime/RHI/RHI_Texture.h @@ -115,7 +115,7 @@ namespace Spartan void SetExternalMemoryHandle(void* handle) { m_rhi_external_memory = handle; } // misc - void ClearBytes(); + void ClearData(); void PrepareForGpu(); void SaveAsImage(const std::string& file_path); static size_t CalculateMipSize(uint32_t width, uint32_t height, uint32_t depth, RHI_Format format, uint32_t bits_per_channel, uint32_t channel_count); @@ -146,6 +146,15 @@ namespace Spartan bool IsDepthStencilFormat() const { return IsDepthFormat() || IsStencilFormat(); } bool IsColorFormat() const { return !IsDepthStencilFormat(); } + // usage + bool IsMaterialTexture() const + { + return m_format == RHI_Format::R8G8B8A8_Unorm && + m_channel_count == 4 && + m_bits_per_channel == 8 && + !(IsRtv() || IsDsv()); + } + // layout void SetLayout(const RHI_Image_Layout layout, RHI_CommandList* cmd_list, uint32_t mip_index = rhi_all_mips, uint32_t mip_range = 0); RHI_Image_Layout GetLayout(const uint32_t mip) const { return m_layout[mip]; } @@ -182,8 +191,8 @@ namespace Spartan // api resources void* m_rhi_srv = nullptr; // an srv with all mips std::array