#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_TEXTURECOMMON_H_ #define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_TEXTURECOMMON_H_ #include "common/abi.h" #include "common/common.h" #include "graphics/guest_gpu/gpu_defs.h" #include "graphics/guest_gpu/tile.h" #include "graphics/host_gpu/transfer.h" #include "graphics/host_gpu/vulkanCommon.h" #include namespace Libs::Graphics { struct GraphicContext; struct VulkanImage; enum class TextureFormatUsage : uint32_t { None = 0, Sampled = 1u << 0u, Storage = 1u << 1u, }; constexpr TextureFormatUsage operator|(TextureFormatUsage lhs, TextureFormatUsage rhs) { return static_cast(static_cast(lhs) | static_cast(rhs)); } constexpr TextureFormatUsage operator&(TextureFormatUsage lhs, TextureFormatUsage rhs) { return static_cast(static_cast(lhs) & static_cast(rhs)); } constexpr TextureFormatUsage operator~(TextureFormatUsage usage) { return static_cast(~static_cast(usage)); } constexpr TextureFormatUsage& operator|=(TextureFormatUsage& lhs, TextureFormatUsage rhs) { lhs = lhs | rhs; return lhs; } constexpr bool TextureHasFormatUsage(TextureFormatUsage usage, TextureFormatUsage flag) { return (static_cast(usage & flag) == static_cast(flag)); } enum class TextureUploadDestination { MipLevels, MipAtlas }; struct RenderTargetFormatInfo { vk::Format format = vk::Format::eUndefined; uint32_t bytes_per_element = 0; Prospero::ColorComponentMapping export_mapping; }; struct TextureUploadLayout { uint32_t tile = 0; uint32_t pitch = 0; uint64_t slice_stride = 0; uint64_t source_slice_stride = 0; uint32_t first_tail_level = 16; TileBlockFamily tile_family = TileBlockFamily::Count; bool volume_texture = false; TileSizeOffset level_sizes[16] = {}; TilePaddedSize padded_sizes[16] = {}; }; struct TextureImageCreateParams { uint32_t fmt = 0; uint64_t width = 0; uint64_t height = 0; uint32_t base_level = 0; uint64_t levels = 1; uint32_t depth = 1; uint64_t type = 0; uint64_t swizzle = 0; TextureFormatUsage format_usage = TextureFormatUsage::Sampled; TextureFormatUsage required_format_usage = TextureFormatUsage::Sampled; TextureFormatUsage view_usage = TextureFormatUsage::Sampled; TextureUploadDestination image_layout = TextureUploadDestination::MipLevels; bool allow_cube_view = false; bool compatible_format_views = false; bool storage_swizzle_fallback = false; const char* owner = nullptr; }; vk::ComponentSwizzle TextureGetComponentSwizzle(uint8_t s); vk::ComponentMapping TextureGetComponentMapping(uint32_t swizzle); bool TextureCheckFormat(GraphicContext* ctx, vk::ImageCreateInfo* image_info); bool TextureCheckStorageSwizzle(vk::ImageCreateInfo* image_info, vk::ComponentMapping* components); vk::ImageUsageFlags TextureGetUsage(TextureFormatUsage usage); vk::ImageUsageFlags TextureGetViewUsage(TextureFormatUsage usage); vk::Format TextureGetFormat(uint32_t fmt); RenderTargetFormatInfo TextureGetRenderTargetFormat(uint32_t layout, uint32_t type, uint32_t order); uint32_t TextureGetAtlasSliceYStride(vk::Format format, uint32_t mip_height, uint32_t depth, uint64_t levels); uint32_t TextureCalcStackedImageHeight(vk::Format format, uint32_t height, uint32_t depth, uint64_t levels); uint32_t TextureCalcMipmapAtlasImageHeight(vk::Format format, uint32_t width, uint32_t height, uint32_t depth, uint64_t levels); bool TextureIs3DTexture(uint64_t type); bool TextureIsCubeTexture(uint64_t type); bool TextureIsLayeredTexture(uint64_t type); bool TextureCanCreateCubeView(uint64_t type, uint32_t base_array, uint32_t layer_count); vk::ComponentMapping TextureCreateImage(GraphicContext* ctx, VulkanImage* image, const TextureImageCreateParams& params); void TextureCreateImageViews(GraphicContext* ctx, VulkanImage* vk_obj, vk::ComponentMapping components, uint64_t type, uint32_t base_array, uint32_t base_level, uint32_t level_count, uint32_t depth, bool allow_cube_view, TextureFormatUsage view_usage); TextureUploadLayout TextureCalcUploadLayout(uint32_t fmt, uint64_t width, uint64_t height, uint64_t levels, uint32_t depth, uint64_t pitch, uint64_t tile, uint64_t upload_size, bool allow_depth_tile, bool volume_texture, const char* owner); uint64_t TextureUploadSliceSourceOffset(const TextureUploadLayout& layout, uint32_t level, uint32_t slice); uint64_t TextureCalcUploadSize(const TextureUploadLayout& layout, const std::vector& regions, uint64_t levels, uint32_t depth); std::vector TextureBuildUploadRegions(const TextureUploadLayout& layout, vk::Format image_format, uint32_t width, uint32_t height, uint32_t depth, uint64_t levels, bool array_texture, bool volume_texture, TextureUploadDestination destination); std::vector TextureBuildDownloadRegions(const std::vector& upload_regions); bool TextureBuildGpuTileInfos(uint64_t size, const std::vector& regions, const TextureUploadLayout& layout, uint32_t fmt, uint32_t depth, uint64_t levels, std::vector* infos); void TextureUploadGuestImage(GraphicContext* ctx, VulkanImage* vk_obj, const void* src_data, uint64_t size, const std::vector& regions, const TextureUploadLayout& layout, uint32_t fmt, uint64_t width, uint64_t height, uint32_t depth, uint64_t levels, const char* owner, vk::ImageLayout dst_layout); } // namespace Libs::Graphics #endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_TEXTURECOMMON_H_ */