mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-07-10 02:04:42 -06:00
Fontlib implemment stubs for knack2 (#4564)
* Improve spec-correct V_CMP_U64 semantics * Clang-format * - implement libSceFont text-source, string, and writing object support - add OrbisFontTextSource, OrbisFontCreateStringDetail, OrbisFontString, and writing-related ABI structures and function declarations - implement font string lifecycle and parsing flow, including default-font handling, terminate state, and character storage management - implement writing-step and writing-metrics APIs, including render-step accessors and invisible-character masking - implement additional glyph and character query APIs for text/font code, glyph form, metrics form, scale, and metric references - implement library font open mode setter and string metadata getters - consolidate duplicated font helper math and system-font alias resolution into shared internal utilities - update font rendering metric snapping logic to use consistent ceil/floor handling for bearings, advance, and stride computation - clean up font internals by removing duplicate local helpers and redundant declarations - apply clang-format and line-ending cleanup to modified font sources --------- Co-authored-by: w1naenator <valdis.bogdans@hotmail.com>
This commit is contained in:
parent
b5b7cb5459
commit
843bec6f4f
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -58,7 +58,6 @@ std::string FormatNamedParams(std::initializer_list<NamedParam> params) {
|
||||
}
|
||||
|
||||
bool HasSfntTables(const std::vector<unsigned char>& bytes);
|
||||
FontState* TryGetState(Libraries::Font::OrbisFontHandle h);
|
||||
std::string ReportSystemFaceRequest(FontState& st, Libraries::Font::OrbisFontHandle handle,
|
||||
bool& attached_out);
|
||||
|
||||
@ -83,34 +82,6 @@ static constexpr FT_Int32 kFtLoadFlagsBase =
|
||||
static constexpr FT_Int32 kFtLoadFlagsRender =
|
||||
static_cast<FT_Int32>(kFtLoadFlagsBase | FT_LOAD_RENDER);
|
||||
|
||||
static s32 RoundFixedMul16x16ToS32(long fixed_16_16, s32 value) {
|
||||
const long long prod = static_cast<long long>(fixed_16_16) * static_cast<long long>(value);
|
||||
const long long sign_adj =
|
||||
(static_cast<long long>(~static_cast<long long>(value)) >> 63) * -0x10000LL;
|
||||
const long long base = sign_adj + prod;
|
||||
long long tmp = base - 0x8000LL;
|
||||
if (tmp < 0) {
|
||||
tmp = base + 0x7FFFLL;
|
||||
}
|
||||
return static_cast<s32>(static_cast<u64>(tmp) >> 16);
|
||||
}
|
||||
|
||||
static int FloorIntCompat(float v) {
|
||||
int i = static_cast<int>(std::trunc(v));
|
||||
if (static_cast<float>(i) > v) {
|
||||
--i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static int CeilIntCompat(float v) {
|
||||
int i = static_cast<int>(std::trunc(v));
|
||||
if (static_cast<float>(i) < v) {
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FT_Face CreateFreeTypeFaceFromBytes(const unsigned char* data, std::size_t size,
|
||||
@ -1398,25 +1369,27 @@ s32 RenderCodepointToSurface(FontState& st, Libraries::Font::OrbisFontHandle han
|
||||
const float bottom_f = top_f - metrics->height;
|
||||
|
||||
const int left_i = FloorIntCompat(left_f);
|
||||
const int top_i = FloorIntCompat(top_f);
|
||||
const int top_i = CeilIntCompat(top_f);
|
||||
const int right_i = CeilIntCompat(right_f);
|
||||
const int bottom_i = CeilIntCompat(bottom_f);
|
||||
const int bottom_i = FloorIntCompat(bottom_f);
|
||||
|
||||
const float adv_f = x + metrics->Horizontal.advance;
|
||||
const float adv_snapped = static_cast<float>(FloorIntCompat(adv_f)) - x;
|
||||
const int adv_i = CeilIntCompat(adv_f);
|
||||
const float adv_snapped = static_cast<float>(adv_i) - x;
|
||||
|
||||
result->ImageMetrics.bearingX = static_cast<float>(left_i) - x;
|
||||
result->ImageMetrics.bearingY = static_cast<float>(top_i) - y;
|
||||
result->ImageMetrics.advance = adv_snapped;
|
||||
int stride_i = right_i + 1;
|
||||
const float adjust = static_cast<float>(right_i) - right_f;
|
||||
const int tmp_i = FloorIntCompat(adv_f + adjust);
|
||||
const int adv_trunc_i = static_cast<int>(std::trunc(adv_f));
|
||||
if (adv_trunc_i == 0) {
|
||||
stride_i = tmp_i;
|
||||
}
|
||||
if (stride_i < tmp_i) {
|
||||
stride_i = tmp_i;
|
||||
int stride_i = adv_i;
|
||||
if (adv_f != static_cast<float>(adv_i)) {
|
||||
const int tmp_i = static_cast<int>((static_cast<float>(right_i) - right_f) + adv_f);
|
||||
stride_i = right_i + 1;
|
||||
if (adv_f <= right_f) {
|
||||
stride_i = tmp_i;
|
||||
}
|
||||
if (stride_i < tmp_i) {
|
||||
stride_i = tmp_i;
|
||||
}
|
||||
}
|
||||
result->ImageMetrics.stride = static_cast<float>(stride_i) - x;
|
||||
result->ImageMetrics.width = static_cast<u32>(std::max(0, right_i - left_i));
|
||||
@ -1629,25 +1602,27 @@ s32 RenderCodepointToSurfaceWithScale(FontState& st, Libraries::Font::OrbisFontH
|
||||
const float bottom_f = top_f - m->height;
|
||||
|
||||
const int left_i = FloorIntCompat(left_f);
|
||||
const int top_i = FloorIntCompat(top_f);
|
||||
const int top_i = CeilIntCompat(top_f);
|
||||
const int right_i = CeilIntCompat(right_f);
|
||||
const int bottom_i = CeilIntCompat(bottom_f);
|
||||
const int bottom_i = FloorIntCompat(bottom_f);
|
||||
|
||||
const float adv_f = x + m->Horizontal.advance;
|
||||
const float adv_snapped = static_cast<float>(FloorIntCompat(adv_f)) - x;
|
||||
const int adv_i = CeilIntCompat(adv_f);
|
||||
const float adv_snapped = static_cast<float>(adv_i) - x;
|
||||
|
||||
result->ImageMetrics.bearingX = static_cast<float>(left_i) - x;
|
||||
result->ImageMetrics.bearingY = static_cast<float>(top_i) - y;
|
||||
result->ImageMetrics.advance = adv_snapped;
|
||||
int stride_i = right_i + 1;
|
||||
const float adjust = static_cast<float>(right_i) - right_f;
|
||||
const int tmp_i = FloorIntCompat(adv_f + adjust);
|
||||
const int adv_trunc_i = static_cast<int>(std::trunc(adv_f));
|
||||
if (adv_trunc_i == 0) {
|
||||
stride_i = tmp_i;
|
||||
}
|
||||
if (stride_i < tmp_i) {
|
||||
stride_i = tmp_i;
|
||||
int stride_i = adv_i;
|
||||
if (adv_f != static_cast<float>(adv_i)) {
|
||||
const int tmp_i = static_cast<int>((static_cast<float>(right_i) - right_f) + adv_f);
|
||||
stride_i = right_i + 1;
|
||||
if (adv_f <= right_f) {
|
||||
stride_i = tmp_i;
|
||||
}
|
||||
if (stride_i < tmp_i) {
|
||||
stride_i = tmp_i;
|
||||
}
|
||||
}
|
||||
result->ImageMetrics.stride = static_cast<float>(stride_i) - x;
|
||||
result->ImageMetrics.width = static_cast<u32>(std::max(0, right_i - left_i));
|
||||
|
||||
@ -197,6 +197,34 @@ inline void log_debug(std::string_view message) {
|
||||
LOG_DEBUG(Lib_Font, "{}", message);
|
||||
}
|
||||
|
||||
inline s32 RoundFixedMul16x16ToS32(long fixed_16_16, s32 value) {
|
||||
const long long prod = static_cast<long long>(fixed_16_16) * static_cast<long long>(value);
|
||||
const long long sign_adj =
|
||||
(static_cast<long long>(~static_cast<long long>(value)) >> 63) * -0x10000LL;
|
||||
const long long base = sign_adj + prod;
|
||||
long long tmp = base - 0x8000LL;
|
||||
if (tmp < 0) {
|
||||
tmp = base + 0x7FFFLL;
|
||||
}
|
||||
return static_cast<s32>(static_cast<u64>(tmp) >> 16);
|
||||
}
|
||||
|
||||
inline int FloorIntCompat(float v) {
|
||||
int i = static_cast<int>(std::trunc(v));
|
||||
if (static_cast<float>(i) > v) {
|
||||
--i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
inline int CeilIntCompat(float v) {
|
||||
int i = static_cast<int>(std::trunc(v));
|
||||
if (static_cast<float>(i) < v) {
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
#define formatParams(...) formatParamsImpl(#__VA_ARGS__ __VA_OPT__(, ) __VA_ARGS__)
|
||||
|
||||
struct FontSetSelector;
|
||||
|
||||
@ -225,34 +225,6 @@ static float MaxSsCompat(float a, float b) {
|
||||
return a;
|
||||
}
|
||||
|
||||
static s32 RoundFixedMul16x16ToS32(long fixed_16_16, s32 value) {
|
||||
const long long prod = static_cast<long long>(fixed_16_16) * static_cast<long long>(value);
|
||||
const long long sign_adj =
|
||||
(static_cast<long long>(~static_cast<long long>(value)) >> 63) * -0x10000LL;
|
||||
const long long base = sign_adj + prod;
|
||||
long long tmp = base - 0x8000LL;
|
||||
if (tmp < 0) {
|
||||
tmp = base + 0x7FFFLL;
|
||||
}
|
||||
return static_cast<s32>(static_cast<u64>(tmp) >> 16);
|
||||
}
|
||||
|
||||
static int FloorIntCompat(float v) {
|
||||
int i = static_cast<int>(std::trunc(v));
|
||||
if (static_cast<float>(i) > v) {
|
||||
--i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static int CeilIntCompat(float v) {
|
||||
int i = static_cast<int>(std::trunc(v));
|
||||
if (static_cast<float>(i) < v) {
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
float FixedMulUnitsToF26Dot6(long fixed_16_16, u16 units_per_em) {
|
||||
constexpr float kOneOver64Local = 1.0f / 64.0f;
|
||||
const long prod = static_cast<long>(static_cast<long long>(fixed_16_16) *
|
||||
@ -1944,25 +1916,27 @@ static s32 RenderGlyphIndexToSurface(FontObj& font_obj, u32 glyph_index,
|
||||
const float bottom_f = top_f - metrics->height;
|
||||
|
||||
const int left_i = FloorIntCompat(left_f);
|
||||
const int top_i = FloorIntCompat(top_f);
|
||||
const int top_i = CeilIntCompat(top_f);
|
||||
const int right_i = CeilIntCompat(right_f);
|
||||
const int bottom_i = FloorIntCompat(bottom_f);
|
||||
|
||||
const float adv_f = x + metrics->Horizontal.advance;
|
||||
const float adv_snapped = static_cast<float>(FloorIntCompat(adv_f)) - x;
|
||||
const int adv_i = CeilIntCompat(adv_f);
|
||||
const float adv_snapped = static_cast<float>(adv_i) - x;
|
||||
|
||||
result->ImageMetrics.bearingX = static_cast<float>(left_i) - x;
|
||||
result->ImageMetrics.bearingY = static_cast<float>(top_i) - y;
|
||||
result->ImageMetrics.advance = adv_snapped;
|
||||
int stride_i = right_i + 1;
|
||||
const float adjust = static_cast<float>(right_i) - right_f;
|
||||
const int tmp_i = FloorIntCompat(adv_f + adjust);
|
||||
const int adv_trunc_i = static_cast<int>(std::trunc(adv_f));
|
||||
if (adv_trunc_i == 0) {
|
||||
stride_i = tmp_i;
|
||||
}
|
||||
if (stride_i < tmp_i) {
|
||||
stride_i = tmp_i;
|
||||
int stride_i = adv_i;
|
||||
if (adv_f != static_cast<float>(adv_i)) {
|
||||
const int tmp_i = static_cast<int>((static_cast<float>(right_i) - right_f) + adv_f);
|
||||
stride_i = right_i + 1;
|
||||
if (adv_f <= right_f) {
|
||||
stride_i = tmp_i;
|
||||
}
|
||||
if (stride_i < tmp_i) {
|
||||
stride_i = tmp_i;
|
||||
}
|
||||
}
|
||||
result->ImageMetrics.stride = static_cast<float>(stride_i) - x;
|
||||
result->ImageMetrics.width = static_cast<u32>(std::max(0, right_i - left_i));
|
||||
@ -2583,90 +2557,6 @@ static float to_f26dot6_s64(s64 value) {
|
||||
return static_cast<float>(value) * kOneOver64;
|
||||
}
|
||||
|
||||
static std::optional<std::filesystem::path> ResolveKnownSysFontAlias(
|
||||
const std::filesystem::path& sysfonts_dir, std::string_view ps4_filename) {
|
||||
const auto resolve_existing =
|
||||
[&](std::string_view filename) -> std::optional<std::filesystem::path> {
|
||||
const std::filesystem::path file_path{std::string(filename)};
|
||||
std::error_code ec;
|
||||
{
|
||||
const auto candidate = sysfonts_dir / file_path;
|
||||
if (std::filesystem::exists(candidate, ec)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
{
|
||||
const auto candidate = sysfonts_dir / "font" / file_path;
|
||||
if (std::filesystem::exists(candidate, ec)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
{
|
||||
const auto candidate = sysfonts_dir / "font2" / file_path;
|
||||
if (std::filesystem::exists(candidate, ec)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
static constexpr std::array<std::pair<std::string_view, std::string_view>, 41> kAliases = {{
|
||||
{"SST-EU-ROMAN-L.OTF", "SST-Light.otf"},
|
||||
{"SST-EU-ROMAN.OTF", "SST-Roman.otf"},
|
||||
{"SST-EU-ROMAN-M.OTF", "SST-Medium.otf"},
|
||||
{"SST-EU-ROMAN-R.OTF", "SST-Roman.otf"},
|
||||
{"SST-EU-ROMAN-I.OTF", "SST-Italic.otf"},
|
||||
{"SST-EU-ROMAN-B.OTF", "SST-Bold.otf"},
|
||||
{"SST-EU-ROMAN-BI.OTF", "SST-BoldItalic.otf"},
|
||||
{"SST-ITALIC-L.OTF", "SST-LightItalic.otf"},
|
||||
{"SST-ITALIC-R.OTF", "SST-Italic.otf"},
|
||||
{"SST-ITALIC-M.OTF", "SST-MediumItalic.otf"},
|
||||
{"SST-ITALIC-B.OTF", "SST-BoldItalic.otf"},
|
||||
{"SST-TYPEWRITER-R.OTF", "SSTTypewriter-Roman.otf"},
|
||||
{"SST-TYPEWRITER-B.OTF", "SSTTypewriter-Bd.otf"},
|
||||
{"SST-JPPRO-R.OTF", "SSTJpPro-Regular.otf"},
|
||||
{"SST-JPPRO-B.OTF", "SSTJpPro-Bold.otf"},
|
||||
{"SST-CNGB-HEI-R.TTF", "DFHEI5-SONY.ttf"},
|
||||
{"SST-ARIB-STD-B24-R.TTF", "SSTAribStdB24-Regular.ttf"},
|
||||
{"SST-ARABIC-R.OTF", "SSTArabic-Roman.otf"},
|
||||
{"SST-ARABIC-L.OTF", "SSTArabic-Light.otf"},
|
||||
{"SST-ARABIC-M.OTF", "SSTArabic-Medium.otf"},
|
||||
{"SST-ARABIC-B.OTF", "SSTArabic-Bold.otf"},
|
||||
{"SCE-EXT-HANGUL-L.OTF", "SCEPS4Yoongd-Light.otf"},
|
||||
{"SCE-EXT-HANGUL-R.OTF", "SCEPS4Yoongd-Medium.otf"},
|
||||
{"SCE-EXT-HANGUL-B.OTF", "SCEPS4Yoongd-Bold.otf"},
|
||||
{"SSTCC-SERIF-MONO.OTF", "e046323ms.ttf"},
|
||||
{"SSTCC-SERIF.OTF", "e046323ts.ttf"},
|
||||
{"SSTCC-SANSSERIF-MONO.OTF", "n023055ms.ttf"},
|
||||
{"SSTCC-SANSSERIF.OTF", "n023055ts.ttf"},
|
||||
{"SSTCC-CUSUAL.OTF", "d013013ds.ttf"},
|
||||
{"SSTCC-CURSIVE.OTF", "k006004ds.ttf"},
|
||||
{"SSTCC-SMALLCAPITAL.OTF", "c041056ts.ttf"},
|
||||
{"SCE-JP-CATTLEYA-L.OTF", "SCE-RDC-R-JPN.otf"},
|
||||
{"SCE-JP-CATTLEYA-B.OTF", "SCE-RDC-B-JPN.otf"},
|
||||
{"SST-THAI-L.OTF", "SSTThai-Light.otf"},
|
||||
{"SST-THAI-R.OTF", "SSTThai-Roman.otf"},
|
||||
{"SST-THAI-M.OTF", "SSTThai-Medium.otf"},
|
||||
{"SST-THAI-B.OTF", "SSTThai-Bold.otf"},
|
||||
{"SST-VIETNAMESE-L.OTF", "SSTVietnamese-Light.otf"},
|
||||
{"SST-VIETNAMESE-R.OTF", "SSTVietnamese-Roman.otf"},
|
||||
{"SST-VIETNAMESE-M.OTF", "SSTVietnamese-Medium.otf"},
|
||||
{"SST-VIETNAMESE-B.OTF", "SSTVietnamese-Bold.otf"},
|
||||
}};
|
||||
|
||||
for (const auto& [from, to] : kAliases) {
|
||||
if (ps4_filename == from) {
|
||||
return resolve_existing(to);
|
||||
}
|
||||
if (ps4_filename == to) {
|
||||
if (auto reverse = resolve_existing(from)) {
|
||||
return reverse;
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static constexpr u32 MakeTag(char a, char b, char c, char d) {
|
||||
return (static_cast<u32>(static_cast<u8>(a)) << 24) |
|
||||
(static_cast<u32>(static_cast<u8>(b)) << 16) |
|
||||
@ -3137,7 +3027,8 @@ s32 PS4_SYSV_ABI LibraryOpenFontMemoryStub(void* library, u32 mode, const void*
|
||||
const std::filesystem::path file_path{ps4_name};
|
||||
candidates.emplace_back((sysfonts_dir / "font" / file_path).string());
|
||||
candidates.emplace_back((sysfonts_dir / "font2" / file_path).string());
|
||||
if (const auto alias = ResolveKnownSysFontAlias(sysfonts_dir, ps4_name)) {
|
||||
if (const auto alias =
|
||||
Libraries::Font::Internal::ResolveKnownSysFontAlias(sysfonts_dir, ps4_name)) {
|
||||
candidates.emplace_back(alias->string());
|
||||
}
|
||||
}
|
||||
|
||||
@ -960,7 +960,7 @@ void Translator::V_CVT_FLR_I32_F32(const GcnInst& inst) {
|
||||
|
||||
void Translator::V_CVT_OFF_F32_I4(const GcnInst& inst) {
|
||||
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||
ASSERT(src0.IsImmediate());
|
||||
ASSERT_MSG(src0.IsImmediate(), "V_CVT_OFF_F32_I4 expects an immediate source operand");
|
||||
static constexpr std::array IntToFloat = {
|
||||
0.0f, 0.0625f, 0.1250f, 0.1875f, 0.2500f, 0.3125f, 0.3750f, 0.4375f,
|
||||
-0.5000f, -0.4375f, -0.3750f, -0.3125f, -0.2500f, -0.1875f, -0.1250f, -0.0625f};
|
||||
@ -1252,45 +1252,57 @@ void Translator::V_CMP_U32(ConditionOp op, bool is_signed, bool set_exec, const
|
||||
}
|
||||
|
||||
void Translator::V_CMP_U64(ConditionOp op, bool is_signed, bool set_exec, const GcnInst& inst) {
|
||||
const bool is_zero = inst.src[1].field == OperandField::ConstZero;
|
||||
const bool is_neg_one = inst.src[1].field == OperandField::SignedConstIntNeg;
|
||||
ASSERT(is_zero || is_neg_one);
|
||||
if (is_neg_one) {
|
||||
ASSERT_MSG(-s32(inst.src[1].code) + SignedConstIntNegMin - 1 == -1,
|
||||
"SignedConstIntNeg must be -1");
|
||||
}
|
||||
// AMD VOPC semantics:
|
||||
// V_CMP_* : D/VCC[threadId] = compare(S0, S1)
|
||||
// V_CMPX_* : EXEC[threadId] = D/VCC[threadId] = compare(S0, S1)
|
||||
//
|
||||
// Do not use subgroup reductions here. Result must stay per-lane.
|
||||
|
||||
const IR::U1 src0 = [&] {
|
||||
switch (inst.src[0].field) {
|
||||
case OperandField::ScalarGPR:
|
||||
return ir.GetThreadBitScalarReg(IR::ScalarReg(inst.src[0].code));
|
||||
case OperandField::VccLo:
|
||||
return ir.GetVcc();
|
||||
default:
|
||||
UNREACHABLE_MSG("src0 = {}", u32(inst.src[0].field));
|
||||
const auto set_result = [&](IR::U1 result) {
|
||||
if (set_exec) {
|
||||
ir.SetExec(result);
|
||||
}
|
||||
}();
|
||||
const IR::U1 result = [&] {
|
||||
SetDst1(inst.dst[1], result);
|
||||
};
|
||||
|
||||
const auto make_compare = [&](IR::U64 src0, IR::U64 src1) -> IR::U1 {
|
||||
switch (op) {
|
||||
case ConditionOp::F:
|
||||
return ir.Imm1(false);
|
||||
case ConditionOp::TRU:
|
||||
return ir.Imm1(true);
|
||||
case ConditionOp::EQ:
|
||||
return is_zero ? ir.LogicalNot(src0) : src0;
|
||||
return ir.IEqual(src0, src1);
|
||||
case ConditionOp::LG: // NE
|
||||
return is_zero ? src0 : ir.LogicalNot(src0);
|
||||
return ir.INotEqual(src0, src1);
|
||||
case ConditionOp::LT:
|
||||
return ir.ILessThan(src0, src1, is_signed);
|
||||
case ConditionOp::LE:
|
||||
return ir.ILessThanEqual(src0, src1, is_signed);
|
||||
case ConditionOp::GT:
|
||||
ASSERT(is_zero);
|
||||
return ir.GroupAny(ir.GetThreadBitScalarReg(IR::ScalarReg(inst.src[0].code)));
|
||||
return ir.IGreaterThan(src0, src1, is_signed);
|
||||
case ConditionOp::GE:
|
||||
return ir.IGreaterThanEqual(src0, src1, is_signed);
|
||||
default:
|
||||
UNREACHABLE_MSG("Unsupported V_CMP_U64 condition operation: {}", u32(op));
|
||||
UNREACHABLE_MSG("Unsupported V_CMP_{}64 condition: {}", is_signed ? "I" : "U", u32(op));
|
||||
}
|
||||
}();
|
||||
};
|
||||
|
||||
if (is_signed) {
|
||||
UNREACHABLE_MSG("V_CMP_U64 with signed integers is not supported");
|
||||
// Cheap constants first. These are always spec-correct.
|
||||
if (op == ConditionOp::F) {
|
||||
set_result(ir.Imm1(false));
|
||||
return;
|
||||
}
|
||||
if (set_exec) {
|
||||
UNREACHABLE_MSG("Exec setting for V_CMP_U64 is not supported");
|
||||
|
||||
if (op == ConditionOp::TRU) {
|
||||
set_result(ir.Imm1(true));
|
||||
return;
|
||||
}
|
||||
SetDst1(inst.dst[1], result);
|
||||
|
||||
const IR::U64 src0 = GetSrc64(inst.src[0]);
|
||||
const IR::U64 src1 = GetSrc64(inst.src[1]);
|
||||
|
||||
set_result(make_compare(src0, src1));
|
||||
}
|
||||
|
||||
void Translator::V_CMP_CLASS_F32(const GcnInst& inst) {
|
||||
|
||||
@ -239,9 +239,13 @@ bool Instance::CreateDevice() {
|
||||
};
|
||||
|
||||
// Required
|
||||
ASSERT(add_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
|
||||
ASSERT(add_extension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME));
|
||||
ASSERT(add_extension(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME));
|
||||
ASSERT_MSG(add_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME),
|
||||
"Required Vulkan extension unavailable: {}", VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
||||
ASSERT_MSG(add_extension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME),
|
||||
"Required Vulkan extension unavailable: {}", VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
|
||||
ASSERT_MSG(add_extension(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME),
|
||||
"Required Vulkan extension unavailable: {}",
|
||||
VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
|
||||
|
||||
// Optional
|
||||
maintenance_8 = add_extension(VK_KHR_MAINTENANCE_8_EXTENSION_NAME);
|
||||
|
||||
@ -310,7 +310,6 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_,
|
||||
.needs_clip_distance_emulation = instance.GetDriverID() == vk::DriverId::eNvidiaProprietary,
|
||||
.supports_shader_stencil_export = instance_.IsShaderStencilExportSupported(),
|
||||
};
|
||||
|
||||
WarmUp();
|
||||
|
||||
auto [cache_result, cache] = instance.GetDevice().createPipelineCacheUnique({});
|
||||
@ -589,7 +588,9 @@ bool PipelineCache::RefreshGraphicsStages() {
|
||||
u32 vertex_binding = 0;
|
||||
for (const auto& attrib : fetch_shader->attributes) {
|
||||
const auto& buffer = attrib.GetSharp(*vs_info);
|
||||
ASSERT(vertex_binding < MaxVertexBufferCount);
|
||||
ASSERT_MSG(vertex_binding < MaxVertexBufferCount,
|
||||
"Vertex attribute binding count exceeded limit: {} >= {}", vertex_binding,
|
||||
MaxVertexBufferCount);
|
||||
key.vertex_buffer_formats[vertex_binding++] =
|
||||
Vulkan::LiverpoolToVK::SurfaceFormat(buffer.GetDataFmt(), buffer.GetNumberFmt());
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user