Merge remote-tracking branch 'upstream/canary_experimental' into edge

This commit is contained in:
Herman S.
2026-01-30 15:01:25 +09:00
12 changed files with 167 additions and 94 deletions
@@ -105,7 +105,7 @@ void ContextPromotionPass::PromoteBlock(Block* block) {
// Volatile instruction - requires all context values be flushed.
validity.reset();
} else if (i->opcode == &OPCODE_LOAD_CONTEXT_info) {
size_t offset = i->src1.offset;
const size_t offset = i->src1.offset;
if (validity.test(static_cast<uint32_t>(offset))) {
// Legit previous value, reuse.
Value* previous_value = context_values_[offset];
@@ -113,15 +113,19 @@ void ContextPromotionPass::PromoteBlock(Block* block) {
i->set_src1(previous_value);
} else {
// Store the loaded value into the table.
context_values_[offset] = i->dest;
validity.set(static_cast<uint32_t>(offset));
if (i->dest->type != TypeName::VEC128_TYPE) {
context_values_[offset] = i->dest;
validity.set(static_cast<uint32_t>(offset));
}
}
} else if (i->opcode == &OPCODE_STORE_CONTEXT_info) {
size_t offset = i->src1.offset;
const size_t offset = i->src1.offset;
Value* value = i->src2.value;
// Store value into the table for later.
context_values_[offset] = value;
validity.set(static_cast<uint32_t>(offset));
if (value->type != TypeName::VEC128_TYPE) {
// Store value into the table for later.
context_values_[offset] = value;
validity.set(static_cast<uint32_t>(offset));
}
}
i = next;
}
@@ -140,13 +144,16 @@ void ContextPromotionPass::RemoveDeadStoresBlock(Block* block) {
// Volatile instruction - requires all context values be flushed.
validity.reset();
} else if (i->opcode == &OPCODE_STORE_CONTEXT_info) {
size_t offset = i->src1.offset;
if (!validity.test(static_cast<uint32_t>(offset))) {
// Offset not yet written, mark and continue.
validity.set(static_cast<uint32_t>(offset));
} else {
// Already written to. Remove this store.
i->UnlinkAndNOP();
const size_t offset = i->src1.offset;
const Value* value = i->src2.value;
if (value->type != TypeName::VEC128_TYPE) {
if (!validity.test(static_cast<uint32_t>(offset))) {
// Offset not yet written, mark and continue.
validity.set(static_cast<uint32_t>(offset));
} else {
// Already written to. Remove this store.
i->UnlinkAndNOP();
}
}
}
i = prev;
+5 -1
View File
@@ -17,6 +17,7 @@
#include "xenia/base/cvar.h"
#include "xenia/base/math.h"
#include "xenia/gpu/dxbc_shader.h"
#include "xenia/gpu/gpu_flags.h"
#include "xenia/gpu/xenos.h"
#include "xenia/ui/graphics_provider.h"
@@ -1379,7 +1380,10 @@ void DxbcShaderTranslator::PostTranslation() {
shader_binding.mag_filter = translator_binding.mag_filter;
shader_binding.min_filter = translator_binding.min_filter;
shader_binding.mip_filter = translator_binding.mip_filter;
shader_binding.aniso_filter = translator_binding.aniso_filter;
shader_binding.aniso_filter =
cvars::anisotropic_override > -1 && cvars::anisotropic_override < 6
? xenos::AnisoFilter(cvars::anisotropic_override)
: translator_binding.aniso_filter;
}
}
}
+12
View File
@@ -186,3 +186,15 @@ DEFINE_bool(gpu_3d_to_2d_texture, true,
"Handle shaders that sample 3D textures as 2D by creating a 2D "
"texture from slice 0 of the guest memory.",
"GPU");
DEFINE_int32(anisotropic_override, -1,
"Level of anisotropic filtering enforced on all texture fetch "
"instructions.\n"
" -1 = No override\n"
" 0 = Disable anisotropic filtering\n"
" 1 = Force 1x anisotropic filtering\n"
" 2 = Force 2x anisotropic filtering\n"
" 3 = Force 4x anisotropic filtering\n"
" 4 = Force 8x anisotropic filtering\n"
" 5 = Force 16x anisotropic filtering",
"GPU");
+2
View File
@@ -41,6 +41,8 @@ void SetOcclusionQueryEnable(bool value);
// Based on use_50Hz_mode cvar.
uint32_t GetGuestVblankRateHz();
DECLARE_int32(anisotropic_override);
DECLARE_bool(disassemble_pm4);
DECLARE_bool(gpu_debug_markers);
+5 -1
View File
@@ -19,6 +19,7 @@
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/string_buffer.h"
#include "xenia/gpu/gpu_flags.h"
#include "xenia/gpu/spirv_compatibility.h"
#include "xenia/gpu/spirv_shader.h"
#include "xenia/ui/vulkan/spirv_tools_context.h"
@@ -1014,7 +1015,10 @@ void SpirvShaderTranslator::PostTranslation() {
shader_binding.mag_filter = translator_binding.mag_filter;
shader_binding.min_filter = translator_binding.min_filter;
shader_binding.mip_filter = translator_binding.mip_filter;
shader_binding.aniso_filter = translator_binding.aniso_filter;
shader_binding.aniso_filter =
cvars::anisotropic_override > -1 && cvars::anisotropic_override < 6
? xenos::AnisoFilter(cvars::anisotropic_override)
: translator_binding.aniso_filter;
}
}
}
+4 -8
View File
@@ -605,11 +605,11 @@ dword_result_t XamUserCreateAchievementEnumerator_entry(
}
if (buffer_size_ptr) {
*buffer_size_ptr = static_cast<uint32_t>(entry_size) * count;
*buffer_size_ptr = static_cast<uint32_t>(entry_size * count);
}
auto e = object_ref<XAchievementEnumerator>(
new XAchievementEnumerator(kernel_state(), count, flags));
new XAchievementEnumerator(kernel_state(), count, offset, flags));
auto result = e->Initialize(user_index, 0xFB, 0xB000A, 0xB000B, 0);
if (XFAILED(result)) {
return result;
@@ -632,15 +632,11 @@ dword_result_t XamUserCreateAchievementEnumerator_entry(
kernel_state()->achievement_manager()->GetTitleAchievements(
requester_xuid, title_id_);
const auto requested_achievements = user_title_achievements |
std::views::drop(offset) |
std::views::take(count);
if (requested_achievements.empty()) {
if (user_title_achievements.empty()) {
return X_ERROR_INVALID_PARAMETER;
}
for (const auto& entry : requested_achievements) {
for (const auto& entry : user_title_achievements) {
auto unlock_time = X_FILETIME();
if (entry.IsUnlocked() && entry.unlock_time.is_valid()) {
unlock_time = entry.unlock_time;
+10
View File
@@ -443,6 +443,16 @@ dword_result_t NtRemoveIoCompletion_entry(
DECLARE_XBOXKRNL_EXPORT2(NtRemoveIoCompletion, kFileSystem, kImplemented,
kHighFrequency);
dword_result_t NtCancelIoFile_entry(dword_t handle) {
auto file = kernel_state()->object_table()->LookupObject<XFile>(handle);
if (!file) {
return X_STATUS_INVALID_HANDLE;
}
return X_STATUS_SUCCESS;
}
DECLARE_XBOXKRNL_EXPORT1(NtCancelIoFile, kFileSystem, kStub);
dword_result_t NtQueryFullAttributesFile_entry(
pointer_t<X_OBJECT_ATTRIBUTES> obj_attribs,
pointer_t<X_FILE_NETWORK_OPEN_INFORMATION> file_info) {
@@ -1838,6 +1838,27 @@ dword_result_t KeSetPriorityThread_entry(pointer_t<X_KTHREAD> thread_ptr,
}
DECLARE_XBOXKRNL_EXPORT1(KeSetPriorityThread, kThreading, kImplemented);
void xeKeInitializeTimerEx(X_KTIMER* timer, uint32_t type, uint32_t proctype,
PPCContext* context) {
xenia_assert(proctype < 3);
xenia_assert(type == 0 || type == 1);
// other fields are unmodified, they must carry through multiple calls of
// initialize
timer->header.process_type = proctype;
timer->header.inserted = 0;
timer->header.type = type + 8;
timer->header.signal_state = 0;
util::XeInitializeListHead(&timer->header.wait_list, context);
timer->due_time = 0;
timer->period = 0;
}
void KeInitializeTimerEx_entry(pointer_t<X_KTIMER> timer, dword_t type,
dword_t proctype, const ppc_context_t& context) {
xeKeInitializeTimerEx(timer, type, proctype & 0xFF, context);
}
DECLARE_XBOXKRNL_EXPORT1(KeInitializeTimerEx, kThreading, kImplemented);
} // namespace xboxkrnl
} // namespace kernel
} // namespace xe
+3 -4
View File
@@ -83,13 +83,12 @@ uint32_t XStaticUntypedEnumerator::WriteItems(uint8_t* buffer_data,
uint32_t XAchievementEnumerator::WriteItems(uint8_t* buffer_data,
uint32_t buffer_size,
uint32_t* written_count) {
size_t count = std::min(items_.size() - current_item_, items_per_enumerate());
if (!count) {
if (items_.size() - current_item_ <= 0) {
return X_ERROR_NO_MORE_FILES;
}
size_t size = count * item_size();
const size_t count =
std::min(items_.size() - current_item_, items_per_enumerate());
auto details = reinterpret_cast<xam::X_ACHIEVEMENT_DETAILS*>(buffer_data);
size_t string_offset =
items_per_enumerate() * sizeof(xam::X_ACHIEVEMENT_DETAILS);
+2 -1
View File
@@ -139,12 +139,13 @@ class XStaticEnumerator : public XStaticUntypedEnumerator {
class XAchievementEnumerator : public XEnumerator {
public:
XAchievementEnumerator(KernelState* kernel_state, size_t items_per_enumerate,
uint32_t flags)
size_t enumeration_offset, uint32_t flags)
: XEnumerator(
kernel_state, items_per_enumerate,
sizeof(xam::X_ACHIEVEMENT_DETAILS) +
(!!(flags & 7) ? xam::X_ACHIEVEMENT_DETAILS::kStringBufferSize
: 0)),
current_item_(enumeration_offset),
flags_(flags) {}
void AppendItem(xam::AchievementDetails item) {
+1
View File
@@ -48,6 +48,7 @@ typedef struct {
union {
uint8_t size;
uint8_t hand;
uint8_t process_type;
};
union {
uint8_t inserted;
+81 -65
View File
@@ -17,6 +17,7 @@ from shutil import rmtree
import subprocess
import sys
import stat
import enum
__author__ = "ben.vanik@gmail.com (Ben Vanik)"
@@ -28,12 +29,30 @@ class bcolors:
# OKBLUE = "\033[94m"
OKCYAN = "\033[96m"
# OKGREEN = "\033[92m"
# WARNING = "\033[93m"
WARNING = "\033[93m"
FAIL = "\033[91m"
ENDC = "\033[0m"
# BOLD = "\033[1m"
# UNDERLINE = "\033[4m"
def print_error(text: str):
print(f"{bcolors.FAIL}ERROR: {text}{bcolors.ENDC}")
def print_warning(text: str):
print(f"{bcolors.WARNING}WARNING: {text}{bcolors.ENDC}")
class ResultStatus(enum.Enum):
SUCCESS = enum.auto()
FAILURE = enum.auto()
def print_status(status: ResultStatus):
match status:
case ResultStatus.SUCCESS:
print(f"{bcolors.OKCYAN}Success!{bcolors.ENDC}")
case ResultStatus.FAILURE:
print(f"{bcolors.FAIL}Error!{bcolors.ENDC}")
# Detect if building on Android via Termux.
host_linux_platform_is_android = False
if sys.platform == "linux":
@@ -152,9 +171,9 @@ def setup_vulkan_sdk():
if has_bin("spirv-opt"):
print(f"VULKAN_SDK is set to {existing_vulkan_sdk}")
return True
print(f"WARNING: VULKAN_SDK is set to {existing_vulkan_sdk} but spirv-opt not found in PATH")
print_warning(f"VULKAN_SDK is set to {existing_vulkan_sdk} but spirv-opt not found in PATH")
else:
print(f"WARNING: VULKAN_SDK is set to {existing_vulkan_sdk} but directory does not exist")
print_warning(f"VULKAN_SDK is set to {existing_vulkan_sdk} but directory does not exist")
return False
if sys.platform != "win32":
@@ -207,7 +226,7 @@ def setup_qt():
print(f"QT_DIR is set to {existing_qt_dir}")
return True
else:
print(f"WARNING: QT_DIR is set to {existing_qt_dir} but directory does not exist")
print_warning(f"QT_DIR is set to {existing_qt_dir} but directory does not exist")
return False
# Determine Qt base directory based on platform
@@ -342,7 +361,7 @@ def generate_moc_files():
moc_path = os.path.join(qt_dir, "bin", "moc")
if not os.path.exists(moc_path):
print(f"WARNING: moc not found at {moc_path}")
print_warning(f"moc not found at {moc_path}")
return False
# Find all Qt headers with Q_OBJECT
@@ -399,7 +418,7 @@ def generate_moc_files():
result = subprocess.call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
if result != 0:
print(f" ERROR: Failed to generate {moc_name}")
print_error(f"Failed to generate {moc_name}")
any_errors = True
else:
print(f"- generated {moc_name}")
@@ -429,19 +448,19 @@ def main():
# Check git exists.
if not has_bin("git"):
print("WARNING: Git should be installed and on PATH. Version info will be omitted from all binaries!\n")
print_warning("Git should be installed and on PATH. Version info will be omitted from all binaries!\n")
elif not git_is_repository():
print("WARNING: The source tree is unversioned. Version info will be omitted from all binaries!\n")
print_warning("The source tree is unversioned. Version info will be omitted from all binaries!\n")
# Check python version.
python_minimum_ver = 3,9
if not sys.version_info[:2] >= (python_minimum_ver[0], python_minimum_ver[1]) or not sys.maxsize > 2**32:
print(f"ERROR: Python {python_minimum_ver[0]}.{python_minimum_ver[1]}+ 64-bit must be installed and on PATH")
print_error(f"Python {python_minimum_ver[0]}.{python_minimum_ver[1]}+ 64-bit must be installed and on PATH")
sys.exit(1)
# Grab Visual Studio version and execute shell to set up environment.
if sys.platform == "win32" and not vs_version:
print("WARNING: Visual Studio not found!"
print_warning("Visual Studio not found!"
"\nBuilding for Windows will not be supported."
" Please refer to the building guide:"
f"\nhttps://github.com/has207/xenia-edge/blob/{default_branch}/docs/building.md")
@@ -610,7 +629,7 @@ def generate_source_class(path):
source_path = f"{path}.cc"
if os.path.isfile(header_path) or os.path.isfile(source_path):
print("ERROR: Target file already exists")
print_error("Target file already exists")
return 1
if generate_source_file(header_path) > 0:
@@ -635,13 +654,13 @@ def generate_source_file(path):
*/"""
if os.path.isfile(path):
print("ERROR: Target file already exists")
print_error("Target file already exists")
return 1
try:
with open(path, "w") as f:
f.write(copyright)
except Exception as e:
print(f"ERROR: Could not write to file [path {path}]")
print_error(f"Could not write to file [path {path}]")
return 1
return 0
@@ -844,7 +863,7 @@ def get_clang_format_binary():
print(best_output)
return best_binary
print(f"{bcolors.FAIL}ERROR: clang-format {clang_format_version_min} or newer is not on PATH{bcolors.ENDC}")
print_error(f"clang-format {clang_format_version_min} or newer is not on PATH")
sys.exit(1)
@@ -873,8 +892,8 @@ def get_premake_target_os(target_os_override=None):
if target_os_override == "android":
target_os = target_os_override
else:
print(
"ERROR: cross-compilation is only supported for Android target")
print_error(
"cross-compilation is only supported for Android target")
sys.exit(1)
return target_os
@@ -969,7 +988,7 @@ def run_windeployqt(bin_path, config):
windeployqt_path = os.path.join(qt_dir, "bin", "windeployqt.exe")
if not os.path.exists(windeployqt_path):
print(f"WARNING: windeployqt not found at {windeployqt_path}")
print_warning(f"windeployqt not found at {windeployqt_path}")
return True
# Find the xenia executable
@@ -1003,7 +1022,7 @@ def run_windeployqt(bin_path, config):
print(" Qt dependencies deployed successfully")
return True
else:
print(f"WARNING: windeployqt failed with exit code {result}")
print_warning(f"windeployqt failed with exit code {result}")
return False
@@ -1137,12 +1156,11 @@ class SetupCommand(Command):
git_submodule_update()
fetch_data_repos()
else:
print("WARNING: Git not available or not a repository. Dependencies may be missing.")
print_warning("Git not available or not a repository. Dependencies may be missing.")
print("\n- running premake...")
ret = run_platform_premake(target_os_override=args["target_os"])
print("\nSuccess!" if ret == 0 else "\nError!")
print_status(ResultStatus.SUCCESS if not ret else ResultStatus.FAILURE)
return ret
@@ -1163,7 +1181,7 @@ class FetchDataCommand(Command):
if git_is_repository():
fetch_data_repos()
else:
print("WARNING: Git not available or not a repository.")
print_warning("Git not available or not a repository.")
return 1
print("\nSuccess!")
@@ -1217,7 +1235,7 @@ class PullCommand(Command):
print("- running premake...")
if run_platform_premake(target_os_override=args["target_os"]) == 0:
print("\nSuccess!")
print_status(ResultStatus.SUCCESS)
return 0
@@ -1245,7 +1263,7 @@ class PremakeCommand(Command):
print("Running premake...\n")
ret = run_platform_premake(target_os_override=args["target_os"],
cc=args["cc"], devenv=args["devenv"])
print("Success!" if ret == 0 else "Error!")
print_status(ResultStatus.SUCCESS if not ret else ResultStatus.FAILURE)
return ret
@@ -1276,7 +1294,7 @@ class BaseBuildCommand(Command):
def execute(self, args, pass_args, cwd):
# Check Vulkan SDK availability
if not os.environ.get("VULKAN_SDK"):
print("ERROR: Vulkan SDK not found!"
print_error("Vulkan SDK not found!"
"\nPlease install Vulkan SDK from:"
"\nhttps://sdk.lunarg.com/sdk/download/latest/windows/vulkan-sdk.exe"
f"\nSee: https://github.com/has207/xenia-edge/blob/{default_branch}/docs/building.md")
@@ -1292,7 +1310,7 @@ class BaseBuildCommand(Command):
args["config"]))
if sys.platform == "win32":
if not vs_version:
print("ERROR: Visual Studio is not installed.")
print_error("Visual Studio is not installed.")
result = 1
else:
targets = None
@@ -1306,7 +1324,7 @@ class BaseBuildCommand(Command):
for target in args["target"]:
project_file = f"build/{target}.vcxproj"
if not os.path.exists(project_file):
print(f"ERROR: Project file {project_file} does not exist")
print_error(f"Project file {project_file} does not exist")
result = 1
break
@@ -1357,14 +1375,14 @@ class BaseBuildCommand(Command):
] + pass_args, env=dict(os.environ))
print("")
if result != 0:
print("ERROR: cmake failed with one or more errors.")
print_error("cmake failed with one or more errors.")
return result
result = subprocess.call([
"ninja",
f"-Cbuild/build_{args['config']}",
] + pass_args, env=dict(os.environ))
if result != 0:
print("ERROR: ninja failed with one or more errors.")
print_error("ninja failed with one or more errors.")
return result
@@ -1384,13 +1402,13 @@ class BuildCommand(BaseBuildCommand):
# Generate MOC files before building
if not generate_moc_files():
print(f"{bcolors.FAIL}ERROR: MOC generation failed{bcolors.ENDC}")
print_error("MOC generation failed")
return 1
# Generate shader bytecode before building
shader_result = build_shaders()
if shader_result != 0:
print(f"{bcolors.FAIL}ERROR: Shader generation failed{bcolors.ENDC}")
print_error("Shader generation failed")
return shader_result
result = super(BuildCommand, self).execute(args, pass_args, cwd)
@@ -1400,9 +1418,7 @@ class BuildCommand(BaseBuildCommand):
bin_path = get_build_bin_path(args)
run_windeployqt(bin_path, args["config"])
print(f"{bcolors.OKCYAN}Success!{bcolors.ENDC}")
else:
print(f"{bcolors.FAIL}Failed!{bcolors.ENDC}")
print_status(ResultStatus.SUCCESS if not result else ResultStatus.FAILURE)
return result
@@ -1501,7 +1517,7 @@ def build_shaders(targets=None):
fxc = glob(os.path.join(os.environ.get("ProgramFiles(x86)", ""),
"Windows Kits", "10", "bin", "*", "x64", "fxc.exe"))
if not fxc:
print("ERROR: could not find fxc! Set FXC_PATH environment variable or install Windows SDK.")
print_error("could not find fxc! Set FXC_PATH environment variable or install Windows SDK.")
return 1
fxc = fxc[-1] # Highest version is last
else:
@@ -1543,7 +1559,7 @@ def build_shaders(targets=None):
src_dir = os.path.dirname(src_path)
if is_dxc:
# DXC only supports SM 6.0+, cannot compile SM 5.1
print("WARNING: DXC doesn't support SM 5.1, using SM 6.0")
print_warning("DXC doesn't support SM 5.1, using SM 6.0")
compiler_args.extend([
"-T", f"{dxbc_stage}_6_0",
"-HV", "2017",
@@ -1572,7 +1588,7 @@ def build_shaders(targets=None):
src_path,
])
if subprocess.call(compiler_args, stdout=subprocess.DEVNULL) != 0:
print(f"ERROR: failed to compile DXBC shader: {src_path}")
print_error(f"failed to compile DXBC shader: {src_path}")
return 1
# Vulkan SPIR-V.
@@ -1582,7 +1598,7 @@ def build_shaders(targets=None):
# Get the SPIR-V tool paths.
vulkan_sdk_path = os.environ.get("VULKAN_SDK")
if not vulkan_sdk_path:
print("ERROR: VULKAN_SDK environment variable is not set")
print_error("VULKAN_SDK environment variable is not set")
if sys.platform == "win32":
print("Please install Vulkan SDK from:")
print("https://sdk.lunarg.com/sdk/download/latest/windows/vulkan-sdk.exe")
@@ -1590,23 +1606,23 @@ def build_shaders(targets=None):
print("Please install Vulkan SDK and set VULKAN_SDK environment variable")
return 1
if not os.path.exists(vulkan_sdk_path):
print(f"ERROR: could not find the Vulkan SDK at {vulkan_sdk_path}")
print_error(f"could not find the Vulkan SDK at {vulkan_sdk_path}")
return 1
vulkan_bin_path = os.path.join(vulkan_sdk_path, "bin")
if not os.path.exists(vulkan_bin_path):
print("ERROR: could not find the Vulkan SDK binaries")
print_error("could not find the Vulkan SDK binaries")
return 1
glslang = os.path.join(vulkan_bin_path, "glslangValidator")
if not has_bin(glslang):
print("ERROR: could not find glslangValidator")
print_error("could not find glslangValidator")
return 1
spirv_opt = os.path.join(vulkan_bin_path, "spirv-opt")
if not has_bin(spirv_opt):
print("ERROR: could not find spirv-opt")
print_error("could not find spirv-opt")
return 1
spirv_dis = os.path.join(vulkan_bin_path, "spirv-dis")
if not has_bin(spirv_dis):
print("ERROR: could not find spirv-dis")
print_error("could not find spirv-dis")
return 1
# Build SPIR-V.
@@ -1650,20 +1666,20 @@ def build_shaders(targets=None):
glslang_arguments,
input=(spirv_xesl_wrapper % src_name) if src_is_xesl else None,
text=True).returncode != 0:
print("ERROR: failed to build a SPIR-V shader")
print_error("failed to build a SPIR-V shader")
return 1
spirv_file_path = f"{spirv_file_path_base}.spv"
if subprocess.call([spirv_opt, "-O", "-O", "--canonicalize-ids",
spirv_glslang_file_path, "-o", spirv_file_path]) != 0:
print("ERROR: failed to optimize a SPIR-V shader")
print_error("failed to optimize a SPIR-V shader")
return 1
os.remove(spirv_glslang_file_path)
spirv_dis_file_path = f"{spirv_file_path_base}.txt"
if subprocess.call([spirv_dis, "-o", spirv_dis_file_path,
spirv_file_path]) != 0:
print("ERROR: failed to disassemble a SPIR-V shader")
print_error("failed to disassemble a SPIR-V shader")
return 1
# Generate the header from the disassembly and the binary.
@@ -1681,7 +1697,7 @@ def build_shaders(targets=None):
c = spirv_file.read(4)
while len(c) != 0:
if len(c) != 4:
print("ERROR: a SPIR-V shader is misaligned")
print_error("a SPIR-V shader is misaligned")
return 1
if index % 6 == 0:
out_file.write("\n ")
@@ -1745,7 +1761,7 @@ class TestCommand(BaseBuildCommand):
for test_target in test_targets]
for i in range(0, len(test_targets)):
if test_executables[i] is None:
print(f"ERROR: Unable to find {test_targets[i]} - build it.")
print_error(f"Unable to find {test_targets[i]} - build it.")
return 1
# Prepare environment with Qt bin directory in PATH if available
@@ -1797,10 +1813,10 @@ class TestCommand(BaseBuildCommand):
result = subprocess.call(cmd, env=test_env)
if result:
print(f"ERROR: {test_name} failed with {cpu_name}")
print_error(f"{test_name} failed with {cpu_name}")
any_failed = True
if not args["continue"]:
print("ERROR: test failed, aborting, use --continue to keep going.")
print_error("test failed, aborting, use --continue to keep going.")
return result
else:
# Non-CPU tests or SDE not available - run normally
@@ -1809,13 +1825,13 @@ class TestCommand(BaseBuildCommand):
if result:
any_failed = True
if args["continue"]:
print("ERROR: test failed but continuing due to --continue.")
print_error("test failed but continuing due to --continue.")
else:
print("ERROR: test failed, aborting, use --continue to keep going.")
print_error("test failed, aborting, use --continue to keep going.")
return result
if any_failed:
print("ERROR: one or more tests failed.")
print_error("one or more tests failed.")
result = 1
return result
@@ -1948,7 +1964,7 @@ class GenTestsCommand(Command):
print(f"- {src_file}")
if any_errors:
print("ERROR: failed to build one or more tests.")
print_error("failed to build one or more tests.")
return 1
return 0
@@ -1999,7 +2015,7 @@ class GpuTestCommand(BaseBuildCommand):
for test_target in test_targets]
for i in range(0, len(test_targets)):
if test_executables[i] is None:
print(f"ERROR: Unable to find {test_targets[i]} - build it.")
print_error(f"Unable to find {test_targets[i]} - build it.")
return 1
output_path = os.path.join(self_path, "build", "gputest")
@@ -2028,7 +2044,7 @@ class GpuTestCommand(BaseBuildCommand):
any_failed = True
if any_failed:
print("ERROR: one or more tests failed.")
print_error("one or more tests failed.")
result = 1
print(f"Check {output_path}/results.html for more details.")
return result
@@ -2056,7 +2072,7 @@ class CleanCommand(Command):
# Also clean generated files
clean_generated_files()
print("\nSuccess!")
print_status(ResultStatus.SUCCESS)
return 0
@@ -2125,7 +2141,7 @@ class NukeCommand(Command):
print("\n- running premake...")
run_platform_premake(target_os_override=args["target_os"])
print("\nSuccess!")
print_status(ResultStatus.SUCCESS)
return 0
@@ -2226,7 +2242,7 @@ class LintCommand(Command):
os.remove(difftemp)
print("")
if any_errors:
print("\nERROR: 1+ diffs. Stage changes and run 'xb format' to fix.")
print_error("1+ diffs. Stage changes and run 'xb format' to fix.")
return 1
else:
print("\nLinting completed successfully.")
@@ -2267,7 +2283,7 @@ class LintCommand(Command):
for generated_file in GENERATED_FILES:
cmd.append(f":(exclude){generated_file}")
shell_call(cmd, throw_on_error=False)
print("ERROR: 1+ diffs. Stage changes and run 'xb format' to fix.")
print_error("1+ diffs. Stage changes and run 'xb format' to fix.")
return 1
else:
print("Linting completed successfully.")
@@ -2309,7 +2325,7 @@ class FormatCommand(Command):
if ret:
any_errors = True
if any_errors:
print("\nERROR: 1+ clang-format calls failed."
print_error("1+ clang-format calls failed."
" Ensure all files are staged.")
return 1
else:
@@ -2363,7 +2379,7 @@ class StyleCommand(Command):
"--root=src",
] + all_files, throw_on_error=False)
if ret:
print("\nERROR: 1+ cpplint calls failed.")
print_error("1+ cpplint calls failed.")
return 1
else:
print("\nStyle linting completed successfully.")
@@ -2429,7 +2445,7 @@ class TidyCommand(Command):
any_errors = True
if any_errors:
print("\nERROR: 1+ clang-tidy calls failed.")
print_error("1+ clang-tidy calls failed.")
return 1
else:
print("\nTidy completed successfully.")
@@ -2482,7 +2498,7 @@ class StubCommand(Command):
print(f"Created file '{file_name}' at {target_dir}")
else:
print("ERROR: Please specify a file/class to generate")
print_error("Please specify a file/class to generate")
return 1
run_platform_premake(target_os_override=args["target_os"])
@@ -2504,7 +2520,7 @@ class DevenvCommand(Command):
show_reload_prompt = False
if sys.platform == "win32":
if not vs_version:
print("ERROR: Visual Studio is not installed.");
print_error("Visual Studio is not installed.");
return 1
print("Launching Visual Studio...")
elif sys.platform == "darwin":