diff --git a/src/compiler/nir/nir_lower_frag_coord_to_pixel_coord.c b/src/compiler/nir/nir_lower_frag_coord_to_pixel_coord.c index db0d4093f61..db97c7f1941 100644 --- a/src/compiler/nir/nir_lower_frag_coord_to_pixel_coord.c +++ b/src/compiler/nir/nir_lower_frag_coord_to_pixel_coord.c @@ -13,13 +13,11 @@ lower(nir_builder *b, nir_intrinsic_instr *intr, UNUSED void *data) if (intr->intrinsic != nir_intrinsic_load_frag_coord) return false; - /* load_pixel_coord gives the top-left corner of the pixel, but frag_coord - * should return the centre of the pixel. + /* Note: frag_coord should already have pixel-center lowering applied with + * nir_lower_wpos_center for VK, or PIPE_CAP_PIXEL_CENTER_INTEGER for GL. */ b->cursor = nir_before_instr(&intr->instr); - nir_def *top_left_xy = nir_u2f32(b, nir_load_pixel_coord(b)); - nir_def *xy = nir_fadd_imm(b, top_left_xy, 0.5); - + nir_def *xy = nir_u2f32(b, nir_load_pixel_coord(b)); nir_def *vec = nir_vec4(b, nir_channel(b, xy, 0), nir_channel(b, xy, 1), nir_load_frag_coord_zw(b, .component = 2), nir_load_frag_coord_zw(b, .component = 3)); diff --git a/src/gallium/drivers/asahi/agx_pipe.c b/src/gallium/drivers/asahi/agx_pipe.c index 329b9469f27..5f49e69cfbb 100644 --- a/src/gallium/drivers/asahi/agx_pipe.c +++ b/src/gallium/drivers/asahi/agx_pipe.c @@ -1670,13 +1670,13 @@ agx_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 12; case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT: - case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER: case PIPE_CAP_TGSI_TEXCOORD: case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL: case PIPE_CAP_FS_POSITION_IS_SYSVAL: return true; case PIPE_CAP_FS_COORD_ORIGIN_LOWER_LEFT: - case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER: + case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER: case PIPE_CAP_FS_POINT_IS_SYSVAL: return false; diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c index af254105b98..13e4c6ba83c 100644 --- a/src/gallium/drivers/panfrost/pan_screen.c +++ b/src/gallium/drivers/panfrost/pan_screen.c @@ -242,13 +242,17 @@ panfrost_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return PAN_MAX_MIP_LEVELS; - case PIPE_CAP_FS_COORD_ORIGIN_LOWER_LEFT: + /* pixel coord is in integer sysval on bifrost. */ case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER: - /* Hardware is upper left. Pixel center at (0.5, 0.5) */ + return dev->arch >= 6; + case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return dev->arch < 6; + + case PIPE_CAP_FS_COORD_ORIGIN_LOWER_LEFT: + /* Hardware is upper left */ return 0; case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT: - case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER: case PIPE_CAP_TGSI_TEXCOORD: return 1; diff --git a/src/panfrost/util/pan_lower_sample_position.c b/src/panfrost/util/pan_lower_sample_position.c index 1bf4efd3de7..e24019cc728 100644 --- a/src/panfrost/util/pan_lower_sample_position.c +++ b/src/panfrost/util/pan_lower_sample_position.c @@ -36,7 +36,8 @@ static bool pan_lower_sample_pos_impl(struct nir_builder *b, nir_intrinsic_instr *intr, UNUSED void *data) { - if (intr->intrinsic != nir_intrinsic_load_sample_pos) + if (intr->intrinsic != nir_intrinsic_load_sample_pos && + intr->intrinsic != nir_intrinsic_load_sample_pos_or_center) return false; b->cursor = nir_before_instr(&intr->instr); diff --git a/src/panfrost/vulkan/panvk_vX_shader.c b/src/panfrost/vulkan/panvk_vX_shader.c index e22be36bc8a..cec8e01b0a5 100644 --- a/src/panfrost/vulkan/panvk_vX_shader.c +++ b/src/panfrost/vulkan/panvk_vX_shader.c @@ -318,6 +318,9 @@ panvk_per_arch(shader_create)(struct panvk_device *dev, NIR_PASS_V(nir, nir_lower_compute_system_values, &options); + if (nir->info.stage == MESA_SHADER_FRAGMENT) + NIR_PASS_V(nir, nir_lower_wpos_center); + NIR_PASS_V(nir, nir_split_var_copies); NIR_PASS_V(nir, nir_lower_var_copies);