diff --git a/build.sh b/build.sh index 25190dccfe..d84b67ee4b 100755 --- a/build.sh +++ b/build.sh @@ -196,7 +196,7 @@ case "$platform" in # Adjust compilation options based on platform Darwin) echo "Compiling for MacOS for $target_arch..." if [ "$target_arch" == "arm64" ]; then - macos_min_ver=12.7.5 + macos_min_ver=13.7.4 elif [ "$target_arch" == "x86_64" ]; then macos_min_ver=12.7.5 else diff --git a/debian/control b/debian/control index 45550f165e..eb495ec081 100644 --- a/debian/control +++ b/debian/control @@ -7,6 +7,7 @@ Build-Depends: debhelper (>= 11), git, python3:any, python3-yaml, + python3-venv, ninja-build, libgtk-3-dev, libepoxy-dev, diff --git a/hw/xbox/nv2a/pgraph/gl/draw.c b/hw/xbox/nv2a/pgraph/gl/draw.c index af87c41e28..bfa92662e7 100644 --- a/hw/xbox/nv2a/pgraph/gl/draw.c +++ b/hw/xbox/nv2a/pgraph/gl/draw.c @@ -332,13 +332,12 @@ void pgraph_gl_draw_begin(NV2AState *d) /* Surface clip */ /* FIXME: Consider moving to PSH w/ window clip */ - unsigned int xmin = pg->surface_shape.clip_x - pg->surface_binding_dim.clip_x, - ymin = pg->surface_shape.clip_y - pg->surface_binding_dim.clip_y; - unsigned int xmax = xmin + pg->surface_shape.clip_width - 1, - ymax = ymin + pg->surface_shape.clip_height - 1; + unsigned int xmin = pg->surface_shape.clip_x, + ymin = pg->surface_shape.clip_y; + + unsigned int scissor_width = pg->surface_shape.clip_width, + scissor_height = pg->surface_shape.clip_height; - unsigned int scissor_width = xmax - xmin + 1, - scissor_height = ymax - ymin + 1; pgraph_apply_anti_aliasing_factor(pg, &xmin, &ymin); pgraph_apply_anti_aliasing_factor(pg, &scissor_width, &scissor_height); ymin = pg->surface_binding_dim.height - (ymin + scissor_height); diff --git a/hw/xbox/nv2a/pgraph/gl/surface.c b/hw/xbox/nv2a/pgraph/gl/surface.c index cd6dd145ca..53df185130 100644 --- a/hw/xbox/nv2a/pgraph/gl/surface.c +++ b/hw/xbox/nv2a/pgraph/gl/surface.c @@ -582,9 +582,7 @@ static bool check_surface_compatibility(SurfaceBinding *s1, SurfaceBinding *s2, (s1->color == s2->color) && (s1->fmt.gl_attachment == s2->fmt.gl_attachment) && (s1->fmt.gl_internal_format == s2->fmt.gl_internal_format) && - (s1->pitch == s2->pitch) && - (s1->shape.clip_x <= s2->shape.clip_x) && - (s1->shape.clip_y <= s2->shape.clip_y); + (s1->pitch == s2->pitch); if (!format_compatible) { return false; } diff --git a/hw/xbox/nv2a/pgraph/gl/texture.c b/hw/xbox/nv2a/pgraph/gl/texture.c index 1f2d599eda..317fcc1070 100644 --- a/hw/xbox/nv2a/pgraph/gl/texture.c +++ b/hw/xbox/nv2a/pgraph/gl/texture.c @@ -467,12 +467,9 @@ static void upload_gl_texture(GLenum gl_target, 8 : 16; unsigned int physical_width = (width + 3) & ~3, physical_height = (height + 3) & ~3; - if (physical_width != width) { - glPixelStorei(GL_UNPACK_ROW_LENGTH, physical_width); - } uint8_t *converted = s3tc_decompress_2d( gl_internal_format_to_s3tc_enum(f.gl_internal_format), - texture_data, physical_width, physical_height); + texture_data, width, height); unsigned int tex_width = width; unsigned int tex_height = height; @@ -492,9 +489,6 @@ static void upload_gl_texture(GLenum gl_target, glTexImage2D(gl_target, level, GL_RGBA, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, converted); g_free(converted); - if (physical_width != width) { - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - } if (s.cubemap && adjusted_width != s.width) { glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); @@ -557,10 +551,10 @@ static void upload_gl_texture(GLenum gl_target, int level; for (level = 0; level < s.levels; level++) { if (f.gl_format == 0) { /* compressed */ - assert(width % 4 == 0 && height % 4 == 0 && - "Compressed 3D texture virtual size"); - width = MAX(width, 4); - height = MAX(height, 4); + width = MAX(width, 1); + height = MAX(height, 1); + unsigned int physical_width = (width + 3) & ~3, + physical_height = (height + 3) & ~3; depth = MAX(depth, 1); unsigned int block_size; @@ -570,7 +564,7 @@ static void upload_gl_texture(GLenum gl_target, block_size = 16; } - size_t texture_size = width/4 * height/4 * depth * block_size; + size_t texture_size = physical_width/4 * physical_height/4 * depth * block_size; uint8_t *converted = s3tc_decompress_3d( gl_internal_format_to_s3tc_enum(f.gl_internal_format), diff --git a/hw/xbox/nv2a/pgraph/glsl/psh.c b/hw/xbox/nv2a/pgraph/glsl/psh.c index a664281f09..e3a566a347 100644 --- a/hw/xbox/nv2a/pgraph/glsl/psh.c +++ b/hw/xbox/nv2a/pgraph/glsl/psh.c @@ -984,8 +984,8 @@ static MString* psh_convert(struct PixelShader *ps) } break; case PS_TEXTUREMODES_CUBEMAP: - mstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, pT%d.xyz / pT%d.w);\n", - i, i, i, i); + mstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, pT%d.xyz);\n", + i, i, i); break; case PS_TEXTUREMODES_PASSTHRU: assert(ps->state.border_logical_size[i][0] == 0.0f && "Unexpected border texture on passthru"); diff --git a/hw/xbox/nv2a/pgraph/s3tc.c b/hw/xbox/nv2a/pgraph/s3tc.c index affd058e66..ed9a600fe2 100644 --- a/hw/xbox/nv2a/pgraph/s3tc.c +++ b/hw/xbox/nv2a/pgraph/s3tc.c @@ -63,9 +63,10 @@ static void decode_bc1_colors(uint16_t c0, uint16_t c1, uint8_t r[4], } static void write_block_to_texture(uint8_t *converted_data, uint32_t indices, - int i, int j, int width, int z_pos_factor, - uint8_t r[4], uint8_t g[4], uint8_t b[4], - uint8_t a[16], bool separate_alpha) + int i, int j, int width, int height, + int z_pos_factor, uint8_t r[4], + uint8_t g[4], uint8_t b[4], uint8_t a[16], + bool separate_alpha) { int x0 = i * 4, y0 = j * 4; @@ -73,10 +74,10 @@ static void write_block_to_texture(uint8_t *converted_data, uint32_t indices, int x1 = x0 + 4, y1 = y0 + 4; - for (int y = y0; y < y1; y++) { + for (int y = y0; y < y1 && y < height; y++) { int y_index = 4 * (y - y0); int z_plus_y_pos_factor = z_pos_factor + y * width; - for (int x = x0; x < x1; x++) { + for (int x = x0; x < x1 && x < width; x++) { int xy_index = y_index + x - x0; uint8_t index = (indices >> 2 * xy_index) & 0x03; uint8_t alpha_index = separate_alpha ? xy_index : index; @@ -91,7 +92,7 @@ static void write_block_to_texture(uint8_t *converted_data, uint32_t indices, static void decompress_dxt1_block(const uint8_t block_data[8], uint8_t *converted_data, int i, int j, - int width, int z_pos_factor) + int width, int height, int z_pos_factor) { uint16_t c0 = ((uint16_t*)block_data)[0], c1 = ((uint16_t*)block_data)[1]; @@ -100,13 +101,13 @@ static void decompress_dxt1_block(const uint8_t block_data[8], uint32_t indices = ((uint32_t*)block_data)[1]; write_block_to_texture(converted_data, indices, - i, j, width, z_pos_factor, + i, j, width, height, z_pos_factor, r, g, b, a, false); } static void decompress_dxt3_block(const uint8_t block_data[16], uint8_t *converted_data, int i, int j, - int width, int z_pos_factor) + int width, int height, int z_pos_factor) { uint16_t c0 = ((uint16_t*)block_data)[4], c1 = ((uint16_t*)block_data)[5]; @@ -120,13 +121,13 @@ static void decompress_dxt3_block(const uint8_t block_data[16], uint32_t indices = ((uint32_t*)block_data)[3]; write_block_to_texture(converted_data, indices, - i, j, width, z_pos_factor, + i, j, width, height, z_pos_factor, r, g, b, a, true); } static void decompress_dxt5_block(const uint8_t block_data[16], uint8_t *converted_data, int i, int j, - int width, int z_pos_factor) + int width, int height, int z_pos_factor) { uint16_t c0 = ((uint16_t*)block_data)[4], c1 = ((uint16_t*)block_data)[5]; @@ -160,7 +161,7 @@ static void decompress_dxt5_block(const uint8_t block_data[16], uint32_t indices = ((uint32_t*)block_data)[3]; write_block_to_texture(converted_data, indices, - i, j, width, z_pos_factor, + i, j, width, height, z_pos_factor, r, g, b, a, true); } @@ -168,39 +169,41 @@ uint8_t *s3tc_decompress_3d(enum S3TC_DECOMPRESS_FORMAT color_format, const uint8_t *data, unsigned int width, unsigned int height, unsigned int depth) { - assert((width > 0) && (width % 4 == 0)); - assert((height > 0) && (height % 4 == 0)); - assert((depth > 0) && (depth < 4 || depth % 4 == 0)); - int block_depth = MIN(depth, 4); - int num_blocks_x = width/4, - num_blocks_y = height/4, - num_blocks_z = depth/block_depth; + assert(width > 0); + assert(height > 0); + assert(depth > 0); + unsigned int physical_width = (width + 3) & ~3, + physical_height = (height + 3) & ~3; + int num_blocks_x = physical_width/4, + num_blocks_y = physical_height/4, + num_blocks_z = (depth + 3)/4; uint8_t *converted_data = (uint8_t*)g_malloc(width * height * depth * 4); + int cur_depth = 0; + int sub_block_index = 0; for (int k = 0; k < num_blocks_z; k++) { + int residual_depth = depth - cur_depth; + int block_depth = MIN(residual_depth, 4); for (int j = 0; j < num_blocks_y; j++) { for (int i = 0; i < num_blocks_x; i++) { for (int slice = 0; slice < block_depth; slice++) { - - int block_index = k * num_blocks_y * num_blocks_x + j * num_blocks_x + i; - int sub_block_index = block_index * block_depth + slice; - int z_pos_factor = (k * block_depth + slice) * width * height; - + int z_pos_factor = (cur_depth + slice) * width * height; if (color_format == S3TC_DECOMPRESS_FORMAT_DXT1) { decompress_dxt1_block(data + 8 * sub_block_index, converted_data, - i, j, width, z_pos_factor); + i, j, width, height, z_pos_factor); } else if (color_format == S3TC_DECOMPRESS_FORMAT_DXT3) { decompress_dxt3_block(data + 16 * sub_block_index, converted_data, - i, j, width, z_pos_factor); + i, j, width, height, z_pos_factor); } else if (color_format == S3TC_DECOMPRESS_FORMAT_DXT5) { decompress_dxt5_block(data + 16 * sub_block_index, converted_data, - i, j, width, z_pos_factor); + i, j, width, height, z_pos_factor); } else { assert(false); } - + sub_block_index++; } } } + cur_depth += block_depth; } return converted_data; } @@ -209,22 +212,24 @@ uint8_t *s3tc_decompress_2d(enum S3TC_DECOMPRESS_FORMAT color_format, const uint8_t *data, unsigned int width, unsigned int height) { - assert((width > 0) && (width % 4 == 0)); - assert((height > 0) && (height % 4 == 0)); - int num_blocks_x = width / 4, num_blocks_y = height / 4; + assert(width > 0); + assert(height > 0); + unsigned int physical_width = (width + 3) & ~3, + physical_height = (height + 3) & ~3; + int num_blocks_x = physical_width / 4, num_blocks_y = physical_height / 4; uint8_t *converted_data = (uint8_t *)g_malloc(width * height * 4); for (int j = 0; j < num_blocks_y; j++) { for (int i = 0; i < num_blocks_x; i++) { int block_index = j * num_blocks_x + i; if (color_format == S3TC_DECOMPRESS_FORMAT_DXT1) { decompress_dxt1_block(data + 8 * block_index, - converted_data, i, j, width, 0); + converted_data, i, j, width, height, 0); } else if (color_format == S3TC_DECOMPRESS_FORMAT_DXT3) { decompress_dxt3_block(data + 16 * block_index, - converted_data, i, j, width, 0); + converted_data, i, j, width, height, 0); } else if (color_format == S3TC_DECOMPRESS_FORMAT_DXT5) { decompress_dxt5_block(data + 16 * block_index, - converted_data, i, j, width, 0); + converted_data, i, j, width, height, 0); } else { assert(false); } diff --git a/hw/xbox/nv2a/pgraph/vk/draw.c b/hw/xbox/nv2a/pgraph/vk/draw.c index f34b6aa094..c082c5cfb4 100644 --- a/hw/xbox/nv2a/pgraph/vk/draw.c +++ b/hw/xbox/nv2a/pgraph/vk/draw.c @@ -1472,16 +1472,11 @@ static void begin_draw(PGRAPHState *pg) /* Surface clip */ /* FIXME: Consider moving to PSH w/ window clip */ - unsigned int xmin = pg->surface_shape.clip_x - - pg->surface_binding_dim.clip_x, - ymin = pg->surface_shape.clip_y - - pg->surface_binding_dim.clip_y; + unsigned int xmin = pg->surface_shape.clip_x, + ymin = pg->surface_shape.clip_y; - unsigned int xmax = xmin + pg->surface_shape.clip_width - 1, - ymax = ymin + pg->surface_shape.clip_height - 1; - - unsigned int scissor_width = xmax - xmin + 1, - scissor_height = ymax - ymin + 1; + unsigned int scissor_width = pg->surface_shape.clip_width, + scissor_height = pg->surface_shape.clip_height; pgraph_apply_anti_aliasing_factor(pg, &xmin, &ymin); pgraph_apply_anti_aliasing_factor(pg, &scissor_width, &scissor_height); diff --git a/hw/xbox/nv2a/pgraph/vk/surface.c b/hw/xbox/nv2a/pgraph/vk/surface.c index 2ce4f84695..5636ecb4b8 100644 --- a/hw/xbox/nv2a/pgraph/vk/surface.c +++ b/hw/xbox/nv2a/pgraph/vk/surface.c @@ -890,9 +890,7 @@ static bool check_surface_compatibility(SurfaceBinding const *s1, bool format_compatible = (s1->color == s2->color) && (s1->host_fmt.vk_format == s2->host_fmt.vk_format) && - (s1->pitch == s2->pitch) && - (s1->shape.clip_x <= s2->shape.clip_x) && - (s1->shape.clip_y <= s2->shape.clip_y); + (s1->pitch == s2->pitch); if (!format_compatible) { return false; } diff --git a/hw/xbox/nv2a/pgraph/vk/texture.c b/hw/xbox/nv2a/pgraph/vk/texture.c index c5d3cf7fe2..69043b2e04 100644 --- a/hw/xbox/nv2a/pgraph/vk/texture.c +++ b/hw/xbox/nv2a/pgraph/vk/texture.c @@ -246,14 +246,11 @@ static TextureLayout *get_texture_layout(PGRAPHState *pg, int texture_idx) unsigned int tex_width = width, tex_height = height; unsigned int physical_width = (width + 3) & ~3, physical_height = (height + 3) & ~3; - // if (physical_width != width) { - // glPixelStorei(GL_UNPACK_ROW_LENGTH, physical_width); - // } size_t converted_size = width * height * 4; uint8_t *converted = s3tc_decompress_2d( kelvin_format_to_s3tc_format(s.color_format), - texture_data_ptr, physical_width, physical_height); + texture_data_ptr, width, height); assert(converted); if (s.cubemap && adjusted_width != s.width) { @@ -335,11 +332,10 @@ static TextureLayout *get_texture_layout(PGRAPHState *pg, int texture_idx) for (int level = 0; level < s.levels; level++) { if (is_compressed) { - assert(width % 4 == 0 && height % 4 == 0 && - "Compressed 3D texture virtual size"); - - width = MAX(width, 4); - height = MAX(height, 4); + width = MAX(width, 1); + height = MAX(height, 1); + unsigned int physical_width = (width + 3) & ~3, + physical_height = (height + 3) & ~3; depth = MAX(depth, 1); size_t converted_size = width * height * depth * 4; @@ -356,7 +352,7 @@ static TextureLayout *get_texture_layout(PGRAPHState *pg, int texture_idx) .decoded_data = converted, }; - texture_data_ptr += width / 4 * height / 4 * depth * block_size; + texture_data_ptr += physical_width / 4 * physical_height / 4 * depth * block_size; } else { width = MAX(width, 1); height = MAX(height, 1); diff --git a/scripts/download-macos-libs.py b/scripts/download-macos-libs.py index 3967f75385..c58703db72 100755 --- a/scripts/download-macos-libs.py +++ b/scripts/download-macos-libs.py @@ -10,8 +10,7 @@ import os.path from tarfile import TarFile import subprocess -# MIRROR = 'http://packages.macports.org/macports/packages' -MIRROR = 'http://nue.de.packages.macports.org/macports/packages' +MIRROR = 'https://packages.macports.org' # FIXME: Inline macports key # FIXME: Move packages to archive directory to track used vs unused @@ -19,7 +18,7 @@ MIRROR = 'http://nue.de.packages.macports.org/macports/packages' class LibInstaller: DARWIN_TARGET_X64="darwin_17" # macOS 10.13 - DARWIN_TARGET_ARM64="darwin_21" # macOS 12.x + DARWIN_TARGET_ARM64="darwin_22" # macOS 13.x def __init__(self, arch): self._queue = [] diff --git a/scripts/xemu-version.sh b/scripts/xemu-version.sh index 95ed0cd2a6..0e5b827acc 100755 --- a/scripts/xemu-version.sh +++ b/scripts/xemu-version.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash set -eu @@ -26,6 +26,10 @@ XEMU_VERSION=$( \ cat XEMU_VERSION; \ fi) +if [[ "${XEMU_VERSION}" == "" ]]; then + XEMU_VERSION="0.0.0" +fi + get_version_field() { echo ${XEMU_VERSION}-0 | cut -d- -f$1 }