early-access version 3352
This commit is contained in:
parent
3ee566278a
commit
8c756f4f3a
33 changed files with 239 additions and 209 deletions
|
@ -514,7 +514,7 @@ endif()
|
|||
# against all the src files. This should be used before making a pull request.
|
||||
# =======================================================================
|
||||
|
||||
set(CLANG_FORMAT_POSTFIX "-12")
|
||||
set(CLANG_FORMAT_POSTFIX "-15")
|
||||
find_program(CLANG_FORMAT
|
||||
NAMES clang-format${CLANG_FORMAT_POSTFIX}
|
||||
clang-format
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
yuzu emulator early access
|
||||
=============
|
||||
|
||||
This is the source code for early-access 3351.
|
||||
This is the source code for early-access 3352.
|
||||
|
||||
## Legal Notice
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
|
||||
namespace Common {
|
||||
template <typename VaType, size_t AddressSpaceBits>
|
||||
concept AddressSpaceValid = std::is_unsigned_v<VaType> && sizeof(VaType) * 8 >= AddressSpaceBits;
|
||||
concept AddressSpaceValid = std::is_unsigned_v<VaType> && sizeof(VaType) * 8 >=
|
||||
AddressSpaceBits;
|
||||
|
||||
struct EmptyStruct {};
|
||||
|
||||
|
|
|
@ -242,7 +242,9 @@ public:
|
|||
|
||||
template <typename T>
|
||||
concept HasRedBlackKeyType = requires {
|
||||
{ std::is_same<typename T::RedBlackKeyType, void>::value } -> std::convertible_to<bool>;
|
||||
{
|
||||
std::is_same<typename T::RedBlackKeyType, void>::value
|
||||
} -> std::convertible_to<bool>;
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
|
|
@ -9,12 +9,14 @@
|
|||
namespace Common {
|
||||
|
||||
template <class T>
|
||||
requires(!std::is_array_v<T>) std::unique_ptr<T> make_unique_for_overwrite() {
|
||||
requires(!std::is_array_v<T>)
|
||||
std::unique_ptr<T> make_unique_for_overwrite() {
|
||||
return std::unique_ptr<T>(new T);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
requires std::is_unbounded_array_v<T> std::unique_ptr<T> make_unique_for_overwrite(std::size_t n) {
|
||||
requires std::is_unbounded_array_v<T>
|
||||
std::unique_ptr<T> make_unique_for_overwrite(std::size_t n) {
|
||||
return std::unique_ptr<T>(new std::remove_extent_t<T>[n]);
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,8 @@ public:
|
|||
* @param default_val Intial value of the setting, and default value of the setting
|
||||
* @param name Label for the setting
|
||||
*/
|
||||
explicit Setting(const Type& default_val, const std::string& name) requires(!ranged)
|
||||
explicit Setting(const Type& default_val, const std::string& name)
|
||||
requires(!ranged)
|
||||
: value{default_val}, default_value{default_val}, label{name} {}
|
||||
virtual ~Setting() = default;
|
||||
|
||||
|
@ -144,7 +145,8 @@ public:
|
|||
* @param name Label for the setting
|
||||
*/
|
||||
explicit Setting(const Type& default_val, const Type& min_val, const Type& max_val,
|
||||
const std::string& name) requires(ranged)
|
||||
const std::string& name)
|
||||
requires(ranged)
|
||||
: value{default_val},
|
||||
default_value{default_val}, maximum{max_val}, minimum{min_val}, label{name} {}
|
||||
|
||||
|
@ -232,7 +234,8 @@ public:
|
|||
* @param default_val Intial value of the setting, and default value of the setting
|
||||
* @param name Label for the setting
|
||||
*/
|
||||
explicit SwitchableSetting(const Type& default_val, const std::string& name) requires(!ranged)
|
||||
explicit SwitchableSetting(const Type& default_val, const std::string& name)
|
||||
requires(!ranged)
|
||||
: Setting<Type>{default_val, name} {}
|
||||
virtual ~SwitchableSetting() = default;
|
||||
|
||||
|
@ -245,7 +248,8 @@ public:
|
|||
* @param name Label for the setting
|
||||
*/
|
||||
explicit SwitchableSetting(const Type& default_val, const Type& min_val, const Type& max_val,
|
||||
const std::string& name) requires(ranged)
|
||||
const std::string& name)
|
||||
requires(ranged)
|
||||
: Setting<Type, true>{default_val, min_val, max_val, name} {}
|
||||
|
||||
/**
|
||||
|
|
|
@ -348,9 +348,7 @@ public:
|
|||
// _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all
|
||||
// component names (x<->r) and permutations (xy<->yx)
|
||||
#define _DEFINE_SWIZZLER2(a, b, name) \
|
||||
[[nodiscard]] constexpr Vec2<T> name() const { \
|
||||
return Vec2<T>(a, b); \
|
||||
}
|
||||
[[nodiscard]] constexpr Vec2<T> name() const { return Vec2<T>(a, b); }
|
||||
#define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \
|
||||
_DEFINE_SWIZZLER2(a, b, a##b); \
|
||||
_DEFINE_SWIZZLER2(a, b, a2##b2); \
|
||||
|
@ -543,9 +541,7 @@ public:
|
|||
// DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and
|
||||
// permutations (xy<->yx)
|
||||
#define _DEFINE_SWIZZLER2(a, b, name) \
|
||||
[[nodiscard]] constexpr Vec2<T> name() const { \
|
||||
return Vec2<T>(a, b); \
|
||||
}
|
||||
[[nodiscard]] constexpr Vec2<T> name() const { return Vec2<T>(a, b); }
|
||||
#define DEFINE_SWIZZLER2_COMP1(a, a2) \
|
||||
_DEFINE_SWIZZLER2(a, a, a##a); \
|
||||
_DEFINE_SWIZZLER2(a, a, a2##a2)
|
||||
|
@ -570,9 +566,7 @@ public:
|
|||
#undef _DEFINE_SWIZZLER2
|
||||
|
||||
#define _DEFINE_SWIZZLER3(a, b, c, name) \
|
||||
[[nodiscard]] constexpr Vec3<T> name() const { \
|
||||
return Vec3<T>(a, b, c); \
|
||||
}
|
||||
[[nodiscard]] constexpr Vec3<T> name() const { return Vec3<T>(a, b, c); }
|
||||
#define DEFINE_SWIZZLER3_COMP1(a, a2) \
|
||||
_DEFINE_SWIZZLER3(a, a, a, a##a##a); \
|
||||
_DEFINE_SWIZZLER3(a, a, a, a2##a2##a2)
|
||||
|
@ -641,8 +635,8 @@ template <typename T>
|
|||
|
||||
// linear interpolation via float: 0.0=begin, 1.0=end
|
||||
template <typename X>
|
||||
[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{})
|
||||
Lerp(const X& begin, const X& end, const float t) {
|
||||
[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end,
|
||||
const float t) {
|
||||
return begin * (1.f - t) + end * t;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,9 +24,7 @@ private:
|
|||
friend class ::Kernel::KClassTokenGenerator; \
|
||||
static constexpr inline auto ObjectType = ::Kernel::KClassTokenGenerator::ObjectType::CLASS; \
|
||||
static constexpr inline const char* const TypeName = #CLASS; \
|
||||
static constexpr inline ClassTokenType ClassToken() { \
|
||||
return ::Kernel::ClassToken<CLASS>; \
|
||||
} \
|
||||
static constexpr inline ClassTokenType ClassToken() { return ::Kernel::ClassToken<CLASS>; } \
|
||||
\
|
||||
public: \
|
||||
YUZU_NON_COPYABLE(CLASS); \
|
||||
|
@ -37,15 +35,9 @@ public:
|
|||
constexpr ClassTokenType Token = ClassToken(); \
|
||||
return TypeObj(TypeName, Token); \
|
||||
} \
|
||||
static constexpr const char* GetStaticTypeName() { \
|
||||
return TypeName; \
|
||||
} \
|
||||
virtual TypeObj GetTypeObj() ATTRIBUTE { \
|
||||
return GetStaticTypeObj(); \
|
||||
} \
|
||||
virtual const char* GetTypeName() ATTRIBUTE { \
|
||||
return GetStaticTypeName(); \
|
||||
} \
|
||||
static constexpr const char* GetStaticTypeName() { return TypeName; } \
|
||||
virtual TypeObj GetTypeObj() ATTRIBUTE { return GetStaticTypeObj(); } \
|
||||
virtual const char* GetTypeName() ATTRIBUTE { return GetStaticTypeName(); } \
|
||||
\
|
||||
private: \
|
||||
constexpr bool operator!=(const TypeObj& rhs)
|
||||
|
@ -245,8 +237,8 @@ public:
|
|||
}
|
||||
|
||||
template <typename U>
|
||||
requires(std::derived_from<T, U> ||
|
||||
std::derived_from<U, T>) constexpr KScopedAutoObject(KScopedAutoObject<U>&& rhs) {
|
||||
requires(std::derived_from<T, U> || std::derived_from<U, T>)
|
||||
constexpr KScopedAutoObject(KScopedAutoObject<U>&& rhs) {
|
||||
if constexpr (std::derived_from<U, T>) {
|
||||
// Upcast.
|
||||
m_obj = rhs.m_obj;
|
||||
|
|
|
@ -17,7 +17,8 @@ namespace Kernel {
|
|||
class KThread;
|
||||
|
||||
template <typename T>
|
||||
concept KPriorityQueueAffinityMask = !std::is_reference_v<T> && requires(T & t) {
|
||||
concept KPriorityQueueAffinityMask = !
|
||||
std::is_reference_v<T>&& requires(T& t) {
|
||||
{ t.GetAffinityMask() } -> Common::ConvertibleTo<u64>;
|
||||
{ t.SetAffinityMask(0) };
|
||||
|
||||
|
@ -27,17 +28,22 @@ concept KPriorityQueueAffinityMask = !std::is_reference_v<T> && requires(T & t)
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
concept KPriorityQueueMember = !std::is_reference_v<T> && requires(T & t) {
|
||||
concept KPriorityQueueMember = !
|
||||
std::is_reference_v<T>&& requires(T& t) {
|
||||
{ typename T::QueueEntry() };
|
||||
{ (typename T::QueueEntry()).Initialize() };
|
||||
{ (typename T::QueueEntry()).SetPrev(std::addressof(t)) };
|
||||
{ (typename T::QueueEntry()).SetNext(std::addressof(t)) };
|
||||
{ (typename T::QueueEntry()).GetNext() } -> std::same_as<T*>;
|
||||
{ (typename T::QueueEntry()).GetPrev() } -> std::same_as<T*>;
|
||||
{ t.GetPriorityQueueEntry(0) } -> std::same_as<typename T::QueueEntry&>;
|
||||
{
|
||||
t.GetPriorityQueueEntry(0)
|
||||
} -> std::same_as<typename T::QueueEntry&>;
|
||||
|
||||
{ t.GetAffinityMask() };
|
||||
{ std::remove_cvref_t<decltype(t.GetAffinityMask())>() } -> KPriorityQueueAffinityMask;
|
||||
{
|
||||
std::remove_cvref_t<decltype(t.GetAffinityMask())>()
|
||||
} -> KPriorityQueueAffinityMask;
|
||||
|
||||
{ t.GetActiveCore() } -> Common::ConvertibleTo<s32>;
|
||||
{ t.GetPriority() } -> Common::ConvertibleTo<s32>;
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
namespace Kernel {
|
||||
|
||||
template <typename T>
|
||||
concept KLockable = !std::is_reference_v<T> && requires(T & t) {
|
||||
concept KLockable = !
|
||||
std::is_reference_v<T>&& requires(T& t) {
|
||||
{ t.Lock() } -> std::same_as<void>;
|
||||
{ t.Unlock() } -> std::same_as<void>;
|
||||
};
|
||||
|
|
|
@ -698,10 +698,8 @@ private:
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
requires(
|
||||
std::same_as<T, KThread> ||
|
||||
std::same_as<T, RedBlackKeyType>) static constexpr int Compare(const T& lhs,
|
||||
const KThread& rhs) {
|
||||
requires(std::same_as<T, KThread> || std::same_as<T, RedBlackKeyType>)
|
||||
static constexpr int Compare(const T& lhs, const KThread& rhs) {
|
||||
const u64 l_key = lhs.GetConditionVariableKey();
|
||||
const u64 r_key = rhs.GetConditionVariableKey();
|
||||
|
||||
|
|
|
@ -70,10 +70,8 @@ public:
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
requires(std::same_as<T, KThreadLocalPage> ||
|
||||
std::same_as<T, RedBlackKeyType>) static constexpr int Compare(const T& lhs,
|
||||
const KThreadLocalPage&
|
||||
rhs) {
|
||||
requires(std::same_as<T, KThreadLocalPage> || std::same_as<T, RedBlackKeyType>)
|
||||
static constexpr int Compare(const T& lhs, const KThreadLocalPage& rhs) {
|
||||
const VAddr lval = GetRedBlackKey(lhs);
|
||||
const VAddr rval = GetRedBlackKey(rhs);
|
||||
|
||||
|
|
|
@ -60,7 +60,8 @@ public:
|
|||
DriverResult SendRawData(std::span<const u8> buffer);
|
||||
|
||||
template <typename Output>
|
||||
requires std::is_trivially_copyable_v<Output> DriverResult SendData(const Output& output) {
|
||||
requires std::is_trivially_copyable_v<Output>
|
||||
DriverResult SendData(const Output& output) {
|
||||
std::array<u8, sizeof(Output)> buffer;
|
||||
std::memcpy(buffer.data(), &output, sizeof(Output));
|
||||
return SendRawData(buffer);
|
||||
|
@ -115,8 +116,8 @@ public:
|
|||
* @returns output object containing the response
|
||||
*/
|
||||
template <typename Output>
|
||||
requires std::is_trivially_copyable_v<Output> DriverResult ReadSPI(SpiAddress addr,
|
||||
Output& output) {
|
||||
requires std::is_trivially_copyable_v<Output>
|
||||
DriverResult ReadSPI(SpiAddress addr, Output& output) {
|
||||
std::array<u8, sizeof(Output)> buffer;
|
||||
output = {};
|
||||
|
||||
|
|
|
@ -59,6 +59,13 @@ std::string Image(EmitContext& ctx, IR::TextureInstInfo info,
|
|||
}
|
||||
}
|
||||
|
||||
bool IsTextureMsaa(EmitContext& ctx, const IR::TextureInstInfo& info) {
|
||||
if (info.type == TextureType::Buffer) {
|
||||
return false;
|
||||
}
|
||||
return ctx.info.texture_descriptors.at(info.descriptor_index).is_multisample;
|
||||
}
|
||||
|
||||
std::string_view TextureType(IR::TextureInstInfo info, bool is_ms = false) {
|
||||
if (info.is_depth) {
|
||||
switch (info.type) {
|
||||
|
@ -535,7 +542,8 @@ void EmitImageQueryDimensions(EmitContext& ctx, IR::Inst& inst, const IR::Value&
|
|||
ScalarS32 lod, [[maybe_unused]] const IR::Value& skip_mips) {
|
||||
const auto info{inst.Flags<IR::TextureInstInfo>()};
|
||||
const std::string texture{Texture(ctx, info, index)};
|
||||
const std::string_view type{TextureType(info)};
|
||||
const bool is_msaa{IsTextureMsaa(ctx, info)};
|
||||
const std::string_view type{TextureType(info, is_msaa)};
|
||||
ctx.Add("TXQ {},{},{},{};", inst, lod, texture, type);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,13 @@ std::string Image(EmitContext& ctx, const IR::TextureInstInfo& info, const IR::V
|
|||
return fmt::format("img{}{}", def.binding, index_offset);
|
||||
}
|
||||
|
||||
bool IsTextureMsaa(EmitContext& ctx, const IR::TextureInstInfo& info) {
|
||||
if (info.type == TextureType::Buffer) {
|
||||
return false;
|
||||
}
|
||||
return ctx.info.texture_descriptors.at(info.descriptor_index).is_multisample;
|
||||
}
|
||||
|
||||
std::string CastToIntVec(std::string_view value, const IR::TextureInstInfo& info) {
|
||||
switch (info.type) {
|
||||
case TextureType::Color1D:
|
||||
|
@ -463,26 +470,33 @@ void EmitImageQueryDimensions(EmitContext& ctx, IR::Inst& inst, const IR::Value&
|
|||
std::string_view lod, const IR::Value& skip_mips_val) {
|
||||
const auto info{inst.Flags<IR::TextureInstInfo>()};
|
||||
const auto texture{Texture(ctx, info, index)};
|
||||
const bool is_msaa{IsTextureMsaa(ctx, info)};
|
||||
const bool skip_mips{skip_mips_val.U1()};
|
||||
const auto mips{
|
||||
[&] { return skip_mips ? "0u" : fmt::format("uint(textureQueryLevels({}))", texture); }};
|
||||
const auto mips{skip_mips ? "0u" : fmt::format("uint(textureQueryLevels({}))", texture)};
|
||||
if (is_msaa && !skip_mips) {
|
||||
throw NotImplementedException("EmitImageQueryDimensions MSAA QueryLevels");
|
||||
}
|
||||
if (info.type == TextureType::Buffer && !skip_mips) {
|
||||
throw NotImplementedException("EmitImageQueryDimensions TextureType::Buffer QueryLevels");
|
||||
}
|
||||
const bool uses_lod{!is_msaa && info.type != TextureType::Buffer};
|
||||
const auto lod_str{uses_lod ? fmt::format(",int({})", lod) : ""};
|
||||
switch (info.type) {
|
||||
case TextureType::Color1D:
|
||||
return ctx.AddU32x4("{}=uvec4(uint(textureSize({},int({}))),0u,0u,{});", inst, texture, lod,
|
||||
mips());
|
||||
return ctx.AddU32x4("{}=uvec4(uint(textureSize({}{})),0u,0u,{});", inst, texture, lod_str,
|
||||
mips);
|
||||
case TextureType::ColorArray1D:
|
||||
case TextureType::Color2D:
|
||||
case TextureType::ColorCube:
|
||||
case TextureType::Color2DRect:
|
||||
return ctx.AddU32x4("{}=uvec4(uvec2(textureSize({},int({}))),0u,{});", inst, texture, lod,
|
||||
mips());
|
||||
return ctx.AddU32x4("{}=uvec4(uvec2(textureSize({}{})),0u,{});", inst, texture, lod_str,
|
||||
mips);
|
||||
case TextureType::ColorArray2D:
|
||||
case TextureType::Color3D:
|
||||
case TextureType::ColorArrayCube:
|
||||
return ctx.AddU32x4("{}=uvec4(uvec3(textureSize({},int({}))),{});", inst, texture, lod,
|
||||
mips());
|
||||
return ctx.AddU32x4("{}=uvec4(uvec3(textureSize({}{})),{});", inst, texture, lod_str, mips);
|
||||
case TextureType::Buffer:
|
||||
throw NotImplementedException("EmitImageQueryDimensions Texture buffers");
|
||||
return ctx.AddU32x4("{}=uvec4(uint(textureSize({})),0u,0u,{});", inst, texture, mips);
|
||||
}
|
||||
throw LogicError("Unspecified image type {}", info.type.Value());
|
||||
}
|
||||
|
|
|
@ -201,6 +201,13 @@ Id Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) {
|
|||
}
|
||||
}
|
||||
|
||||
bool IsTextureMsaa(EmitContext& ctx, const IR::TextureInstInfo& info) {
|
||||
if (info.type == TextureType::Buffer) {
|
||||
return false;
|
||||
}
|
||||
return ctx.textures.at(info.descriptor_index).is_multisample;
|
||||
}
|
||||
|
||||
Id Decorate(EmitContext& ctx, IR::Inst* inst, Id sample) {
|
||||
const auto info{inst->Flags<IR::TextureInstInfo>()};
|
||||
if (info.relaxed_precision != 0) {
|
||||
|
@ -452,24 +459,26 @@ Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& i
|
|||
const Id zero{ctx.u32_zero_value};
|
||||
const bool skip_mips{skip_mips_val.U1()};
|
||||
const auto mips{[&] { return skip_mips ? zero : ctx.OpImageQueryLevels(ctx.U32[1], image); }};
|
||||
const bool is_msaa{IsTextureMsaa(ctx, info)};
|
||||
const bool uses_lod{!is_msaa && info.type != TextureType::Buffer};
|
||||
const auto query{[&](Id type) {
|
||||
return uses_lod ? ctx.OpImageQuerySizeLod(type, image, lod)
|
||||
: ctx.OpImageQuerySize(type, image);
|
||||
}};
|
||||
switch (info.type) {
|
||||
case TextureType::Color1D:
|
||||
return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[1], image, lod),
|
||||
zero, zero, mips());
|
||||
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[1]), zero, zero, mips());
|
||||
case TextureType::ColorArray1D:
|
||||
case TextureType::Color2D:
|
||||
case TextureType::ColorCube:
|
||||
case TextureType::Color2DRect:
|
||||
return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[2], image, lod),
|
||||
zero, mips());
|
||||
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[2]), zero, mips());
|
||||
case TextureType::ColorArray2D:
|
||||
case TextureType::Color3D:
|
||||
case TextureType::ColorArrayCube:
|
||||
return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[3], image, lod),
|
||||
mips());
|
||||
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[3]), mips());
|
||||
case TextureType::Buffer:
|
||||
return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySize(ctx.U32[1], image), zero,
|
||||
zero, mips());
|
||||
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[1]), zero, zero, mips());
|
||||
}
|
||||
throw LogicError("Unspecified image type {}", info.type.Value());
|
||||
}
|
||||
|
|
|
@ -1288,6 +1288,7 @@ void EmitContext::DefineTextures(const Info& info, u32& binding, u32& scaling_in
|
|||
.pointer_type = pointer_type,
|
||||
.image_type = image_type,
|
||||
.count = desc.count,
|
||||
.is_multisample = desc.is_multisample,
|
||||
});
|
||||
if (profile.supported_spirv >= 0x00010400) {
|
||||
interfaces.push_back(id);
|
||||
|
|
|
@ -35,6 +35,7 @@ struct TextureDefinition {
|
|||
Id pointer_type;
|
||||
Id image_type;
|
||||
u32 count;
|
||||
bool is_multisample;
|
||||
};
|
||||
|
||||
struct TextureBufferDefinition {
|
||||
|
|
|
@ -409,7 +409,8 @@ private:
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
requires(sizeof(T) <= sizeof(u32) && std::is_trivially_copyable_v<T>) struct Flags {
|
||||
requires(sizeof(T) <= sizeof(u32) && std::is_trivially_copyable_v<T>)
|
||||
struct Flags {
|
||||
Flags() = default;
|
||||
Flags(T proxy_) : proxy{proxy_} {}
|
||||
|
||||
|
|
|
@ -101,9 +101,8 @@ public:
|
|||
TypedValue() = default;
|
||||
|
||||
template <IR::Type other_type>
|
||||
requires((other_type & type_) != IR::Type::Void) explicit(false)
|
||||
TypedValue(const TypedValue<other_type>& value)
|
||||
: Value(value) {}
|
||||
requires((other_type & type_) != IR::Type::Void)
|
||||
explicit(false) TypedValue(const TypedValue<other_type>& value) : Value(value) {}
|
||||
|
||||
explicit TypedValue(const Value& value) : Value(value) {
|
||||
if ((value.Type() & type_) == IR::Type::Void) {
|
||||
|
@ -202,8 +201,8 @@ public:
|
|||
}
|
||||
|
||||
template <typename FlagsType>
|
||||
requires(sizeof(FlagsType) <= sizeof(u32) &&
|
||||
std::is_trivially_copyable_v<FlagsType>) void SetFlags(FlagsType value) noexcept {
|
||||
requires(sizeof(FlagsType) <= sizeof(u32) && std::is_trivially_copyable_v<FlagsType>)
|
||||
void SetFlags(FlagsType value) noexcept {
|
||||
std::memcpy(&flags, &value, sizeof(value));
|
||||
}
|
||||
|
||||
|
|
|
@ -19,9 +19,7 @@ public:
|
|||
explicit DescriptorTable(Tegra::MemoryManager& gpu_memory_) : gpu_memory{gpu_memory_} {}
|
||||
|
||||
[[nodiscard]] bool Synchronize(GPUVAddr gpu_addr, u32 limit) {
|
||||
[[likely]] if (current_gpu_addr == gpu_addr && current_limit == limit) {
|
||||
return false;
|
||||
}
|
||||
[[likely]] if (current_gpu_addr == gpu_addr && current_limit == limit) { return false; }
|
||||
Refresh(gpu_addr, limit);
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue