diff --git a/src/imagination/common/pvr_device_info.c b/src/imagination/common/pvr_device_info.c index c1dd1dbd01a..85161bb5027 100644 --- a/src/imagination/common/pvr_device_info.c +++ b/src/imagination/common/pvr_device_info.c @@ -151,6 +151,7 @@ const struct pvr_device_features pvr_device_features_33_V_11_3 = { .has_tile_size_16x16 = true, .has_tile_size_x = true, .has_tile_size_y = true, + .has_tpu_border_colour_enhanced = true, .has_tpu_extended_integer_lookup = true, .has_tpu_image_state_v2 = true, .has_usc_f16sop_u8 = true, @@ -235,6 +236,7 @@ const struct pvr_device_features pvr_device_features_36_V_104_796 = { .has_tile_size_16x16 = true, .has_tile_size_x = true, .has_tile_size_y = true, + .has_tpu_border_colour_enhanced = true, .has_tpu_extended_integer_lookup = true, .has_tpu_image_state_v2 = true, .has_usc_f16sop_u8 = true, diff --git a/src/imagination/common/pvr_device_info.h b/src/imagination/common/pvr_device_info.h index ed8286d5e1d..8fdb26d551c 100644 --- a/src/imagination/common/pvr_device_info.h +++ b/src/imagination/common/pvr_device_info.h @@ -286,6 +286,7 @@ struct pvr_device_features { bool has_tile_size_x : 1; bool has_tile_size_y : 1; bool has_tpu_array_textures : 1; + bool has_tpu_border_colour_enhanced : 1; bool has_tpu_extended_integer_lookup : 1; bool has_tpu_image_state_v2 : 1; bool has_usc_f16sop_u8 : 1; diff --git a/src/imagination/csbgen/rogue_texstate.xml b/src/imagination/csbgen/rogue_texstate.xml index 79c91eb56f0..dd181556758 100644 --- a/src/imagination/csbgen/rogue_texstate.xml +++ b/src/imagination/csbgen/rogue_texstate.xml @@ -267,7 +267,9 @@ SOFTWARE. - + + + @@ -325,7 +327,9 @@ SOFTWARE. - + + + diff --git a/src/imagination/vulkan/meson.build b/src/imagination/vulkan/meson.build index fa034c95b09..6a16acf82fd 100644 --- a/src/imagination/vulkan/meson.build +++ b/src/imagination/vulkan/meson.build @@ -39,6 +39,7 @@ pvr_files = files( 'winsys/pvr_winsys_helper.c', 'pvr_blit.c', 'pvr_bo.c', + 'pvr_border.c', 'pvr_clear.c', 'pvr_cmd_buffer.c', 'pvr_csb.c', @@ -111,7 +112,7 @@ endif libvulkan_powervr_mesa = shared_library( 'vulkan_powervr_mesa', - [pvr_files, pvr_entrypoints], + [pvr_files, pvr_entrypoints, u_format_pack_h], include_directories : [ pvr_includes, inc_gallium_aux, diff --git a/src/imagination/vulkan/pvr_border.c b/src/imagination/vulkan/pvr_border.c new file mode 100644 index 00000000000..f2d874f183d --- /dev/null +++ b/src/imagination/vulkan/pvr_border.c @@ -0,0 +1,1147 @@ +/* + * Copyright © 2023 Imagination Technologies Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include + +#include "hwdef/rogue_hw_utils.h" +#include "pvr_border.h" +#include "pvr_csb.h" +#include "pvr_device_info.h" +#include "pvr_private.h" +#include "util/bitset.h" +#include "util/format_r11g11b10f.h" +#include "util/format_rgb9e5.h" +#include "util/format/format_utils.h" +#include "util/format/u_format_pack.h" +#include "util/macros.h" +#include "util/u_endian.h" +#include "vk_sampler.h" +#include "vk_util.h" + +#define PVR_BORDER_COLOR_TABLE_NR_FORMATS \ + (PVRX(TEXSTATE_IMAGE_WORD0_TEXFORMAT_MAX_SIZE) + 1) + +/* TODO: Eliminate all of these format-wrangling macros & functions by encoding + * our internal formats in a csv (a la src/mesa/main/formats.csv) + */ + +#define intx(i, b) (i & BITFIELD_MASK(b)) +#define normx(n, b) _mesa_float_to_unorm(n, b) +#define snormx(s, b) _mesa_float_to_snorm(s, b) + +#define int1(i) intx(i, 1) +#define int2(i) intx(i, 2) +#define int3(i) intx(i, 3) +#define int4(i) intx(i, 4) +#define int5(i) intx(i, 5) +#define int6(i) intx(i, 6) +#define int8(i) intx(i, 8) +#define int10(i) intx(i, 10) +#define int16(i) intx(i, 16) +#define int24(i) intx(i, 24) +#define int32(i) intx(i, 32) + +#define norm1(n) normx(n, 1) +#define norm2(n) normx(n, 2) +#define norm3(n) normx(n, 3) +#define norm4(n) normx(n, 4) +#define norm5(n) normx(n, 5) +#define norm6(n) normx(n, 6) +#define norm8(n) normx(n, 8) +#define norm10(n) normx(n, 10) +#define norm16(n) normx(n, 16) +#define norm24(n) normx(n, 24) +#define norm32(n) normx(n, 32) + +#define snorm5(s) snormx(s, 5) +#define snorm8(s) snormx(s, 8) +#define snorm16(s) snormx(s, 16) +#define snorm32(s) snormx(s, 32) + +#define zero8 (0) +#define zero10 (0) +#define zero24 (0) +#define zero32 (0) + +#define float10(f) f32_to_uf10(f) +#define float11(f) f32_to_uf11(f) +#define float16(f) ((uint32_t)_mesa_float_to_half(f)) +#define float32(f) ((uint32_t)(f)) + +union pvr_border_color_table_value { + struct { + uint32_t w0, w1, w2, w3; + }; + uint32_t arr[4]; + uint8_t bytes[16]; +} PACKED; +static_assert(sizeof(union pvr_border_color_table_value) == + 4 * sizeof(uint32_t), + "pvr_border_color_table_value must be 4 x u32"); + +struct pvr_border_color_table_entry { + union pvr_border_color_table_value formats[PVR_BORDER_COLOR_TABLE_NR_FORMATS]; + union pvr_border_color_table_value + compressed_formats[PVR_BORDER_COLOR_TABLE_NR_FORMATS]; +} PACKED; + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i8(const uint32_t i0) +{ + return (union pvr_border_color_table_value){ + .w0 = int8(i0), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i8i8(const uint32_t i0, const uint32_t i1) +{ + return (union pvr_border_color_table_value){ + .w0 = int8(i0) | int8(i1) << 8, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i8i8i8(const uint32_t i0, + const uint32_t i1, + const uint32_t i2) +{ + return (union pvr_border_color_table_value){ + .w0 = int8(i0) | int8(i1) << 8 | int8(i2) << 16, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i8i8i8i8(const uint32_t i0, + const uint32_t i1, + const uint32_t i2, + const uint32_t i3) +{ + return (union pvr_border_color_table_value){ + .w0 = int8(i0) | int8(i1) << 8 | int8(i2) << 16 | int8(i3) << 24, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i8i8i8x8(const uint32_t i0, + const uint32_t i1, + const uint32_t i2) +{ + return (union pvr_border_color_table_value){ + .w0 = int8(i0) | int8(i1) << 8 | int8(i2) << 16 | zero8 << 24, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i16(const uint32_t i0) +{ + return (union pvr_border_color_table_value){ + .w0 = int16(i0), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i16i16(const uint32_t i0, const uint32_t i1) +{ + return (union pvr_border_color_table_value){ + .w0 = int16(i0) | int16(i1) << 16, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i16i16i16(const uint32_t i0, + const uint32_t i1, + const uint32_t i2) +{ + return (union pvr_border_color_table_value){ + .w0 = int16(i0) | int16(i1) << 16, + .w1 = int16(i2), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i16i16i16i16(const uint32_t i0, + const uint32_t i1, + const uint32_t i2, + const uint32_t i3) +{ + return (union pvr_border_color_table_value){ + .w0 = int16(i0) | int16(i1) << 16, + .w1 = int16(i2) | int16(i3) << 16, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i32(const uint32_t i0) +{ + return (union pvr_border_color_table_value){ + .w0 = int32(i0), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i32i32(const uint32_t i0, const uint32_t i1) +{ + return (union pvr_border_color_table_value){ + .w0 = int32(i0), + .w1 = int32(i1), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i32i32i32(const uint32_t i0, + const uint32_t i1, + const uint32_t i2) +{ + return (union pvr_border_color_table_value){ + .w0 = int32(i0), + .w1 = int32(i1), + .w2 = int32(i2), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i32i32i32i32(const uint32_t i0, + const uint32_t i1, + const uint32_t i2, + const uint32_t i3) +{ + return (union pvr_border_color_table_value){ + .w0 = int32(i0), + .w1 = int32(i1), + .w2 = int32(i2), + .w3 = int32(i3), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i4i4i4i4(const uint32_t i0, + const uint32_t i1, + const uint32_t i2, + const uint32_t i3) +{ + return (union pvr_border_color_table_value){ + .w0 = int4(i0) | int4(i1) << 4 | int4(i2) << 8 | int4(i3) << 12, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i2i3i3i8(const uint32_t i0, + const uint32_t i1, + const uint32_t i2, + const uint32_t i3) +{ + return (union pvr_border_color_table_value){ + .w0 = int2(i0) | int3(i1) << 2 | int3(i2) << 5 | int8(i3) << 8, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i5i5i5i1(const uint32_t i0, + const uint32_t i1, + const uint32_t i2, + const uint32_t i3) +{ + return (union pvr_border_color_table_value){ + .w0 = int5(i0) | int5(i1) << 5 | int5(i2) << 10 | int1(i3) << 15, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i1i5i5i5(const uint32_t i0, + const uint32_t i1, + const uint32_t i2, + const uint32_t i3) +{ + return (union pvr_border_color_table_value){ + .w0 = int1(i0) | int5(i1) << 1 | int5(i2) << 6 | int5(i3) << 11, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i5i6i5(const uint32_t i0, + const uint32_t i1, + const uint32_t i2) +{ + return (union pvr_border_color_table_value){ + .w0 = int5(i0) | int6(i1) << 5 | int5(i2) << 11, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i6i5i5(const uint32_t i0, + const uint32_t i1, + const uint32_t i2) +{ + return (union pvr_border_color_table_value){ + .w0 = int6(i0) | int5(i1) << 6 | int5(i2) << 11, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i5i5i6(const uint32_t i0, + const uint32_t i1, + const uint32_t i2) +{ + return (union pvr_border_color_table_value){ + .w0 = int5(i0) | int5(i1) << 5 | int6(i2) << 10, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i10i10i10i2(const uint32_t i0, + const uint32_t i1, + const uint32_t i2, + const uint32_t i3) +{ + return (union pvr_border_color_table_value){ + .w0 = int10(i0) | int10(i1) << 10 | int10(i2) << 20 | int2(i3) << 30, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_x10x10x10i2(const uint32_t i3) +{ + return (union pvr_border_color_table_value){ + .w0 = zero10 | zero10 << 10 | zero10 << 20 | int2(i3) << 30, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i2i10i10i10(const uint32_t i0, + const uint32_t i1, + const uint32_t i2, + const uint32_t i3) +{ + return (union pvr_border_color_table_value){ + .w0 = int2(i0) | int10(i1) << 2 | int10(i2) << 12 | int10(i3) << 22, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i2x10x10x10(const uint32_t i0) +{ + return (union pvr_border_color_table_value){ + .w0 = int2(i0) | zero10 << 2 | zero10 << 12 | zero10 << 22, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i24i8(const uint32_t i0, const uint32_t i1) +{ + return (union pvr_border_color_table_value){ + .w0 = int24(i0) | int8(i1) << 24, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i24x8(const uint32_t i0) +{ + return (union pvr_border_color_table_value){ + .w0 = int24(i0) | zero8 << 24, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_x24i8(const uint32_t i1) +{ + return (union pvr_border_color_table_value){ + .w0 = zero24 | int8(i1) << 24, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_i8i24(const uint32_t i0, const uint32_t i1) +{ + return (union pvr_border_color_table_value){ + .w0 = int8(i0) | int24(i1) << 8, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_x32i8x24(const uint32_t i1) +{ + return (union pvr_border_color_table_value){ + .w0 = zero32, + .w1 = int8(i1) | zero24 << 8, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n8(const float n0) +{ + return (union pvr_border_color_table_value){ + .w0 = norm8(n0), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n8n8(const float n0, const float n1) +{ + return (union pvr_border_color_table_value){ + .w0 = norm8(n0) | norm8(n1) << 8, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n8n8n8(const float n0, const float n1, const float n2) +{ + return (union pvr_border_color_table_value){ + .w0 = norm8(n0) | norm8(n1) << 8 | norm8(n2) << 16, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n8n8n8n8(const float n0, + const float n1, + const float n2, + const float n3) +{ + return (union pvr_border_color_table_value){ + .w0 = norm8(n0) | norm8(n1) << 8 | norm8(n2) << 16 | norm8(n3) << 24, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n8n8n8x8(const float n0, const float n1, const float n2) +{ + return (union pvr_border_color_table_value){ + .w0 = norm8(n0) | norm8(n1) << 8 | norm8(n2) << 16 | zero8 << 24, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n8s8s8x8(const float n0, const float s1, const float s2) +{ + return (union pvr_border_color_table_value){ + .w0 = norm8(n0) | snorm8(s1) << 8 | snorm8(s2) << 16 | zero8 << 24, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_s8(const float s0) +{ + return (union pvr_border_color_table_value){ + .w0 = snorm8(s0), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_s8s8(const float s0, const float s1) +{ + return (union pvr_border_color_table_value){ + .w0 = snorm8(s0) | snorm8(s1) << 8, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_s8s8s8(const float s0, const float s1, const float s2) +{ + return (union pvr_border_color_table_value){ + .w0 = snorm8(s0) | snorm8(s1) << 8 | snorm8(s2) << 16, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_s8s8s8s8(const float s0, + const float s1, + const float s2, + const float s3) +{ + return (union pvr_border_color_table_value){ + .w0 = snorm8(s0) | snorm8(s1) << 8 | snorm8(s2) << 16 | snorm8(s3) << 24, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n16(const float n0) +{ + return (union pvr_border_color_table_value){ + .w0 = norm16(n0), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n16n16(const float n0, const float n1) +{ + return (union pvr_border_color_table_value){ + .w0 = norm16(n0) | norm16(n1) << 16, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n16n16n16(const float n0, const float n1, const float n2) +{ + return (union pvr_border_color_table_value){ + .w0 = norm16(n0) | norm16(n1) << 16, + .w1 = norm16(n2), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n16n16n16n16(const float n0, + const float n1, + const float n2, + const float n3) +{ + return (union pvr_border_color_table_value){ + .w0 = norm16(n0) | norm16(n1) << 16, + .w1 = norm16(n2) | norm16(n3) << 16, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_s16(const float s0) +{ + return (union pvr_border_color_table_value){ + .w0 = snorm16(s0), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_s16s16(const float s0, const float s1) +{ + return (union pvr_border_color_table_value){ + .w0 = snorm16(s0) | snorm16(s1) << 16, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_s16s16s16(const float s0, const float s1, const float s2) +{ + return (union pvr_border_color_table_value){ + .w0 = snorm16(s0) | snorm16(s1) << 16, + .w1 = snorm16(s2), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_s16s16s16s16(const float s0, + const float s1, + const float s2, + const float s3) +{ + return (union pvr_border_color_table_value){ + .w0 = snorm16(s0) | snorm16(s1) << 16, + .w1 = snorm16(s2) | snorm16(s3) << 16, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n32(const float n0) +{ + return (union pvr_border_color_table_value){ + .w0 = norm32(n0), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n32n32(const float n0, const float n1) +{ + return (union pvr_border_color_table_value){ + .w0 = norm32(n0), + .w1 = norm32(n1), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n32n32n32(const float n0, const float n1, const float n2) +{ + return (union pvr_border_color_table_value){ + .w0 = norm32(n0), + .w1 = norm32(n1), + .w2 = norm32(n2), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n32n32n32n32(const float n0, + const float n1, + const float n2, + const float n3) +{ + return (union pvr_border_color_table_value){ + .w0 = norm32(n0), + .w1 = norm32(n1), + .w2 = norm32(n2), + .w3 = norm32(n3), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_s32(const float s0) +{ + return (union pvr_border_color_table_value){ + .w0 = snorm32(s0), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_s32s32(const float s0, const float s1) +{ + return (union pvr_border_color_table_value){ + .w0 = snorm32(s0), + .w1 = snorm32(s1), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_s32s32s32(const float s0, const float s1, const float s2) +{ + return (union pvr_border_color_table_value){ + .w0 = snorm32(s0), + .w1 = snorm32(s1), + .w2 = snorm32(s2), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_s32s32s32s32(const float s0, + const float s1, + const float s2, + const float s3) +{ + return (union pvr_border_color_table_value){ + .w0 = snorm32(s0), + .w1 = snorm32(s1), + .w2 = snorm32(s2), + .w3 = snorm32(s3), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n4n4n4n4(const float n0, + const float n1, + const float n2, + const float n3) +{ + return (union pvr_border_color_table_value){ + .w0 = norm4(n0) | norm4(n1) << 4 | norm4(n2) << 8 | norm4(n3) << 12, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n2n3n3n8(const float n0, + const float n1, + const float n2, + const float n3) +{ + return (union pvr_border_color_table_value){ + .w0 = norm2(n0) | norm3(n1) << 2 | norm3(n2) << 5 | norm8(n3) << 8, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n5n5n5n1(const float n0, + const float n1, + const float n2, + const float n3) +{ + return (union pvr_border_color_table_value){ + .w0 = norm5(n0) | norm5(n1) << 5 | norm5(n2) << 10 | norm1(n3) << 15, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n1n5n5n5(const float n0, + const float n1, + const float n2, + const float n3) +{ + return (union pvr_border_color_table_value){ + .w0 = norm1(n0) | norm5(n1) << 1 | norm5(n2) << 6 | norm5(n3) << 11, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n5n6n5(const float n0, const float n1, const float n2) +{ + return (union pvr_border_color_table_value){ + .w0 = norm5(n0) | norm6(n1) << 5 | norm5(n2) << 11, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n6s5s5(const float n0, const float s1, const float s2) +{ + return (union pvr_border_color_table_value){ + .w0 = norm6(n0) | snorm5(s1) << 6 | snorm5(s2) << 11, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_s5s5n6(const float s0, const float s1, const float n2) +{ + return (union pvr_border_color_table_value){ + .w0 = snorm5(s0) | snorm5(s1) << 5 | norm6(n2) << 10, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n10n10n10n2(const float n0, + const float n1, + const float n2, + const float n3) +{ + return (union pvr_border_color_table_value){ + .w0 = norm10(n0) | norm10(n1) << 10 | norm10(n2) << 20 | norm2(n3) << 30, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_f10f10f10n2(const float f0, + const float f1, + const float f2, + const float n3) +{ + return (union pvr_border_color_table_value){ + .w0 = float10(f0) | float10(f1) << 10 | float10(f2) << 20 | + norm2(n3) << 30, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n2n10n10n10(const float n0, + const float n1, + const float n2, + const float n3) +{ + return (union pvr_border_color_table_value){ + .w0 = norm2(n0) | norm10(n1) << 2 | norm10(n2) << 12 | norm10(n3) << 22, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n2f10f10f10(const float n0, + const float f1, + const float f2, + const float f3) +{ + return (union pvr_border_color_table_value){ + .w0 = norm2(n0) | float10(f1) << 2 | float10(f2) << 12 | + float10(f3) << 22, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n24n8(const float n0, const float n1) +{ + return (union pvr_border_color_table_value){ + .w0 = norm24(n0) | norm8(n1) << 24, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n24x8(const float n0) +{ + return (union pvr_border_color_table_value){ + .w0 = norm24(n0) | zero8 << 24, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_x24n8(const float n1) +{ + return (union pvr_border_color_table_value){ + .w0 = zero24 | norm8(n1) << 24, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_n8n24(const float n0, const float n1) +{ + return (union pvr_border_color_table_value){ + .w0 = norm8(n0) | norm24(n1) << 8, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_f32n8x24(const float f0, const float n1) +{ + return (union pvr_border_color_table_value){ + .w0 = float32(f0), + .w1 = norm8(n1) | zero24 << 8, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_f32x8x24(const float f0) +{ + return (union pvr_border_color_table_value){ + .w0 = float32(f0), + .w1 = zero8 | zero24 << 8, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_x32n8x24(const float n1) +{ + return (union pvr_border_color_table_value){ + .w0 = zero32, + .w1 = norm8(n1) | zero24 << 8, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_f16(const float f0) +{ + return (union pvr_border_color_table_value){ + .w0 = float16(f0), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_f16f16(const float f0, const float f1) +{ + return (union pvr_border_color_table_value){ + .w0 = float16(f0) | float16(f1) << 16, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_f16f16f16(const float f0, const float f1, const float f2) +{ + return (union pvr_border_color_table_value){ + .w0 = float16(f0) | float16(f1) << 16, + .w1 = float16(f2), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_f16f16f16f16(const float f0, + const float f1, + const float f2, + const float f3) +{ + return (union pvr_border_color_table_value){ + .w0 = float16(f0) | float16(f1) << 16, + .w1 = float16(f2) | float16(f3) << 16, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_f32(const float f0) +{ + return (union pvr_border_color_table_value){ + .w0 = float32(f0), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_g32(const float g0) +{ + return (union pvr_border_color_table_value){ + .w0 = float32(g0) & 0x7fffffff, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_f32f32(const float f0, const float f1) +{ + return (union pvr_border_color_table_value){ + .w0 = float32(f0), + .w1 = float32(f1), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_f32f32f32(const float f0, const float f1, const float f2) +{ + return (union pvr_border_color_table_value){ + .w0 = float32(f0), + .w1 = float32(f1), + .w2 = float32(f2), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_f32f32f32f32(const float f0, + const float f1, + const float f2, + const float f3) +{ + return (union pvr_border_color_table_value){ + .w0 = float32(f0), + .w1 = float32(f1), + .w2 = float32(f2), + .w3 = float32(f3), + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_f10f11f11(const float f0, const float f1, const float f2) +{ + return (union pvr_border_color_table_value){ + .w0 = float10(f0) | float11(f1) << 10 | float11(f2) << 21, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_f11f11f10(const float f0, const float f1, const float f2) +{ + return (union pvr_border_color_table_value){ + .w0 = float11(f0) | float11(f1) << 11 | float10(f2) << 22, + }; +} + +static inline union pvr_border_color_table_value +pvr_pack_border_color_e9e9e9x5(const float f0, const float f1, const float f2) +{ + return (union pvr_border_color_table_value){ + .w0 = float3_to_rgb9e5((float[3]){ f0, f1, f2 }), + }; +} + +#define PACK(format_, layout_, channels_...) \ + entry->formats[PVRX(TEXSTATE_FORMAT_##format_)] = \ + pvr_pack_border_color_##layout_(channels_) + +/* clang-format off */ +#define UDEF(format_) \ + entry->formats[PVRX(TEXSTATE_FORMAT_##format_)] = \ + (union pvr_border_color_table_value){ 0 } +/* clang-format on */ + +static void +pvr_pack_border_color_ints(struct pvr_border_color_table_entry *const entry, + const uint32_t color[const static 4]) +{ + const uint32_t r = color[0]; + const uint32_t g = color[1]; + const uint32_t b = color[2]; + const uint32_t a = color[3]; + + /* 0 */ PACK(U8, i8, r); + /* 1 */ PACK(S8, i8, r); + /* 7 */ PACK(U8U8, i8i8, g, r); + /* 8 */ PACK(S8S8, i8i8, g, r); + /* 9 */ PACK(U16, i16, r); + /* 10 */ PACK(S16, i16, r); + /* 11 */ UDEF(F16); + /* 12 */ PACK(U8U8U8U8, i8i8i8i8, a, b, g, r); + /* 13 */ PACK(S8S8S8S8, i8i8i8i8, a, b, g, r); + /* 14 */ PACK(A2R10B10G10, i10i10i10i2, r, g, b, a); + /* 15 */ PACK(U16U16, i16i16, g, r); + /* 16 */ PACK(S16S16, i16i16, g, r); + /* 17 */ UDEF(F16F16); + /* 18 */ UDEF(F32); + /* 22 */ PACK(ST8U24, i24i8, g, r); + /* 23 */ PACK(U8X24, x24i8, r); + /* 24 */ PACK(U32, i32, r); + /* 25 */ PACK(S32, i32, r); + /* 26 */ UDEF(SE9995); + /* 28 */ UDEF(F16F16F16F16); + /* 29 */ PACK(U16U16U16U16, i16i16i16i16, a, b, g, r); + /* 30 */ PACK(S16S16S16S16, i16i16i16i16, a, b, g, r); + /* 35 */ PACK(U32U32, i32i32, g, r); + /* 36 */ PACK(S32S32, i32i32, g, r); + /* 61 */ UDEF(F32F32F32F32); + /* 62 */ PACK(U32U32U32U32, i32i32i32i32, a, b, g, r); + /* 63 */ PACK(S32S32S32S32, i32i32i32i32, a, b, g, r); + /* 64 */ UDEF(F32F32F32); + /* 65 */ PACK(U32U32U32, i32i32i32, b, g, r); + /* 66 */ PACK(S32S32S32, i32i32i32, b, g, r); + /* 88 */ UDEF(F10F11F11); +} + +static void +pvr_pack_border_color_floats(struct pvr_border_color_table_entry *const entry, + const float color[const static 4]) +{ + const float r = color[0]; + const float g = color[1]; + const float b = color[2]; + const float a = color[3]; + + /* 0 */ PACK(U8, n8, r); + /* 1 */ PACK(S8, s8, r); + /* 2 */ PACK(A4R4G4B4, n4n4n4n4, b, g, r, a); + /* 4 */ PACK(A1R5G5B5, n5n5n5n1, b, g, r, a); + /* 5 */ PACK(R5G6B5, n5n6n5, b, g, r); + /* 7 */ PACK(U8U8, n8n8, g, r); + /* 8 */ PACK(S8S8, s8s8, g, r); + /* 9 */ PACK(U16, n16, r); + /* 10 */ PACK(S16, s16, r); + /* 11 */ PACK(F16, f16, r); + /* 12 */ PACK(U8U8U8U8, n8n8n8n8, a, b, g, r); + /* 13 */ PACK(S8S8S8S8, s8s8s8s8, a, b, g, r); + /* 14 */ PACK(A2R10B10G10, n10n10n10n2, r, g, b, a); + /* 15 */ PACK(U16U16, n16n16, g, r); + /* 16 */ PACK(S16S16, s16s16, g, r); + /* 17 */ PACK(F16F16, f16f16, g, r); + /* 18 */ PACK(F32, f32, r); + /* 22 */ PACK(ST8U24, n24n8, g, r); + /* 26 */ PACK(SE9995, e9e9e9x5, r, g, b); + /* 28 */ PACK(F16F16F16F16, f16f16f16f16, a, b, g, r); + /* 29 */ PACK(U16U16U16U16, n16n16n16n16, a, b, g, r); + /* 30 */ PACK(S16S16S16S16, s16s16s16s16, a, b, g, r); + /* 34 */ PACK(F32F32, f32f32, g, r); + /* 61 */ PACK(F32F32F32F32, f32f32f32f32, a, b, g, r); + /* 64 */ PACK(F32F32F32, f32f32f32, b, g, r); + /* 88 */ PACK(F10F11F11, f11f11f10, b, g, r); +} + +#undef PACK +#undef UDEF + +#define PACKC(format_, layout_, channels_...) \ + entry->compressed_formats[PVRX(TEXSTATE_FORMAT_COMPRESSED_##format_)] = \ + pvr_pack_border_color_##layout_(channels_) + +static void pvr_pack_border_color_compressed( + struct pvr_border_color_table_entry *const entry, + const VkClearColorValue color[const static 4]) +{ + const uint32_t r = color->uint32[0]; + const uint32_t g = color->uint32[1]; + const uint32_t b = color->uint32[2]; + const uint32_t a = color->uint32[3]; + + /* 68 */ PACKC(ETC2_RGB, i8i8i8i8, a, b, g, r); + /* 69 */ PACKC(ETC2A_RGBA, i8i8i8i8, a, b, g, r); + /* 70 */ PACKC(ETC2_PUNCHTHROUGHA, i8i8i8i8, a, b, g, r); + /* 71 */ PACKC(EAC_R11_UNSIGNED, i16i16i16i16, a, b, g, r); + /* 72 */ PACKC(EAC_R11_SIGNED, i16i16i16i16, a, b, g, r); + /* 73 */ PACKC(EAC_RG11_UNSIGNED, i16i16i16i16, a, b, g, r); + /* 74 */ PACKC(EAC_RG11_SIGNED, i16i16i16i16, a, b, g, r); +} + +#undef PACKC + +static int32_t +pvr_border_color_table_alloc_entry(struct pvr_border_color_table *const table) +{ + const int32_t index = BITSET_FFS(table->unused_entries); + + /* BITSET_FFS() returns 0 if there are no set bits; we have to determine + * whether a value of 0 means "no set bits" or "zero is the first set bit". + */ + if (index == 0 && !pvr_border_color_table_is_index_valid(table, 0)) { + return -1; + } + + BITSET_CLEAR(table->unused_entries, index); + + return index; +} + +static void +pvr_border_color_table_free_entry(struct pvr_border_color_table *const table, + const uint32_t index) +{ + assert(BITSET_TEST(table->unused_entries, index)); + BITSET_SET(table->unused_entries, index); +} + +static void +pvr_border_color_table_fill_entry(struct pvr_border_color_table *const table, + const struct pvr_device *const device, + const uint32_t index, + const VkClearColorValue *const color, + const bool is_int) +{ + struct pvr_border_color_table_entry *const entries = table->table->bo->map; + const struct pvr_device_info *const dev_info = &device->pdevice->dev_info; + struct pvr_border_color_table_entry *entry; + + assert(pvr_border_color_table_is_index_valid(table, index)); + assert(entries); + + entry = &entries[index]; + memset(entry, 0, sizeof(*entry)); + + if (is_int) + pvr_pack_border_color_ints(entry, color->uint32); + else + pvr_pack_border_color_floats(entry, color->float32); + + if (PVR_HAS_FEATURE(dev_info, tpu_border_colour_enhanced)) { + pvr_pack_border_color_compressed(entry, color); + } else { + pvr_finishme("Devices without tpu_border_colour_enhanced require entries " + "for compressed formats to be stored in the table " + "pre-compressed."); + } +} + +VkResult pvr_border_color_table_init(struct pvr_border_color_table *const table, + struct pvr_device *const device) +{ + const struct pvr_device_info *const dev_info = &device->pdevice->dev_info; + const uint32_t cache_line_size = rogue_get_slc_cache_line_size(dev_info); + const uint32_t table_size = sizeof(struct pvr_border_color_table_entry) * + PVR_BORDER_COLOR_TABLE_NR_ENTRIES; + + VkResult result; + + /* Initialize to ones so ffs can be used to find unused entries. */ + BITSET_ONES(table->unused_entries); + + result = pvr_bo_alloc(device, + device->heaps.general_heap, + table_size, + cache_line_size, + PVR_BO_ALLOC_FLAG_CPU_MAPPED, + &table->table); + if (result != VK_SUCCESS) + return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); + + BITSET_CLEAR_RANGE(table->unused_entries, + 0, + PVR_BORDER_COLOR_TABLE_NR_BUILTIN_ENTRIES - 1); + + for (uint32_t i = 0; i < PVR_BORDER_COLOR_TABLE_NR_BUILTIN_ENTRIES; i++) { + const VkClearColorValue color = vk_border_color_value(i); + const bool is_int = vk_border_color_is_int(i); + + pvr_border_color_table_fill_entry(table, device, i, &color, is_int); + } + + pvr_bo_cpu_unmap(device, table->table); + + return VK_SUCCESS; +} + +void pvr_border_color_table_finish(struct pvr_border_color_table *const table, + struct pvr_device *const device) +{ + pvr_bo_free(device, table->table); +} + +VkResult pvr_border_color_table_get_or_create_entry( + UNUSED struct pvr_border_color_table *const table, + const struct VkSamplerCreateInfo *const sampler_create_info, + uint32_t *const index_out) +{ + const VkBorderColor vk_type = sampler_create_info->borderColor; + + if (vk_type <= PVR_BORDER_COLOR_TABLE_NR_BUILTIN_ENTRIES) { + *index_out = vk_type; + return VK_SUCCESS; + } + + pvr_finishme("VK_EXT_custom_border_color is currently unsupported."); + return vk_error(NULL, VK_ERROR_EXTENSION_NOT_PRESENT); +} diff --git a/src/imagination/vulkan/pvr_border.h b/src/imagination/vulkan/pvr_border.h new file mode 100644 index 00000000000..4c190f0d0ba --- /dev/null +++ b/src/imagination/vulkan/pvr_border.h @@ -0,0 +1,76 @@ +/* + * Copyright © 2023 Imagination Technologies Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef PVR_BORDER_H +#define PVR_BORDER_H + +#include +#include +#include + +#include "pvr_csb.h" +#include "util/bitset.h" + +#define PVR_BORDER_COLOR_TABLE_NR_ENTRIES \ + (PVRX(TEXSTATE_SAMPLER_BORDERCOLOR_INDEX_MAX_SIZE) + 1) + +#define PVR_BORDER_COLOR_TABLE_NR_BUILTIN_ENTRIES \ + (VK_BORDER_COLOR_INT_OPAQUE_WHITE + 1U) + +#define PVR_BORDER_COLOR_TABLE_NR_CUSTOM_ENTRIES \ + (PVR_BORDER_COLOR_TABLE_NR_ENTRIES - \ + PVR_BORDER_COLOR_TABLE_NR_BUILTIN_ENTRIES) + +/* Forward declaration from "pvr_bo.h" */ +struct pvr_bo; + +/* Forward declaration from "pvr_private.h" */ +struct pvr_device; + +struct pvr_border_color_table { + BITSET_DECLARE(unused_entries, PVR_BORDER_COLOR_TABLE_NR_ENTRIES); + + /* Contains an array of: + * PVR_BORDER_COLOR_TABLE_NR_ENTRIES x struct pvr_border_color_table_entry + */ + struct pvr_bo *table; +}; + +VkResult pvr_border_color_table_init(struct pvr_border_color_table *table, + struct pvr_device *device); +void pvr_border_color_table_finish(struct pvr_border_color_table *table, + struct pvr_device *device); + +VkResult pvr_border_color_table_get_or_create_entry( + struct pvr_border_color_table *table, + const struct VkSamplerCreateInfo *sampler_create_info, + uint32_t *index_out); + +static inline bool pvr_border_color_table_is_index_valid( + const struct pvr_border_color_table *const table, + const uint32_t index) +{ + return !BITSET_TEST(table->unused_entries, index); +} + +#endif /* PVR_BORDER_H */ diff --git a/src/imagination/vulkan/pvr_cmd_buffer.c b/src/imagination/vulkan/pvr_cmd_buffer.c index a52f439e9bc..ac6b75d7bb9 100644 --- a/src/imagination/vulkan/pvr_cmd_buffer.c +++ b/src/imagination/vulkan/pvr_cmd_buffer.c @@ -1436,11 +1436,6 @@ static VkResult pvr_sub_cmd_gfx_job_init(const struct pvr_device_info *dev_info, job->ctrl_stream_addr = pvr_csb_get_start_address(&sub_cmd->control_stream); - /* FIXME: Need to set up the border color table at device creation - * time. Set to invalid for the time being. - */ - job->border_colour_table_addr = PVR_DEV_ADDR_INVALID; - if (sub_cmd->depth_bias_bo) job->depth_bias_table_addr = sub_cmd->depth_bias_bo->dev_addr; else diff --git a/src/imagination/vulkan/pvr_device.c b/src/imagination/vulkan/pvr_device.c index f533daa1bc9..2aede42234f 100644 --- a/src/imagination/vulkan/pvr_device.c +++ b/src/imagination/vulkan/pvr_device.c @@ -41,6 +41,7 @@ #include "hwdef/rogue_hw_utils.h" #include "pipe/p_defines.h" #include "pvr_bo.h" +#include "pvr_border.h" #include "pvr_clear.h" #include "pvr_csb.h" #include "pvr_csb_enum_helpers.h" @@ -1876,6 +1877,10 @@ VkResult pvr_CreateDevice(VkPhysicalDevice physicalDevice, if (result != VK_SUCCESS) goto err_pvr_spm_finish_scratch_buffer_store; + result = pvr_border_color_table_init(&device->border_color_table, device); + if (result != VK_SUCCESS) + goto err_pvr_robustness_buffer_finish; + /* FIXME: Move this to a later stage and possibly somewhere other than * pvr_device. The purpose of this is so that we don't have to get the size * on each kick. @@ -1891,6 +1896,9 @@ VkResult pvr_CreateDevice(VkPhysicalDevice physicalDevice, return VK_SUCCESS; +err_pvr_robustness_buffer_finish: + pvr_robustness_buffer_finish(device); + err_pvr_spm_finish_scratch_buffer_store: pvr_spm_finish_scratch_buffer_store(device); @@ -1954,6 +1962,7 @@ void pvr_DestroyDevice(VkDevice _device, if (!device) return; + pvr_border_color_table_finish(&device->border_color_table, device); pvr_robustness_buffer_finish(device); pvr_spm_finish_scratch_buffer_store(device); pvr_queues_destroy(device); @@ -2987,10 +2996,12 @@ VkResult pvr_CreateSampler(VkDevice _device, VkSampler *pSampler) { PVR_FROM_HANDLE(pvr_device, device, _device); + uint32_t border_color_table_index; struct pvr_sampler *sampler; float lod_rounding_bias; VkFilter min_filter; VkFilter mag_filter; + VkResult result; float min_lod; float max_lod; @@ -3001,12 +3012,21 @@ VkResult pvr_CreateSampler(VkDevice _device, pAllocator, sizeof(*sampler), VK_OBJECT_TYPE_SAMPLER); - if (!sampler) - return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); + if (!sampler) { + result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); + goto err_out; + } mag_filter = pCreateInfo->magFilter; min_filter = pCreateInfo->minFilter; + result = + pvr_border_color_table_get_or_create_entry(&device->border_color_table, + pCreateInfo, + &border_color_table_index); + if (result != VK_SUCCESS) + goto err_free_sampler; + if (PVR_HAS_QUIRK(&device->pdevice->dev_info, 51025)) { /* The min/mag filters may need adjustment here, the GPU should decide * which of the two filters to use based on the clamped LOD value: LOD @@ -3108,7 +3128,7 @@ VkResult pvr_CreateSampler(VkDevice _device, word.maxlod = util_unsigned_fixed(CLAMP(max_lod, 0.0f, lod_clamp_max), PVRX(TEXSTATE_CLAMP_FRACTIONAL_BITS)); - word.bordercolor_index = pCreateInfo->borderColor; + word.bordercolor_index = border_color_table_index; if (pCreateInfo->unnormalizedCoordinates) word.non_normalized_coords = true; @@ -3117,6 +3137,12 @@ VkResult pvr_CreateSampler(VkDevice _device, *pSampler = pvr_sampler_to_handle(sampler); return VK_SUCCESS; + +err_free_sampler: + vk_object_free(&device->vk, pAllocator, sampler); + +err_out: + return result; } void pvr_DestroySampler(VkDevice _device, diff --git a/src/imagination/vulkan/pvr_job_compute.c b/src/imagination/vulkan/pvr_job_compute.c index c22960b21fd..ef00dd6d5d3 100644 --- a/src/imagination/vulkan/pvr_job_compute.c +++ b/src/imagination/vulkan/pvr_job_compute.c @@ -41,7 +41,8 @@ pvr_submit_info_stream_init(struct pvr_compute_ctx *ctx, struct pvr_sub_cmd_compute *sub_cmd, struct pvr_winsys_compute_submit_info *submit_info) { - const struct pvr_physical_device *const pdevice = ctx->device->pdevice; + const struct pvr_device *const device = ctx->device; + const struct pvr_physical_device *const pdevice = device->pdevice; const struct pvr_device_runtime_info *const dev_runtime_info = &pdevice->dev_runtime_info; const struct pvr_device_info *const dev_info = &pdevice->dev_info; @@ -49,13 +50,11 @@ pvr_submit_info_stream_init(struct pvr_compute_ctx *ctx, uint32_t *stream_ptr = (uint32_t *)submit_info->fw_stream; - /* FIXME: Need to set up the border color table at device creation time. Set - * to invalid for the time being. - */ pvr_csb_pack ((uint64_t *)stream_ptr, CR_TPU_BORDER_COLOUR_TABLE_CDM, value) { - value.border_colour_table_address = PVR_DEV_ADDR_INVALID; + value.border_colour_table_address = + device->border_color_table.table->vma->dev_addr; } stream_ptr += pvr_cmd_length(CR_TPU_BORDER_COLOUR_TABLE_CDM); diff --git a/src/imagination/vulkan/pvr_job_render.c b/src/imagination/vulkan/pvr_job_render.c index b8ab0c9945c..d325e1ff2e6 100644 --- a/src/imagination/vulkan/pvr_job_render.c +++ b/src/imagination/vulkan/pvr_job_render.c @@ -938,7 +938,8 @@ static void pvr_geom_state_stream_init(struct pvr_render_ctx *ctx, struct pvr_render_job *job, struct pvr_winsys_geometry_state *state) { - const struct pvr_device_info *dev_info = &ctx->device->pdevice->dev_info; + const struct pvr_device *const device = ctx->device; + const struct pvr_device_info *const dev_info = &device->pdevice->dev_info; uint32_t *stream_ptr = (uint32_t *)state->fw_stream; @@ -950,7 +951,8 @@ static void pvr_geom_state_stream_init(struct pvr_render_ctx *ctx, pvr_csb_pack ((uint64_t *)stream_ptr, CR_TPU_BORDER_COLOUR_TABLE_VDM, value) { - value.border_colour_table_address = job->border_colour_table_addr; + value.border_colour_table_address = + device->border_color_table.table->vma->dev_addr; } stream_ptr += pvr_cmd_length(CR_TPU_BORDER_COLOUR_TABLE_VDM); @@ -1058,7 +1060,8 @@ static void pvr_frag_state_stream_init(struct pvr_render_ctx *ctx, struct pvr_render_job *job, struct pvr_winsys_fragment_state *state) { - const struct pvr_physical_device *const pdevice = ctx->device->pdevice; + const struct pvr_device *const device = ctx->device; + const struct pvr_physical_device *const pdevice = device->pdevice; const struct pvr_device_runtime_info *dev_runtime_info = &pdevice->dev_runtime_info; const struct pvr_device_info *dev_info = &pdevice->dev_info; @@ -1203,7 +1206,8 @@ static void pvr_frag_state_stream_init(struct pvr_render_ctx *ctx, pvr_csb_pack ((uint64_t *)stream_ptr, CR_TPU_BORDER_COLOUR_TABLE_PDM, value) { - value.border_colour_table_address = job->border_colour_table_addr; + value.border_colour_table_address = + device->border_color_table.table->vma->dev_addr; } stream_ptr += pvr_cmd_length(CR_TPU_BORDER_COLOUR_TABLE_PDM); diff --git a/src/imagination/vulkan/pvr_job_render.h b/src/imagination/vulkan/pvr_job_render.h index 5754306731d..a214d5e5239 100644 --- a/src/imagination/vulkan/pvr_job_render.h +++ b/src/imagination/vulkan/pvr_job_render.h @@ -88,7 +88,6 @@ struct pvr_render_job { pvr_dev_addr_t ctrl_stream_addr; - pvr_dev_addr_t border_colour_table_addr; pvr_dev_addr_t depth_bias_table_addr; pvr_dev_addr_t scissor_table_addr; diff --git a/src/imagination/vulkan/pvr_private.h b/src/imagination/vulkan/pvr_private.h index b691411c115..19e7507e8dd 100644 --- a/src/imagination/vulkan/pvr_private.h +++ b/src/imagination/vulkan/pvr_private.h @@ -38,6 +38,7 @@ #include "compiler/shader_enums.h" #include "hwdef/rogue_hw_defs.h" +#include "pvr_border.h" #include "pvr_clear.h" #include "pvr_common.h" #include "pvr_csb.h" @@ -277,6 +278,8 @@ struct pvr_device { struct pvr_bo *robustness_buffer; struct vk_sync *presignaled_sync; + + struct pvr_border_color_table border_color_table; }; struct pvr_device_memory {