mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-22 04:24:44 +00:00
added support for cubemap arrays
This commit is contained in:
parent
223a7e4eef
commit
0c7fa82c02
12 changed files with 42 additions and 25 deletions
|
@ -510,7 +510,8 @@ Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) {
|
|||
case AmdGpu::ImageType::Color3D:
|
||||
return ctx.TypeImage(sampled_type, spv::Dim::Dim3D, false, false, false, sampled, format);
|
||||
case AmdGpu::ImageType::Cube:
|
||||
return ctx.TypeImage(sampled_type, spv::Dim::Cube, false, false, false, sampled, format);
|
||||
return ctx.TypeImage(sampled_type, spv::Dim::Cube, false, desc.is_array, false, sampled,
|
||||
format);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1032,6 +1032,7 @@ void GcnDecodeContext::decodeInstructionMIMG(uint64_t hexInstruction) {
|
|||
|
||||
m_instruction.control.mimg = *reinterpret_cast<InstControlMIMG*>(&hexInstruction);
|
||||
m_instruction.control.mimg.mod = getMimgModifier(m_instruction.opcode);
|
||||
ASSERT(m_instruction.control.mimg.r128 == 0);
|
||||
}
|
||||
|
||||
void GcnDecodeContext::decodeInstructionDS(uint64_t hexInstruction) {
|
||||
|
|
|
@ -546,6 +546,7 @@ void Translator::IMAGE_SAMPLE(const GcnInst& inst) {
|
|||
info.has_offset.Assign(flags.test(MimgModifier::Offset));
|
||||
info.explicit_lod.Assign(explicit_lod);
|
||||
info.has_derivatives.Assign(has_derivatives);
|
||||
info.is_array.Assign(mimg.da);
|
||||
|
||||
// Issue IR instruction, leaving unknown fields blank to patch later.
|
||||
const IR::Value texel = [&]() -> IR::Value {
|
||||
|
@ -630,6 +631,7 @@ void Translator::IMAGE_GATHER(const GcnInst& inst) {
|
|||
info.has_offset.Assign(flags.test(MimgModifier::Offset));
|
||||
// info.explicit_lod.Assign(explicit_lod);
|
||||
info.gather_comp.Assign(std::bit_width(mimg.dmask) - 1);
|
||||
info.is_array.Assign(mimg.da);
|
||||
|
||||
// Issue IR instruction, leaving unknown fields blank to patch later.
|
||||
const IR::Value texel = [&]() -> IR::Value {
|
||||
|
|
|
@ -64,9 +64,10 @@ struct ImageResource {
|
|||
u32 dword_offset;
|
||||
AmdGpu::ImageType type;
|
||||
AmdGpu::NumberFormat nfmt;
|
||||
bool is_storage;
|
||||
bool is_depth;
|
||||
bool is_storage{};
|
||||
bool is_depth{};
|
||||
bool is_atomic{};
|
||||
bool is_array{};
|
||||
|
||||
constexpr AmdGpu::Image GetSharp(const Info& info) const noexcept;
|
||||
};
|
||||
|
|
|
@ -491,6 +491,7 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
|
|||
.is_storage = is_storage,
|
||||
.is_depth = bool(inst_info.is_depth),
|
||||
.is_atomic = IsImageAtomicInstruction(inst),
|
||||
.is_array = bool(inst_info.is_array),
|
||||
});
|
||||
|
||||
// Read sampler sharp. This doesn't exist for IMAGE_LOAD/IMAGE_STORE instructions
|
||||
|
|
|
@ -59,6 +59,7 @@ union TextureInstInfo {
|
|||
BitField<5, 1, u32> has_offset;
|
||||
BitField<6, 2, u32> gather_comp;
|
||||
BitField<8, 1, u32> has_derivatives;
|
||||
BitField<9, 1, u32> is_array;
|
||||
};
|
||||
|
||||
union BufferInstInfo {
|
||||
|
|
|
@ -282,6 +282,7 @@ bool Instance::CreateDevice() {
|
|||
vk::PhysicalDeviceFeatures2{
|
||||
.features{
|
||||
.robustBufferAccess = features.robustBufferAccess,
|
||||
.imageCubeArray = features.imageCubeArray,
|
||||
.independentBlend = features.independentBlend,
|
||||
.geometryShader = features.geometryShader,
|
||||
.logicOp = features.logicOp,
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <boost/container/static_vector.hpp>
|
||||
|
||||
#include "shader_recompiler/info.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
#include "video_core/renderer_vulkan/vk_pipeline_common.h"
|
||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||
|
@ -21,7 +22,7 @@ Pipeline::~Pipeline() = default;
|
|||
void Pipeline::BindTextures(VideoCore::TextureCache& texture_cache, const Shader::Info& stage,
|
||||
u32& binding, DescriptorWrites& set_writes) const {
|
||||
|
||||
using ImageBindingInfo = std::tuple<VideoCore::ImageId, AmdGpu::Image, bool>;
|
||||
using ImageBindingInfo = std::tuple<VideoCore::ImageId, AmdGpu::Image, Shader::ImageResource>;
|
||||
boost::container::static_vector<ImageBindingInfo, 32> image_bindings;
|
||||
|
||||
for (const auto& image_desc : stage.images) {
|
||||
|
@ -31,9 +32,9 @@ void Pipeline::BindTextures(VideoCore::TextureCache& texture_cache, const Shader
|
|||
const auto image_id = texture_cache.FindImage(image_info);
|
||||
auto& image = texture_cache.GetImage(image_id);
|
||||
image.flags |= VideoCore::ImageFlagBits::Bound;
|
||||
image_bindings.emplace_back(image_id, tsharp, image_desc.is_storage);
|
||||
image_bindings.emplace_back(image_id, tsharp, image_desc);
|
||||
} else {
|
||||
image_bindings.emplace_back(VideoCore::ImageId{}, tsharp, image_desc.is_storage);
|
||||
image_bindings.emplace_back(VideoCore::ImageId{}, tsharp, image_desc);
|
||||
}
|
||||
|
||||
if (texture_cache.IsMeta(tsharp.Address())) {
|
||||
|
@ -42,7 +43,7 @@ void Pipeline::BindTextures(VideoCore::TextureCache& texture_cache, const Shader
|
|||
}
|
||||
|
||||
// Second pass to re-bind images that were updated after binding
|
||||
for (auto [image_id, tsharp, is_storage] : image_bindings) {
|
||||
for (auto [image_id, tsharp, desc] : image_bindings) {
|
||||
if (!image_id) {
|
||||
if (instance.IsNullDescriptorSupported()) {
|
||||
image_infos.emplace_back(VK_NULL_HANDLE, VK_NULL_HANDLE, vk::ImageLayout::eGeneral);
|
||||
|
@ -56,7 +57,7 @@ void Pipeline::BindTextures(VideoCore::TextureCache& texture_cache, const Shader
|
|||
if (True(image.flags & VideoCore::ImageFlagBits::NeedsRebind)) {
|
||||
image_id = texture_cache.FindImage(image.info);
|
||||
}
|
||||
VideoCore::ImageViewInfo view_info{tsharp, is_storage};
|
||||
VideoCore::ImageViewInfo view_info{tsharp, desc};
|
||||
auto& image_view = texture_cache.FindTexture(image_id, view_info);
|
||||
image_infos.emplace_back(VK_NULL_HANDLE, *image_view.image_view,
|
||||
texture_cache.GetImage(image_id).last_state.layout);
|
||||
|
@ -69,8 +70,8 @@ void Pipeline::BindTextures(VideoCore::TextureCache& texture_cache, const Shader
|
|||
.dstBinding = binding++,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType =
|
||||
is_storage ? vk::DescriptorType::eStorageImage : vk::DescriptorType::eSampledImage,
|
||||
.descriptorType = desc.is_storage ? vk::DescriptorType::eStorageImage
|
||||
: vk::DescriptorType::eSampledImage,
|
||||
.pImageInfo = &image_infos.back(),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback(
|
|||
case 0xc81ad50e:
|
||||
case 0xb7c39078:
|
||||
case 0x32868fde: // vkCreateBufferView(): pCreateInfo->range does not equal VK_WHOLE_SIZE
|
||||
case 0x92d66fc1: // `pMultisampleState is NULL` for depth only passes (confirmed VL error)
|
||||
return VK_FALSE;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -200,11 +200,13 @@ boost::container::small_vector<vk::ImageMemoryBarrier2, 32> Image::GetBarriers(
|
|||
// resource transition for the next time.
|
||||
const auto mips =
|
||||
needs_partial_transition
|
||||
? std::ranges::views::iota(subres_range->base.level, subres_range->extent.levels)
|
||||
? std::ranges::views::iota(subres_range->base.level,
|
||||
subres_range->base.level + subres_range->extent.levels)
|
||||
: std::views::iota(0u, info.resources.levels);
|
||||
const auto layers =
|
||||
needs_partial_transition
|
||||
? std::ranges::views::iota(subres_range->base.layer, subres_range->extent.layers)
|
||||
? std::ranges::views::iota(subres_range->base.layer,
|
||||
subres_range->base.layer + subres_range->extent.layers)
|
||||
: std::views::iota(0u, info.resources.layers);
|
||||
|
||||
for (u32 mip : mips) {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "shader_recompiler/info.h"
|
||||
#include "video_core/amdgpu/resource.h"
|
||||
#include "video_core/renderer_vulkan/liverpool_to_vk.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
|
@ -66,8 +67,8 @@ vk::Format TrySwizzleFormat(vk::Format format, u32 dst_sel) {
|
|||
return format;
|
||||
}
|
||||
|
||||
ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, bool is_storage_) noexcept
|
||||
: is_storage{is_storage_} {
|
||||
ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageResource& desc) noexcept
|
||||
: is_storage{desc.is_storage} {
|
||||
const auto dfmt = image.GetDataFmt();
|
||||
auto nfmt = image.GetNumberFmt();
|
||||
if (is_storage && nfmt == AmdGpu::NumberFormat::Srgb) {
|
||||
|
@ -76,19 +77,24 @@ ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, bool is_storage_) noexc
|
|||
format = Vulkan::LiverpoolToVK::SurfaceFormat(dfmt, nfmt);
|
||||
range.base.level = image.base_level;
|
||||
range.base.layer = image.base_array;
|
||||
range.extent.levels = image.last_level + 1;
|
||||
range.extent.layers = image.last_array + 1;
|
||||
range.extent.levels = image.last_level - image.base_level + 1;
|
||||
range.extent.layers = image.last_array - image.base_array + 1;
|
||||
type = ConvertImageViewType(image.GetType());
|
||||
|
||||
// Adjust view type for partial cubemaps and arrays
|
||||
if (image.IsPartialCubemap()) {
|
||||
type = vk::ImageViewType::e2DArray;
|
||||
}
|
||||
if (type == vk::ImageViewType::eCube && range.extent.layers > 6) {
|
||||
type = vk::ImageViewType::eCubeArray;
|
||||
if (type == vk::ImageViewType::eCube) {
|
||||
if (desc.is_array) {
|
||||
type = vk::ImageViewType::eCubeArray;
|
||||
} else {
|
||||
// Some games try to bind an array of cubemaps while shader reads only single one.
|
||||
range.extent.layers = std::min(range.extent.layers, 6u);
|
||||
}
|
||||
}
|
||||
if (type == vk::ImageViewType::e3D && range.extent.layers > 1) {
|
||||
// Some games pass incorrect layer count for 3D textures so we need to fixup it
|
||||
// Some games pass incorrect layer count for 3D textures so we need to fixup it.
|
||||
range.extent.layers = 1;
|
||||
}
|
||||
|
||||
|
@ -116,7 +122,7 @@ ImageViewInfo::ImageViewInfo(const AmdGpu::Liverpool::ColorBuffer& col_buffer,
|
|||
const auto base_format =
|
||||
Vulkan::LiverpoolToVK::SurfaceFormat(col_buffer.info.format, col_buffer.NumFormat());
|
||||
range.base.layer = col_buffer.view.slice_start;
|
||||
range.extent.layers = col_buffer.NumSlices();
|
||||
range.extent.layers = col_buffer.NumSlices() - range.base.layer;
|
||||
format = Vulkan::LiverpoolToVK::AdjustColorBufferFormat(
|
||||
base_format, col_buffer.info.comp_swap.Value(), is_vo_surface);
|
||||
}
|
||||
|
@ -128,7 +134,7 @@ ImageViewInfo::ImageViewInfo(const AmdGpu::Liverpool::DepthBuffer& depth_buffer,
|
|||
depth_buffer.stencil_info.format);
|
||||
is_storage = ctl.depth_write_enable;
|
||||
range.base.layer = view.slice_start;
|
||||
range.extent.layers = view.NumSlices();
|
||||
range.extent.layers = view.NumSlices() - range.base.layer;
|
||||
}
|
||||
|
||||
ImageView::ImageView(const Vulkan::Instance& instance, const ImageViewInfo& info_, Image& image,
|
||||
|
@ -160,9 +166,9 @@ ImageView::ImageView(const Vulkan::Instance& instance, const ImageViewInfo& info
|
|||
.subresourceRange{
|
||||
.aspectMask = aspect,
|
||||
.baseMipLevel = info.range.base.level,
|
||||
.levelCount = info.range.extent.levels - info.range.base.level,
|
||||
.levelCount = info.range.extent.levels,
|
||||
.baseArrayLayer = info.range.base.layer,
|
||||
.layerCount = info.range.extent.layers - info.range.base.layer,
|
||||
.layerCount = info.range.extent.layers,
|
||||
},
|
||||
};
|
||||
image_view = instance.GetDevice().createImageViewUnique(image_view_ci);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "shader_recompiler/info.h"
|
||||
#include "video_core/amdgpu/liverpool.h"
|
||||
#include "video_core/amdgpu/resource.h"
|
||||
#include "video_core/renderer_vulkan/vk_common.h"
|
||||
|
@ -17,7 +18,7 @@ namespace VideoCore {
|
|||
|
||||
struct ImageViewInfo {
|
||||
ImageViewInfo() = default;
|
||||
ImageViewInfo(const AmdGpu::Image& image, bool is_storage) noexcept;
|
||||
ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageResource& desc) noexcept;
|
||||
ImageViewInfo(const AmdGpu::Liverpool::ColorBuffer& col_buffer, bool is_vo_surface) noexcept;
|
||||
ImageViewInfo(const AmdGpu::Liverpool::DepthBuffer& depth_buffer,
|
||||
AmdGpu::Liverpool::DepthView view, AmdGpu::Liverpool::DepthControl ctl);
|
||||
|
|
Loading…
Add table
Reference in a new issue