early-access version 3973

This commit is contained in:
pineappleEA 2023-11-12 23:16:19 +01:00
parent 16a6230063
commit c434e00765
8 changed files with 60 additions and 31 deletions

View File

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 3972. This is the source code for early-access 3973.
## Legal Notice ## Legal Notice

View File

@ -196,36 +196,44 @@ Id Texture(EmitContext& ctx, IR::TextureInstInfo info, [[maybe_unused]] const IR
} }
Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& index) { Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& index) {
if (!index.IsImmediate() || index.U32() != 0) {
throw NotImplementedException("Indirect image indexing");
}
if (info.type == TextureType::Buffer) { if (info.type == TextureType::Buffer) {
const TextureBufferDefinition& def{ctx.texture_buffers.at(info.descriptor_index)}; const TextureBufferDefinition& def{ctx.texture_buffers.at(info.descriptor_index)};
if (def.count > 1) { if (def.count > 1) {
throw NotImplementedException("Indirect texture sample"); const Id buffer_pointer{ctx.OpAccessChain(def.pointer_type, def.id, ctx.Def(index))};
} return ctx.OpLoad(ctx.image_buffer_type, buffer_pointer);
} else {
return ctx.OpLoad(ctx.image_buffer_type, def.id); return ctx.OpLoad(ctx.image_buffer_type, def.id);
}
} else { } else {
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)}; const TextureDefinition& def{ctx.textures.at(info.descriptor_index)};
if (def.count > 1) { if (def.count > 1) {
throw NotImplementedException("Indirect texture sample"); const Id texture_pointer{ctx.OpAccessChain(def.pointer_type, def.id, ctx.Def(index))};
} return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, texture_pointer));
} else {
return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, def.id)); return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, def.id));
} }
} }
}
Id Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) { Id Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) {
if (!index.IsImmediate() || index.U32() != 0) {
throw NotImplementedException("Indirect image indexing");
}
if (info.type == TextureType::Buffer) { if (info.type == TextureType::Buffer) {
const ImageBufferDefinition def{ctx.image_buffers.at(info.descriptor_index)}; const ImageBufferDefinition def{ctx.image_buffers.at(info.descriptor_index)};
if (def.count > 1) {
const Id image_pointer{ctx.OpAccessChain(def.pointer_type, def.id, ctx.Def(index))};
return ctx.OpLoad(def.image_type, image_pointer);
} else {
return ctx.OpLoad(def.image_type, def.id); return ctx.OpLoad(def.image_type, def.id);
}
} else { } else {
const ImageDefinition def{ctx.images.at(info.descriptor_index)}; const ImageDefinition def{ctx.images.at(info.descriptor_index)};
if (def.count > 1) {
const Id image_pointer{ctx.OpAccessChain(def.pointer_type, def.id, ctx.Def(index))};
return ctx.OpLoad(def.image_type, image_pointer);
} else {
return ctx.OpLoad(def.image_type, def.id); return ctx.OpLoad(def.image_type, def.id);
} }
} }
}
bool IsTextureMsaa(EmitContext& ctx, const IR::TextureInstInfo& info) { bool IsTextureMsaa(EmitContext& ctx, const IR::TextureInstInfo& info) {
if (info.type == TextureType::Buffer) { if (info.type == TextureType::Buffer) {

View File

@ -7,15 +7,23 @@
namespace Shader::Backend::SPIRV { namespace Shader::Backend::SPIRV {
namespace { namespace {
Id Image(EmitContext& ctx, IR::TextureInstInfo info) { Id ImagePointer(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) {
if (info.type == TextureType::Buffer) { if (info.type == TextureType::Buffer) {
const ImageBufferDefinition def{ctx.image_buffers.at(info.descriptor_index)}; const ImageBufferDefinition def{ctx.image_buffers.at(info.descriptor_index)};
if (def.count > 1) {
return ctx.OpAccessChain(def.pointer_type, def.id, ctx.Def(index));
} else {
return def.id; return def.id;
}
} else { } else {
const ImageDefinition def{ctx.images.at(info.descriptor_index)}; const ImageDefinition def{ctx.images.at(info.descriptor_index)};
if (def.count > 1) {
return ctx.OpAccessChain(def.pointer_type, def.id, ctx.Def(index));
} else {
return def.id; return def.id;
} }
} }
}
std::pair<Id, Id> AtomicArgs(EmitContext& ctx) { std::pair<Id, Id> AtomicArgs(EmitContext& ctx) {
const Id scope{ctx.Const(static_cast<u32>(spv::Scope::Device))}; const Id scope{ctx.Const(static_cast<u32>(spv::Scope::Device))};
@ -25,15 +33,12 @@ std::pair<Id, Id> AtomicArgs(EmitContext& ctx) {
Id ImageAtomicU32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id value, Id ImageAtomicU32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id value,
Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) { Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) {
if (!index.IsImmediate() || index.U32() != 0) {
// TODO: handle layers
throw NotImplementedException("Image indexing");
}
const auto info{inst->Flags<IR::TextureInstInfo>()}; const auto info{inst->Flags<IR::TextureInstInfo>()};
const Id image{Image(ctx, info)}; const Id image_pointer{ImagePointer(ctx, index, info)};
const Id pointer{ctx.OpImageTexelPointer(ctx.image_u32, image, coords, ctx.Const(0U))}; const Id texel_pointer{
ctx.OpImageTexelPointer(ctx.image_u32, image_pointer, coords, ctx.Const(0U))};
const auto [scope, semantics]{AtomicArgs(ctx)}; const auto [scope, semantics]{AtomicArgs(ctx)};
return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics, value); return (ctx.*atomic_func)(ctx.U32[1], texel_pointer, scope, semantics, value);
} }
} // Anonymous namespace } // Anonymous namespace

View File

@ -1243,18 +1243,20 @@ void EmitContext::DefineTextureBuffers(const Info& info, u32& binding) {
const spv::ImageFormat format{spv::ImageFormat::Unknown}; const spv::ImageFormat format{spv::ImageFormat::Unknown};
image_buffer_type = TypeImage(F32[1], spv::Dim::Buffer, 0U, false, false, 1, format); image_buffer_type = TypeImage(F32[1], spv::Dim::Buffer, 0U, false, false, 1, format);
const Id type{TypePointer(spv::StorageClass::UniformConstant, image_buffer_type)}; const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_buffer_type)};
texture_buffers.reserve(info.texture_buffer_descriptors.size()); texture_buffers.reserve(info.texture_buffer_descriptors.size());
for (const TextureBufferDescriptor& desc : info.texture_buffer_descriptors) { for (const TextureBufferDescriptor& desc : info.texture_buffer_descriptors) {
if (desc.count != 1) { if (desc.count != 1) {
throw NotImplementedException("Array of texture buffers"); LOG_WARNING(Shader_SPIRV, "Array of texture buffers");
} }
const Id id{AddGlobalVariable(type, spv::StorageClass::UniformConstant)}; const Id desc_type{DescType(*this, image_buffer_type, pointer_type, desc.count)};
const Id id{AddGlobalVariable(desc_type, spv::StorageClass::UniformConstant)};
Decorate(id, spv::Decoration::Binding, binding); Decorate(id, spv::Decoration::Binding, binding);
Decorate(id, spv::Decoration::DescriptorSet, 0U); Decorate(id, spv::Decoration::DescriptorSet, 0U);
Name(id, NameOf(stage, desc, "texbuf")); Name(id, NameOf(stage, desc, "texbuf"));
texture_buffers.push_back({ texture_buffers.push_back({
.id = id, .id = id,
.pointer_type = pointer_type,
.count = desc.count, .count = desc.count,
}); });
if (profile.supported_spirv >= 0x00010400) { if (profile.supported_spirv >= 0x00010400) {
@ -1268,7 +1270,7 @@ void EmitContext::DefineImageBuffers(const Info& info, u32& binding) {
image_buffers.reserve(info.image_buffer_descriptors.size()); image_buffers.reserve(info.image_buffer_descriptors.size());
for (const ImageBufferDescriptor& desc : info.image_buffer_descriptors) { for (const ImageBufferDescriptor& desc : info.image_buffer_descriptors) {
if (desc.count != 1) { if (desc.count != 1) {
throw NotImplementedException("Array of image buffers"); LOG_WARNING(Shader_SPIRV, "Array of image buffers");
} }
const spv::ImageFormat format{GetImageFormat(desc.format)}; const spv::ImageFormat format{GetImageFormat(desc.format)};
const Id image_type{TypeImage(U32[1], spv::Dim::Buffer, false, false, false, 2, format)}; const Id image_type{TypeImage(U32[1], spv::Dim::Buffer, false, false, false, 2, format)};
@ -1280,6 +1282,7 @@ void EmitContext::DefineImageBuffers(const Info& info, u32& binding) {
image_buffers.push_back({ image_buffers.push_back({
.id = id, .id = id,
.image_type = image_type, .image_type = image_type,
.pointer_type = pointer_type,
.count = desc.count, .count = desc.count,
}); });
if (profile.supported_spirv >= 0x00010400) { if (profile.supported_spirv >= 0x00010400) {
@ -1323,17 +1326,19 @@ void EmitContext::DefineImages(const Info& info, u32& binding, u32& scaling_inde
images.reserve(info.image_descriptors.size()); images.reserve(info.image_descriptors.size());
for (const ImageDescriptor& desc : info.image_descriptors) { for (const ImageDescriptor& desc : info.image_descriptors) {
if (desc.count != 1) { if (desc.count != 1) {
throw NotImplementedException("Array of images"); LOG_WARNING(Shader_SPIRV, "Array of images");
} }
const Id image_type{ImageType(*this, desc)}; const Id image_type{ImageType(*this, desc)};
const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_type)}; const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_type)};
const Id id{AddGlobalVariable(pointer_type, spv::StorageClass::UniformConstant)}; const Id desc_type{DescType(*this, image_type, pointer_type, desc.count)};
const Id id{AddGlobalVariable(desc_type, spv::StorageClass::UniformConstant)};
Decorate(id, spv::Decoration::Binding, binding); Decorate(id, spv::Decoration::Binding, binding);
Decorate(id, spv::Decoration::DescriptorSet, 0U); Decorate(id, spv::Decoration::DescriptorSet, 0U);
Name(id, NameOf(stage, desc, "img")); Name(id, NameOf(stage, desc, "img"));
images.push_back({ images.push_back({
.id = id, .id = id,
.image_type = image_type, .image_type = image_type,
.pointer_type = pointer_type,
.count = desc.count, .count = desc.count,
}); });
if (profile.supported_spirv >= 0x00010400) { if (profile.supported_spirv >= 0x00010400) {

View File

@ -40,18 +40,21 @@ struct TextureDefinition {
struct TextureBufferDefinition { struct TextureBufferDefinition {
Id id; Id id;
Id pointer_type;
u32 count; u32 count;
}; };
struct ImageBufferDefinition { struct ImageBufferDefinition {
Id id; Id id;
Id image_type; Id image_type;
Id pointer_type;
u32 count; u32 count;
}; };
struct ImageDefinition { struct ImageDefinition {
Id id; Id id;
Id image_type; Id image_type;
Id pointer_type;
u32 count; u32 count;
}; };

View File

@ -555,7 +555,7 @@ void RasterizerOpenGL::OnCacheInvalidation(VAddr addr, u64 size) {
} }
{ {
std::scoped_lock lock{buffer_cache.mutex}; std::scoped_lock lock{buffer_cache.mutex};
buffer_cache.CachedWriteMemory(addr, size); buffer_cache.WriteMemory(addr, size);
} }
shader_cache.InvalidateRegion(addr, size); shader_cache.InvalidateRegion(addr, size);
} }

View File

@ -621,7 +621,7 @@ void RasterizerVulkan::OnCacheInvalidation(VAddr addr, u64 size) {
} }
{ {
std::scoped_lock lock{buffer_cache.mutex}; std::scoped_lock lock{buffer_cache.mutex};
buffer_cache.CachedWriteMemory(addr, size); buffer_cache.WriteMemory(addr, size);
} }
pipeline_cache.InvalidateRegion(addr, size); pipeline_cache.InvalidateRegion(addr, size);
} }

View File

@ -222,6 +222,14 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se
const u64 signal_value = master_semaphore->NextTick(); const u64 signal_value = master_semaphore->NextTick();
RecordWithUploadBuffer([signal_semaphore, wait_semaphore, signal_value, RecordWithUploadBuffer([signal_semaphore, wait_semaphore, signal_value,
this](vk::CommandBuffer cmdbuf, vk::CommandBuffer upload_cmdbuf) { this](vk::CommandBuffer cmdbuf, vk::CommandBuffer upload_cmdbuf) {
static constexpr VkMemoryBarrier WRITE_BARRIER{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
};
upload_cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER);
upload_cmdbuf.End(); upload_cmdbuf.End();
cmdbuf.End(); cmdbuf.End();