early-access version 3973
This commit is contained in:
parent
16a6230063
commit
c434e00765
8 changed files with 60 additions and 31 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -196,34 +196,42 @@ 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)};
|
||||||
return ctx.OpLoad(def.image_type, def.id);
|
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);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const ImageDefinition def{ctx.images.at(info.descriptor_index)};
|
const ImageDefinition def{ctx.images.at(info.descriptor_index)};
|
||||||
return ctx.OpLoad(def.image_type, def.id);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,21 @@
|
||||||
|
|
||||||
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)};
|
||||||
return def.id;
|
if (def.count > 1) {
|
||||||
|
return ctx.OpAccessChain(def.pointer_type, def.id, ctx.Def(index));
|
||||||
|
} else {
|
||||||
|
return def.id;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const ImageDefinition def{ctx.images.at(info.descriptor_index)};
|
const ImageDefinition def{ctx.images.at(info.descriptor_index)};
|
||||||
return def.id;
|
if (def.count > 1) {
|
||||||
|
return ctx.OpAccessChain(def.pointer_type, def.id, ctx.Def(index));
|
||||||
|
} else {
|
||||||
|
return def.id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue