diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp index 5a78b976c..f6951786b 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp @@ -1,6 +1,7 @@ #include "BdaAbi.hpp" #include "prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp" #include "prx/libSceAgcDriver/Execution/include/BdaFeatures.hpp" +#include "prx/libSceAgcDriver/Graphics/include/TextureDetiler.hpp" #include "prx/libc/include/General.hpp" #include #include @@ -63,6 +64,9 @@ struct VulkanDevice::State { bool fragmentShaderBarycentric = false; bool depthClipControl = false; bool depthRangeUnrestricted = false; + bool samplerAnisotropy = false; + bool textureCompressionBC = false; + std::unique_ptr detiler; VkPhysicalDeviceMeshShaderPropertiesEXT meshLimits{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_EXT}; template @@ -128,6 +132,7 @@ struct VulkanDevice::State { if (device != VK_NULL_HANDLE) { const auto idle = reinterpret_cast(deviceProc(device, "vkDeviceWaitIdle"))(device); if (idle != VK_SUCCESS && idle != VK_ERROR_DEVICE_LOST) std::terminate(); + detiler.reset(); if (presentQueued && idle != VK_ERROR_DEVICE_LOST) { const auto result = reinterpret_cast(deviceProc(device, "vkWaitForFences"))(device, 1, &presentFence, VK_TRUE, std::numeric_limits::max()); if (result != VK_SUCCESS && result != VK_ERROR_DEVICE_LOST) std::terminate(); @@ -363,6 +368,11 @@ VulkanDevice::VulkanDevice(const PresentationWindow* window) : state(std::make_u enabled.tessellationShader = available.tessellationShader; state->tessellationShader = enabled.tessellationShader == VK_TRUE; if (state->tessellationShader) state->capabilities.push_back(3); + require(available.samplerAnisotropy && available.textureCompressionBC, "device lacks sampler anisotropy or BC texture compression support required for texture sampling"); + enabled.samplerAnisotropy = VK_TRUE; + enabled.textureCompressionBC = VK_TRUE; + state->samplerAnisotropy = true; + state->textureCompressionBC = true; deviceInfo.pEnabledFeatures = &enabled; deviceInfo.enabledExtensionCount = static_cast(deviceExtensions.size()); deviceInfo.ppEnabledExtensionNames = deviceExtensions.data(); diff --git a/core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp b/core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp index bc49d28f7..6b595a940 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp @@ -11,6 +11,8 @@ namespace AgcDriver::Graphics { +class TextureDetiler; + inline void Require(bool condition, const std::string& reason) { if (!condition) throw std::runtime_error("AGC graphics: " + reason); } @@ -37,6 +39,9 @@ struct Context { bool bufferDeviceAddress = false; VkPhysicalDeviceSubgroupProperties subgroup{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES}; bool fragmentShaderBarycentric = false; + bool samplerAnisotropy = false; + bool textureCompressionBC = false; + TextureDetiler* detiler = nullptr; template TFunction Function(const char* name) const { diff --git a/core/libs/prx/libSceAgcDriver/Graphics/include/GuestSamplerResource.hpp b/core/libs/prx/libSceAgcDriver/Graphics/include/GuestSamplerResource.hpp new file mode 100644 index 000000000..1b4026ab9 --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/Graphics/include/GuestSamplerResource.hpp @@ -0,0 +1,32 @@ +#ifndef CORE_LIBS_PRX_LIBSCEAGCDRIVER_GRAPHICS_INCLUDE_GUESTSAMPLERRESOURCE_HPP +#define CORE_LIBS_PRX_LIBSCEAGCDRIVER_GRAPHICS_INCLUDE_GUESTSAMPLERRESOURCE_HPP + +#ifndef VK_NO_PROTOTYPES +#define VK_NO_PROTOTYPES +#endif +#include +#include +#include + +namespace AgcDriver::Graphics { + +struct GuestSamplerResource { + VkFilter magFilter; + VkFilter minFilter; + VkSamplerMipmapMode mipmapMode; + VkSamplerAddressMode addressModeU; + VkSamplerAddressMode addressModeV; + VkSamplerAddressMode addressModeW; + bool anisotropyEnable; + float maxAnisotropy; + float minLod; + float maxLod; + float lodBias; + VkBorderColor borderColor; +}; + +GuestSamplerResource DecodeSamplerResource(std::span words); + +} + +#endif diff --git a/core/libs/prx/libSceAgcDriver/Graphics/include/GuestTextureResource.hpp b/core/libs/prx/libSceAgcDriver/Graphics/include/GuestTextureResource.hpp new file mode 100644 index 000000000..049feea2f --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/Graphics/include/GuestTextureResource.hpp @@ -0,0 +1,46 @@ +#ifndef CORE_LIBS_PRX_LIBSCEAGCDRIVER_GRAPHICS_INCLUDE_GUESTTEXTURERESOURCE_HPP +#define CORE_LIBS_PRX_LIBSCEAGCDRIVER_GRAPHICS_INCLUDE_GUESTTEXTURERESOURCE_HPP + +#include "Recompiler.hpp" +#include +#include + +namespace AgcDriver::Graphics { + +enum class TextureTileMode { + kLinear, + kStandard256B, + kStandard4KB, + kStandard64KB +}; + +enum class TextureDimension { + k1D, + k2D, + k2DArray, + kCube +}; + +struct GuestTextureResource { + std::uint64_t baseAddress; + std::uint32_t width; + std::uint32_t height; + std::uint32_t depthOrLastArray; + std::uint32_t baseArray; + std::uint32_t mipCount; + std::uint32_t baseLevel; + TextureTileMode tileMode; + TextureDimension dimension; + std::uint32_t format; + std::uint8_t dstSelX; + std::uint8_t dstSelY; + std::uint8_t dstSelZ; + std::uint8_t dstSelW; +}; + +GuestTextureResource DecodeTextureResource(std::span words); +bool MatchesGuestDimension(ShaderRecompiler::DescriptorImageShape shape, TextureDimension dimension); + +} + +#endif diff --git a/core/libs/prx/libSceAgcDriver/Graphics/include/Sampler.hpp b/core/libs/prx/libSceAgcDriver/Graphics/include/Sampler.hpp new file mode 100644 index 000000000..adfe6216f --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/Graphics/include/Sampler.hpp @@ -0,0 +1,27 @@ +#ifndef CORE_LIBS_PRX_LIBSCEAGCDRIVER_GRAPHICS_INCLUDE_SAMPLER_HPP +#define CORE_LIBS_PRX_LIBSCEAGCDRIVER_GRAPHICS_INCLUDE_SAMPLER_HPP + +#include "prx/libSceAgcDriver/Graphics/include/Context.hpp" +#include "prx/libSceAgcDriver/Graphics/include/GuestSamplerResource.hpp" + +namespace AgcDriver::Graphics { + +class Sampler { +public: + Sampler(const Context& context, const GuestSamplerResource& descriptor); + ~Sampler(); + Sampler(const Sampler&) = delete; + Sampler& operator=(const Sampler&) = delete; + + VkSampler Handle() const; + +private: + void release() noexcept; + + const Context& context; + VkSampler sampler = VK_NULL_HANDLE; +}; + +} + +#endif diff --git a/core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp b/core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp index e6b18bda7..8f49a411f 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp @@ -3,6 +3,8 @@ #include "prx/libSceAgcDriver/Graphics/include/Resources.hpp" #include "prx/libSceAgcDriver/Graphics/include/BdaResources.hpp" +#include "prx/libSceAgcDriver/Graphics/include/Texture.hpp" +#include "prx/libSceAgcDriver/Graphics/include/Sampler.hpp" #include "Recompiler.hpp" #include "prx/libSceAgcDriver/Graphics/include/Shaders.hpp" #include @@ -35,6 +37,7 @@ private: void build(std::span shaders, const ColorTarget* target, std::uint64_t indexAddress, std::size_t indexBytes); std::size_t addGuestBuffer(std::span words, const ColorTarget* target, std::uint64_t indexAddress, std::size_t indexBytes); std::size_t addDataBuffer(std::span words); + void addImageBinding(const ShaderRecompiler::DescriptorBinding& binding, VkShaderStageFlags flags); void release() noexcept; void prepareAddressBindings(std::span shaders, std::span snapshots); VkDescriptorBufferInfo descriptor(const Allocation& allocation) const; @@ -46,6 +49,8 @@ private: VkDescriptorSet _set = VK_NULL_HANDLE; VkDescriptorPool pool = VK_NULL_HANDLE; std::vector allocations; + std::vector> textures; + std::vector> samplers; }; } diff --git a/core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp b/core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp new file mode 100644 index 000000000..6b4466cc2 --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp @@ -0,0 +1,30 @@ +#ifndef CORE_LIBS_PRX_LIBSCEAGCDRIVER_GRAPHICS_INCLUDE_TEXTURE_HPP +#define CORE_LIBS_PRX_LIBSCEAGCDRIVER_GRAPHICS_INCLUDE_TEXTURE_HPP + +#include "prx/libSceAgcDriver/Graphics/include/Context.hpp" +#include "prx/libSceAgcDriver/Graphics/include/GuestTextureResource.hpp" +#include "prx/libSceAgcDriver/Graphics/include/TextureDetiler.hpp" + +namespace AgcDriver::Graphics { + +class Texture { +public: + Texture(const Context& context, TextureDetiler& detiler, const GuestTextureResource& descriptor, VkComponentMapping components); + ~Texture(); + Texture(const Texture&) = delete; + Texture& operator=(const Texture&) = delete; + + VkImageView View() const; + +private: + void release() noexcept; + + const Context& context; + VkImage image = VK_NULL_HANDLE; + VkDeviceMemory memory = VK_NULL_HANDLE; + VkImageView view = VK_NULL_HANDLE; +}; + +} + +#endif diff --git a/core/libs/prx/libSceAgcDriver/Graphics/include/TextureDetiler.hpp b/core/libs/prx/libSceAgcDriver/Graphics/include/TextureDetiler.hpp new file mode 100644 index 000000000..67929affd --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/Graphics/include/TextureDetiler.hpp @@ -0,0 +1,35 @@ +#ifndef CORE_LIBS_PRX_LIBSCEAGCDRIVER_GRAPHICS_INCLUDE_TEXTUREDETILER_HPP +#define CORE_LIBS_PRX_LIBSCEAGCDRIVER_GRAPHICS_INCLUDE_TEXTUREDETILER_HPP + +#include "prx/libSceAgcDriver/Graphics/include/Context.hpp" +#include "prx/libSceAgcDriver/Graphics/include/GuestTextureResource.hpp" +#include "prx/libSceAgcDriver/Graphics/include/TextureTiling.hpp" +#include +#include +#include + +namespace AgcDriver::Graphics { + +class TextureDetiler { +public: + explicit TextureDetiler(const Context& context); + ~TextureDetiler(); + TextureDetiler(const TextureDetiler&) = delete; + TextureDetiler& operator=(const TextureDetiler&) = delete; + + void Dispatch(VkCommandBuffer commands, TextureTileMode tileMode, std::uint32_t elementBytes, VkBuffer source, std::uint64_t sourceOffset, VkBuffer destination, std::uint64_t destinationOffset, const TileMipLayout& layout); + +private: + VkPipeline pipeline(TextureTileMode tileMode, std::uint32_t elementBytes); + void release() noexcept; + + const Context& context; + VkDescriptorSetLayout descriptorLayout = VK_NULL_HANDLE; + VkPipelineLayout pipelineLayout = VK_NULL_HANDLE; + VkShaderModule module = VK_NULL_HANDLE; + std::vector> pipelines; +}; + +} + +#endif diff --git a/core/libs/prx/libSceAgcDriver/Graphics/include/TextureFormat.hpp b/core/libs/prx/libSceAgcDriver/Graphics/include/TextureFormat.hpp new file mode 100644 index 000000000..a631ca03e --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/Graphics/include/TextureFormat.hpp @@ -0,0 +1,20 @@ +#ifndef CORE_LIBS_PRX_LIBSCEAGCDRIVER_GRAPHICS_INCLUDE_TEXTUREFORMAT_HPP +#define CORE_LIBS_PRX_LIBSCEAGCDRIVER_GRAPHICS_INCLUDE_TEXTUREFORMAT_HPP + +#ifndef VK_NO_PROTOTYPES +#define VK_NO_PROTOTYPES +#endif +#include +#include + +namespace AgcDriver::Graphics { + +VkFormat ResolveTextureFormat(std::uint32_t guestFormat); +std::uint32_t BytesPerElement(std::uint32_t guestFormat); +bool IsBlockCompressed(std::uint32_t guestFormat); +std::uint32_t BlockWidth(std::uint32_t guestFormat); +std::uint32_t BlockHeight(std::uint32_t guestFormat); + +} + +#endif diff --git a/core/libs/prx/libSceAgcDriver/Graphics/include/TextureTiling.hpp b/core/libs/prx/libSceAgcDriver/Graphics/include/TextureTiling.hpp new file mode 100644 index 000000000..fbfe21b38 --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/Graphics/include/TextureTiling.hpp @@ -0,0 +1,29 @@ +#ifndef CORE_LIBS_PRX_LIBSCEAGCDRIVER_GRAPHICS_INCLUDE_TEXTURETILING_HPP +#define CORE_LIBS_PRX_LIBSCEAGCDRIVER_GRAPHICS_INCLUDE_TEXTURETILING_HPP + +#include "prx/libSceAgcDriver/Graphics/include/GuestTextureResource.hpp" +#include +#include + +namespace AgcDriver::Graphics { + +struct TileMipLayout { + std::uint64_t tiledOffset; + std::uint64_t tiledSize; + std::uint64_t linearOffset; + std::uint64_t linearSize; + std::uint32_t width; + std::uint32_t height; + std::uint32_t blocksPerRow; + std::uint32_t pitchBytes; + bool tail; + std::uint32_t tailX; + std::uint32_t tailY; +}; + +std::vector ComputeMipLayout(TextureTileMode tileMode, std::uint32_t format, std::uint32_t width, std::uint32_t height, std::uint32_t mipCount); +std::uint64_t ComputeSurfaceSize(const std::vector& mips, std::uint32_t arrayLayers); + +} + +#endif diff --git a/core/libs/prx/libSceAgcDriver/Graphics/shaders/TextureDetile.comp b/core/libs/prx/libSceAgcDriver/Graphics/shaders/TextureDetile.comp new file mode 100644 index 000000000..7157f3339 --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/Graphics/shaders/TextureDetile.comp @@ -0,0 +1,26 @@ +#version 450 + +layout(constant_id = 0) const uint ELEMENT_BYTES = 4u; +layout(constant_id = 1) const uint BLOCK_BYTES = 256u; +layout(constant_id = 2) const uint TILE_FAMILY = 0u; + +layout(local_size_x = 8, local_size_y = 8) in; + +layout(set = 0, binding = 0, std430) readonly buffer Input { uint data[]; } inputBuffer; +layout(set = 0, binding = 1, std430) buffer Output { uint data[]; } outputBuffer; + +layout(push_constant) uniform Push { + uint srcBase; + uint dstBase; + uint width; + uint height; + uint pitchBytes; + uint blocksPerRow; + uint tail; + uint tailX; + uint tailY; + uint elementBytes; +} params; + +void main() { +} diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/GuestSamplerResource.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/GuestSamplerResource.cpp new file mode 100644 index 000000000..2d52d7aeb --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/GuestSamplerResource.cpp @@ -0,0 +1,12 @@ +#include "prx/libSceAgcDriver/Graphics/include/GuestSamplerResource.hpp" +#include +#include + +namespace AgcDriver::Graphics { + +GuestSamplerResource DecodeSamplerResource(std::span words) { + static_cast(words); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + +} diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/GuestTextureResource.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/GuestTextureResource.cpp new file mode 100644 index 000000000..917a33d02 --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/GuestTextureResource.cpp @@ -0,0 +1,18 @@ +#include "prx/libSceAgcDriver/Graphics/include/GuestTextureResource.hpp" +#include +#include + +namespace AgcDriver::Graphics { + +GuestTextureResource DecodeTextureResource(std::span words) { + static_cast(words); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + +bool MatchesGuestDimension(ShaderRecompiler::DescriptorImageShape shape, TextureDimension dimension) { + static_cast(shape); + static_cast(dimension); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + +} diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/Sampler.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/Sampler.cpp new file mode 100644 index 000000000..7f04b9a7d --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/Sampler.cpp @@ -0,0 +1,24 @@ +#include "prx/libSceAgcDriver/Graphics/include/Sampler.hpp" +#include +#include + +namespace AgcDriver::Graphics { + +Sampler::Sampler(const Context& context, const GuestSamplerResource& descriptor) : context(context) { + static_cast(descriptor); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + +Sampler::~Sampler() { + release(); +} + +void Sampler::release() noexcept { + if (sampler) context.Function("vkDestroySampler")(context.device, sampler, nullptr); +} + +VkSampler Sampler::Handle() const { + return sampler; +} + +} diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp index 0331bcf47..8799955e2 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp @@ -74,7 +74,10 @@ void ShaderResources::build(std::span shaders, const Color const bool addressRole = binding.role == ShaderRecompiler::DescriptorRole::BdaPagetable || binding.role == ShaderRecompiler::DescriptorRole::FaultBuffer; const bool bufferRole = addressRole || binding.role == ShaderRecompiler::DescriptorRole::GuestBuffers || binding.role == ShaderRecompiler::DescriptorRole::ShaderData || binding.role == ShaderRecompiler::DescriptorRole::FlattenedSrt; const bool imageRole = binding.role == ShaderRecompiler::DescriptorRole::GuestImages || binding.role == ShaderRecompiler::DescriptorRole::GuestSamplers; - Require(!imageRole, "sampled and storage image resources are not implemented"); + if (imageRole) { + addImageBinding(binding, flags); + continue; + } Require(bufferRole, std::string("unsupported descriptor role ") + roleName(binding.role)); Require(binding.kind == ShaderRecompiler::DescriptorKind::StorageBuffer, std::string("unsupported descriptor kind ") + kindName(binding.kind) + " for role " + roleName(binding.role) + ": only StorageBuffer is supported"); Require(!binding.readOnly, "read-only descriptors are unsupported because the recompiler emits no NonWritable decoration"); @@ -161,6 +164,12 @@ std::size_t ShaderResources::addDataBuffer(std::span words) return allocations.size() - 1; } +void ShaderResources::addImageBinding(const ShaderRecompiler::DescriptorBinding& binding, VkShaderStageFlags flags) { + static_cast(binding); + static_cast(flags); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + ShaderResources::~ShaderResources() { release(); } diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp index 303c8fafd..50895732f 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp @@ -395,7 +395,7 @@ Module Inspect(const CompiledShader& compiled, const State& state, const VkPhysi const auto binding = std::find_if(shader.bindings.begin(), shader.bindings.end(), [&](const auto& item) { return item.descriptorSet == key.first && item.binding == key.second; }); Require(binding != shader.bindings.end(), "SPIR-V resource is absent from recompiler binding metadata"); Require(binding->kind == ShaderRecompiler::DescriptorKind::Sampler || binding->kind == ShaderRecompiler::DescriptorKind::SampledImage || binding->kind == ShaderRecompiler::DescriptorKind::StorageImage, "SPIR-V descriptor type disagrees with recompiler binding metadata"); - Require(false, "sampled and storage image resources are not implemented"); + Require(binding->kind != ShaderRecompiler::DescriptorKind::StorageImage, "storage image resources are not implemented"); } else { Require(variable.storage == spv::StorageClassStorageBuffer && decoration.set && decoration.binding, "unsupported or unbound shader resource"); const auto key = std::make_pair(*decoration.set, *decoration.binding); diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp new file mode 100644 index 000000000..65b67e50f --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp @@ -0,0 +1,28 @@ +#include "prx/libSceAgcDriver/Graphics/include/Texture.hpp" +#include +#include + +namespace AgcDriver::Graphics { + +Texture::Texture(const Context& context, TextureDetiler& detiler, const GuestTextureResource& descriptor, VkComponentMapping components) : context(context) { + static_cast(detiler); + static_cast(descriptor); + static_cast(components); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + +Texture::~Texture() { + release(); +} + +void Texture::release() noexcept { + if (view) context.Function("vkDestroyImageView")(context.device, view, nullptr); + if (image) context.Function("vkDestroyImage")(context.device, image, nullptr); + if (memory) context.Function("vkFreeMemory")(context.device, memory, nullptr); +} + +VkImageView Texture::View() const { + return view; +} + +} diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/TextureDetiler.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/TextureDetiler.cpp new file mode 100644 index 000000000..1fa834f0f --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/TextureDetiler.cpp @@ -0,0 +1,36 @@ +#include "prx/libSceAgcDriver/Graphics/include/TextureDetiler.hpp" +#include +#include + +namespace AgcDriver::Graphics { + +TextureDetiler::TextureDetiler(const Context& context) : context(context) { + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + +TextureDetiler::~TextureDetiler() { + release(); +} + +void TextureDetiler::release() noexcept { +} + +VkPipeline TextureDetiler::pipeline(TextureTileMode tileMode, std::uint32_t elementBytes) { + static_cast(tileMode); + static_cast(elementBytes); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + +void TextureDetiler::Dispatch(VkCommandBuffer commands, TextureTileMode tileMode, std::uint32_t elementBytes, VkBuffer source, std::uint64_t sourceOffset, VkBuffer destination, std::uint64_t destinationOffset, const TileMipLayout& layout) { + static_cast(commands); + static_cast(tileMode); + static_cast(elementBytes); + static_cast(source); + static_cast(sourceOffset); + static_cast(destination); + static_cast(destinationOffset); + static_cast(layout); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + +} diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/TextureFormat.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/TextureFormat.cpp new file mode 100644 index 000000000..dd6d2f356 --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/TextureFormat.cpp @@ -0,0 +1,32 @@ +#include "prx/libSceAgcDriver/Graphics/include/TextureFormat.hpp" +#include +#include + +namespace AgcDriver::Graphics { + +VkFormat ResolveTextureFormat(std::uint32_t guestFormat) { + static_cast(guestFormat); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + +std::uint32_t BytesPerElement(std::uint32_t guestFormat) { + static_cast(guestFormat); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + +bool IsBlockCompressed(std::uint32_t guestFormat) { + static_cast(guestFormat); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + +std::uint32_t BlockWidth(std::uint32_t guestFormat) { + static_cast(guestFormat); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + +std::uint32_t BlockHeight(std::uint32_t guestFormat) { + static_cast(guestFormat); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + +} diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/TextureTiling.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/TextureTiling.cpp new file mode 100644 index 000000000..d658c6dac --- /dev/null +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/TextureTiling.cpp @@ -0,0 +1,22 @@ +#include "prx/libSceAgcDriver/Graphics/include/TextureTiling.hpp" +#include +#include + +namespace AgcDriver::Graphics { + +std::vector ComputeMipLayout(TextureTileMode tileMode, std::uint32_t format, std::uint32_t width, std::uint32_t height, std::uint32_t mipCount) { + static_cast(tileMode); + static_cast(format); + static_cast(width); + static_cast(height); + static_cast(mipCount); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + +std::uint64_t ComputeSurfaceSize(const std::vector& mips, std::uint32_t arrayLayers) { + static_cast(mips); + static_cast(arrayLayers); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + +} diff --git a/core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp b/core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp index 68d4b22c6..ec7268707 100644 --- a/core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp +++ b/core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp @@ -54,6 +54,12 @@ DescriptorRole RoleFor(DescriptorBindingKind kind) { fail("DescriptorBindingBuilder::Populate binding kind has no descriptor role"); } +DescriptorImageShape ImageShapeFor(const std::vector& images, const std::vector& resources) { + static_cast(images); + static_cast(resources); + throw std::runtime_error(std::string(__func__) + " not implemented"); +} + std::vector GuestBuffersDescriptor(const std::vector& resources, const ResourceSnapshot& snapshot) { std::vector result; result.reserve(resources.size() * 4u); @@ -156,6 +162,7 @@ void DescriptorBindingBuilder::Populate(BindingAllocationResult& allocation, con break; case DescriptorRole::GuestImages: physical.guestDescriptor = GuestImagesDescriptor(logical.resources, snapshot); + physical.imageShape = ImageShapeFor(program.Info().images, logical.resources); break; case DescriptorRole::GuestSamplers: physical.guestDescriptor = GuestSamplersDescriptor(logical.resources, snapshot); diff --git a/core/shader/recompiler/Recompiler.hpp b/core/shader/recompiler/Recompiler.hpp index 659a5664d..74c3b8856 100644 --- a/core/shader/recompiler/Recompiler.hpp +++ b/core/shader/recompiler/Recompiler.hpp @@ -210,6 +210,14 @@ enum class DescriptorKind { Sampler }; +enum class DescriptorImageShape { + Image1D, + Image2D, + Image2DArray, + ImageCube, + Image3D +}; + enum class DescriptorRole { GuestBuffers, GuestImages, @@ -229,6 +237,7 @@ struct DescriptorBinding { std::uint32_t count; std::vector guestDescriptor; bool readOnly = false; + std::optional imageShape; }; struct VertexAttribute {