diff --git a/src/libpisp/backend/backend.hpp b/src/libpisp/backend/backend.hpp index fde0ef4..6b29213 100644 --- a/src/libpisp/backend/backend.hpp +++ b/src/libpisp/backend/backend.hpp @@ -7,6 +7,7 @@ */ #pragma once +#include #include #include #include diff --git a/src/libpisp/backend/backend_debug.cpp b/src/libpisp/backend/backend_debug.cpp index ace43dd..26267bd 100644 --- a/src/libpisp/backend/backend_debug.cpp +++ b/src/libpisp/backend/backend_debug.cpp @@ -501,7 +501,7 @@ std::string BackEnd::GetJsonConfig(pisp_be_tiles_config *config) j["config"].push_back(b); } - for (int t = 0; t < config->num_tiles; t++) + for (unsigned int t = 0; t < config->num_tiles; t++) { json b; for (auto const &field : tiles_config.fields) diff --git a/src/libpisp/backend/backend_prepare.cpp b/src/libpisp/backend/backend_prepare.cpp index f24cd2f..a57ac78 100644 --- a/src/libpisp/backend/backend_prepare.cpp +++ b/src/libpisp/backend/backend_prepare.cpp @@ -36,7 +36,7 @@ void check_stride(pisp_image_format_config const &config) if (config.stride % PISP_BACK_END_OUTPUT_MIN_ALIGN || config.stride2 % PISP_BACK_END_OUTPUT_MIN_ALIGN) throw std::runtime_error("Output stride values not sufficiently aligned"); - if (PISP_IMAGE_FORMAT_wallpaper(config.format) && (config.stride % 128 || config.stride2 % 128)) + if (PISP_IMAGE_FORMAT_WALLPAPER(config.format) && (config.stride % 128 || config.stride2 % 128)) throw std::runtime_error("Wallpaper format should have 128-byte aligned rolls"); pisp_image_format_config check = config; @@ -66,13 +66,13 @@ void finalise_inputs(pisp_be_config &config) } else if (config.global.rgb_enables & PISP_BE_RGB_ENABLE_INPUT) { - if (PISP_IMAGE_FORMAT_sampling_420(config.input_format.format) && (config.input_format.width & 1)) + if (PISP_IMAGE_FORMAT_SAMPLING_420(config.input_format.format) && (config.input_format.width & 1)) throw std::runtime_error("finalise_inputs: 420 input height must be even"); - else if ((PISP_IMAGE_FORMAT_sampling_420(config.input_format.format) || - PISP_IMAGE_FORMAT_sampling_422(config.input_format.format)) && + else if ((PISP_IMAGE_FORMAT_SAMPLING_420(config.input_format.format) || + PISP_IMAGE_FORMAT_SAMPLING_422(config.input_format.format)) && (config.input_format.width & 1)) throw std::runtime_error("finalise_inputs: 420/422 input width must be even"); - if (PISP_IMAGE_FORMAT_wallpaper(config.input_format.format)) + if (PISP_IMAGE_FORMAT_WALLPAPER(config.input_format.format)) { if ((config.input_format.stride & 127) || (config.input_format.stride2 & 127)) throw std::runtime_error("finalise_inputs: wallpaper format strides must be at least 128-byte aligned"); @@ -150,13 +150,13 @@ void finalise_decompression(pisp_be_config const &be_config) { uint32_t fmt = be_config.input_format.format, bayer_enables = be_config.global.bayer_enables; - if (PISP_IMAGE_FORMAT_compressed(fmt) && !(bayer_enables & PISP_BE_BAYER_ENABLE_DECOMPRESS)) + if (PISP_IMAGE_FORMAT_COMPRESSED(fmt) && !(bayer_enables & PISP_BE_BAYER_ENABLE_DECOMPRESS)) throw std::runtime_error("BackEnd::finalise: input compressed but decompression not enabled"); - if (!PISP_IMAGE_FORMAT_compressed(fmt) && (bayer_enables & PISP_BE_BAYER_ENABLE_DECOMPRESS)) + if (!PISP_IMAGE_FORMAT_COMPRESSED(fmt) && (bayer_enables & PISP_BE_BAYER_ENABLE_DECOMPRESS)) throw std::runtime_error("BackEnd::finalise: input uncompressed but decompression enabled"); - if ((bayer_enables & PISP_BE_BAYER_ENABLE_DECOMPRESS) && !PISP_IMAGE_FORMAT_bps_8(fmt)) + if ((bayer_enables & PISP_BE_BAYER_ENABLE_DECOMPRESS) && !PISP_IMAGE_FORMAT_BPS_8(fmt)) throw std::runtime_error("BackEnd::finalise: compressed input is not 8bpp"); } @@ -189,13 +189,13 @@ void finalise_tdn(pisp_be_config &config) if (tdn_enabled && !tdn_output_enabled) throw std::runtime_error("BackEnd::finalise: TDN output not enabled when TDN enabled"); - if (PISP_IMAGE_FORMAT_compressed(fmt) && !tdn_compress_enabled) + if (PISP_IMAGE_FORMAT_COMPRESSED(fmt) && !tdn_compress_enabled) throw std::runtime_error("BackEnd::finalise: TDN output compressed but compression not enabled"); - if (!PISP_IMAGE_FORMAT_compressed(fmt) && tdn_compress_enabled) + if (!PISP_IMAGE_FORMAT_COMPRESSED(fmt) && tdn_compress_enabled) throw std::runtime_error("BackEnd::finalise: TDN output uncompressed but compression enabled"); - if (tdn_compress_enabled && !PISP_IMAGE_FORMAT_bps_8(fmt)) + if (tdn_compress_enabled && !PISP_IMAGE_FORMAT_BPS_8(fmt)) throw std::runtime_error("BackEnd::finalise: TDN output does not match compression mode"); if (tdn_output_enabled) @@ -222,11 +222,11 @@ void finalise_tdn(pisp_be_config &config) // Make the TDN input match the output if it's unset. Usually this will be the sensible thing to do. if (config.tdn_input_format.width == 0 && config.tdn_input_format.height == 0) config.tdn_input_format = config.tdn_output_format; - if (PISP_IMAGE_FORMAT_compressed(fmt) && !tdn_decompress_enabled) + if (PISP_IMAGE_FORMAT_COMPRESSED(fmt) && !tdn_decompress_enabled) throw std::runtime_error("BackEnd::finalise: TDN input compressed but decompression not enabled"); - if (!PISP_IMAGE_FORMAT_compressed(fmt) && tdn_decompress_enabled) + if (!PISP_IMAGE_FORMAT_COMPRESSED(fmt) && tdn_decompress_enabled) throw std::runtime_error("BackEnd::finalise: TDN input uncompressed but decompression enabled"); - if (tdn_compress_enabled && !PISP_IMAGE_FORMAT_bps_8(fmt)) + if (tdn_compress_enabled && !PISP_IMAGE_FORMAT_BPS_8(fmt)) throw std::runtime_error("BackEnd::finalise: TDN output does not match compression mode"); } } @@ -243,17 +243,17 @@ void finalise_stitch(pisp_be_config &config) if (stitch_enabled != stitch_input_enabled) throw std::runtime_error("BackEnd::finalise: stitch and stitch_input should be enabled/disabled together"); - if (stitch_input_enabled && PISP_IMAGE_FORMAT_compressed(input_fmt) && !stitch_decompress_enabled) + if (stitch_input_enabled && PISP_IMAGE_FORMAT_COMPRESSED(input_fmt) && !stitch_decompress_enabled) throw std::runtime_error("BackEnd::finalise: stitch output compressed but decompression not enabled"); - if (stitch_input_enabled && !PISP_IMAGE_FORMAT_compressed(input_fmt) && stitch_decompress_enabled) + if (stitch_input_enabled && !PISP_IMAGE_FORMAT_COMPRESSED(input_fmt) && stitch_decompress_enabled) throw std::runtime_error("BackEnd::finalise: stitch output uncompressed but decompression enabled"); - if (stitch_output_enabled && PISP_IMAGE_FORMAT_compressed(output_fmt) && !stitch_compress_enabled) + if (stitch_output_enabled && PISP_IMAGE_FORMAT_COMPRESSED(output_fmt) && !stitch_compress_enabled) throw std::runtime_error("BackEnd::finalise: stitch output compressed but compression not enabled"); - if (stitch_output_enabled && !PISP_IMAGE_FORMAT_compressed(output_fmt) && stitch_compress_enabled) + if (stitch_output_enabled && !PISP_IMAGE_FORMAT_COMPRESSED(output_fmt) && stitch_compress_enabled) throw std::runtime_error("BackEnd::finalise: stitch output uncompressed but compression enabled"); - if (stitch_decompress_enabled && !PISP_IMAGE_FORMAT_bps_8(input_fmt)) + if (stitch_decompress_enabled && !PISP_IMAGE_FORMAT_BPS_8(input_fmt)) throw std::runtime_error("BackEnd::finalise: stitch input does not match compression mode"); - if (stitch_compress_enabled && !PISP_IMAGE_FORMAT_bps_8(output_fmt)) + if (stitch_compress_enabled && !PISP_IMAGE_FORMAT_BPS_8(output_fmt)) throw std::runtime_error("BackEnd::finalise: stitch output does not match compression mode"); if (stitch_output_enabled) @@ -286,14 +286,14 @@ void finalise_output(pisp_be_output_format_config &config) if (config.image.width < PISP_BACK_END_MIN_TILE_WIDTH || config.image.height < PISP_BACK_END_MIN_TILE_HEIGHT) throw std::runtime_error("finalise_output: output image too small"); - if (PISP_IMAGE_FORMAT_sampling_420(config.image.format) && (config.image.height & 1)) + if (PISP_IMAGE_FORMAT_SAMPLING_420(config.image.format) && (config.image.height & 1)) throw std::runtime_error("finalise_output: 420 image height should be even"); - if ((PISP_IMAGE_FORMAT_sampling_420(config.image.format) || PISP_IMAGE_FORMAT_sampling_422(config.image.format)) && + if ((PISP_IMAGE_FORMAT_SAMPLING_420(config.image.format) || PISP_IMAGE_FORMAT_SAMPLING_422(config.image.format)) && (config.image.width & 1)) throw std::runtime_error("finalise_output: 420/422 image width should be even"); - if (PISP_IMAGE_FORMAT_wallpaper(config.image.format)) + if (PISP_IMAGE_FORMAT_WALLPAPER(config.image.format)) { if ((config.image.stride & 127) || (config.image.stride2 & 127)) throw std::runtime_error("finalise_output: wallpaper image stride should be at least 128-byte aligned"); @@ -367,17 +367,17 @@ unsigned int get_pixel_alignment(uint32_t format, int byte_alignment) { int alignment_pixels = byte_alignment; // for 8bpp formats - if (PISP_IMAGE_FORMAT_bps_16(format)) + if (PISP_IMAGE_FORMAT_BPS_16(format)) alignment_pixels = byte_alignment / 2; - else if (PISP_IMAGE_FORMAT_bps_10(format)) + else if (PISP_IMAGE_FORMAT_BPS_10(format)) alignment_pixels = byte_alignment * 3 / 4; - else if (PISP_IMAGE_FORMAT_bpp_32(format)) + else if (PISP_IMAGE_FORMAT_BPP_32(format)) alignment_pixels = byte_alignment / 4; - if (PISP_IMAGE_FORMAT_planar(format) && !PISP_IMAGE_FORMAT_sampling_444(format)) + if (PISP_IMAGE_FORMAT_PLANAR(format) && !PISP_IMAGE_FORMAT_SAMPLING_444(format)) alignment_pixels *= 2; // the UV planes in fully planar 420/422 output will have half the width - else if (PISP_IMAGE_FORMAT_interleaved(format) && - (PISP_IMAGE_FORMAT_sampling_422(format) || PISP_IMAGE_FORMAT_sampling_420(format))) + else if (PISP_IMAGE_FORMAT_INTERLEAVED(format) && + (PISP_IMAGE_FORMAT_SAMPLING_422(format) || PISP_IMAGE_FORMAT_SAMPLING_420(format))) alignment_pixels /= 2; // YUYV type outputs need only 8 pixels to make 16 bytes return alignment_pixels; @@ -398,7 +398,7 @@ static tiling::Length2 calculate_input_alignment(pisp_be_config const &config) PISP_LOG(debug, "RGB input enabled"); // Need 4 byte alignment AND even number of pixels. Height must be 2 row aligned only for 420 input. return tiling::Length2(lcm(get_pixel_alignment(config.input_format.format, PISP_BACK_END_INPUT_ALIGN), 2), - PISP_IMAGE_FORMAT_sampling_420(config.input_format.format) ? 2 : 1); + PISP_IMAGE_FORMAT_SAMPLING_420(config.input_format.format) ? 2 : 1); } uint32_t bayer_enables = config.global.bayer_enables; @@ -406,11 +406,11 @@ static tiling::Length2 calculate_input_alignment(pisp_be_config const &config) int pixel_alignment = get_pixel_alignment(config.input_format.format, PISP_BACK_END_INPUT_ALIGN); // If any input is compressed, we need 8 *pixel* alignment. - if (PISP_IMAGE_FORMAT_compressed(config.input_format.format) || + if (PISP_IMAGE_FORMAT_COMPRESSED(config.input_format.format) || ((bayer_enables & PISP_BE_BAYER_ENABLE_TDN_INPUT) && - PISP_IMAGE_FORMAT_compressed(config.tdn_input_format.format)) || + PISP_IMAGE_FORMAT_COMPRESSED(config.tdn_input_format.format)) || ((bayer_enables & PISP_BE_BAYER_ENABLE_STITCH_INPUT) && - PISP_IMAGE_FORMAT_compressed(config.stitch_input_format.format))) + PISP_IMAGE_FORMAT_COMPRESSED(config.stitch_input_format.format))) pixel_alignment = lcm(pixel_alignment, PISP_BACK_END_COMPRESSED_ALIGN); // If any of the Bayer outputs are enabled, those need 16 *byte* alignment. (This already covers the outputs being compressed.) @@ -426,7 +426,7 @@ static tiling::Length2 calculate_input_alignment(pisp_be_config const &config) static tiling::Length2 calculate_output_alignment(uint32_t format, int align = PISP_BACK_END_OUTPUT_MAX_ALIGN) { - int y_alignment = PISP_IMAGE_FORMAT_sampling_420(format) ? 2 : 1; + int y_alignment = PISP_IMAGE_FORMAT_SAMPLING_420(format) ? 2 : 1; return tiling::Length2(get_pixel_alignment(format, align), y_alignment); } diff --git a/src/libpisp/backend/pisp_be_config.h b/src/libpisp/backend/pisp_be_config.h index 32e89a6..6af9372 100644 --- a/src/libpisp/backend/pisp_be_config.h +++ b/src/libpisp/backend/pisp_be_config.h @@ -1,8 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* - * Copyright (C) 2021 - 2023, Raspberry Pi Ltd + * PiSP Back End configuration definitions. + * + * Copyright (C) 2021 - Raspberry Pi Ltd * - * pisp_be_config.h - PiSP Back End HW configuration definitions */ #ifndef _PISP_BE_CONFIG_H_ #define _PISP_BE_CONFIG_H_ @@ -30,7 +31,7 @@ #define PISP_BACK_END_NUM_TILES 64 -typedef enum { +enum pisp_be_bayer_enable { PISP_BE_BAYER_ENABLE_INPUT = 0x000001, PISP_BE_BAYER_ENABLE_DECOMPRESS = 0x000002, PISP_BE_BAYER_ENABLE_DPC = 0x000004, @@ -54,9 +55,9 @@ typedef enum { PISP_BE_BAYER_ENABLE_CAC = 0x100000, PISP_BE_BAYER_ENABLE_DEBIN = 0x200000, PISP_BE_BAYER_ENABLE_DEMOSAIC = 0x400000, -} pisp_be_bayer_enable; +}; -typedef enum { +enum pisp_be_rgb_enable { PISP_BE_RGB_ENABLE_INPUT = 0x000001, PISP_BE_RGB_ENABLE_CCM = 0x000002, PISP_BE_RGB_ENABLE_SAT_CONTROL = 0x000004, @@ -75,7 +76,7 @@ typedef enum { PISP_BE_RGB_ENABLE_OUTPUT0 = 0x040000, PISP_BE_RGB_ENABLE_OUTPUT1 = 0x080000, PISP_BE_RGB_ENABLE_HOG = 0x200000 -} pisp_be_rgb_enable; +}; #define PISP_BE_RGB_ENABLE_CSC(i) (PISP_BE_RGB_ENABLE_CSC0 << (i)) #define PISP_BE_RGB_ENABLE_DOWNSCALE(i) (PISP_BE_RGB_ENABLE_DOWNSCALE0 << (i)) @@ -86,433 +87,882 @@ typedef enum { * We use the enable flags to show when blocks are "dirty", but we need some * extra ones too. */ -typedef enum { +enum pisp_be_dirty { PISP_BE_DIRTY_GLOBAL = 0x0001, PISP_BE_DIRTY_SH_FC_COMBINE = 0x0002, PISP_BE_DIRTY_CROP = 0x0004 -} pisp_be_dirty; - -typedef struct { - uint32_t bayer_enables; - uint32_t rgb_enables; - uint8_t bayer_order; - uint8_t pad[3]; -} pisp_be_global_config; - -typedef struct { - /* low 32 bits followed by high 32 bits (for each of up to three planes) */ - uint32_t addr[3][2]; -} pisp_be_input_buffer_config; - -typedef struct { - uint8_t coeff_level; - uint8_t coeff_range; - uint8_t pad; +}; + +/** + * struct pisp_be_global_config - PiSP global enable bitmaps + * @bayer_enables: Bayer input enable flags + * @rgb_enables: RGB output enable flags + * @bayer_order: Bayer input format ordering + * @pad: Padding bytes + */ +struct pisp_be_global_config { + __u32 bayer_enables; + __u32 rgb_enables; + __u8 bayer_order; + __u8 pad[3]; +} __attribute__((packed)); + +/** + * struct pisp_be_input_buffer_config - PiSP Back End input buffer + * @addr: Input buffer address + */ +struct pisp_be_input_buffer_config { + /* low 32 bits followed by high 32 bits (for each of up to 3 planes) */ + __u32 addr[3][2]; +} __attribute__((packed)); + +/** + * struct pisp_be_dpc_config - PiSP Back End DPC config + * + * Defective Pixel Correction configuration + * + * @coeff_level: Coefficient for the darkest neighbouring pixel value + * @coeff_range: Coefficient for the range of pixels for this Bayer channel + * @pad: Padding byte + * @flags: DPC configuration flags + */ +struct pisp_be_dpc_config { + __u8 coeff_level; + __u8 coeff_range; + __u8 pad; #define PISP_BE_DPC_FLAG_FOLDBACK 1 - uint8_t flags; -} pisp_be_dpc_config; + __u8 flags; +} __attribute__((packed)); -typedef struct { - uint16_t offset; -#define PISP_BE_GEQ_SHARPER (1 << 15) +/** + * struct pisp_be_geq_config - PiSP Back End GEQ config + * + * Green Equalisation configuration + * + * @offset: Offset value for threshold calculation + * @slope_sharper: Slope/Sharper configuration + * @min: Minimum value the threshold may have + * @max: Maximum value the threshold may have + */ +struct pisp_be_geq_config { + __u16 offset; +#define PISP_BE_GEQ_SHARPER (1U << 15) #define PISP_BE_GEQ_SLOPE ((1 << 10) - 1) /* top bit is the "sharper" flag, slope value is bottom 10 bits */ - uint16_t slope_sharper; - uint16_t min; - uint16_t max; -} pisp_be_geq_config; - -typedef struct { + __u16 slope_sharper; + __u16 min; + __u16 max; +} __attribute__((packed)); + +/** + * struct pisp_be_tdn_input_buffer_config - PiSP Back End TDN input buffer + * @addr: TDN input buffer address + */ +struct pisp_be_tdn_input_buffer_config { /* low 32 bits followed by high 32 bits */ - uint32_t addr[2]; -} pisp_be_tdn_input_buffer_config; - -typedef struct { - uint16_t black_level; - uint16_t ratio; - uint16_t noise_constant; - uint16_t noise_slope; - uint16_t threshold; - uint8_t reset; - uint8_t pad; -} pisp_be_tdn_config; - -typedef struct { + __u32 addr[2]; +} __attribute__((packed)); + +/** + * struct pisp_be_tdn_config - PiSP Back End TDN config + * + * Temporal Denoise configuration + * + * @black_level: Black level value subtracted from pixels + * @ratio: Multiplier for the LTA input frame + * @noise_constant: Constant offset value used in noise estimation + * @noise_slope: Noise estimation multiplier + * @threshold: Threshold for TDN operations + * @reset: Disable TDN operations + * @pad: Padding byte + */ +struct pisp_be_tdn_config { + __u16 black_level; + __u16 ratio; + __u16 noise_constant; + __u16 noise_slope; + __u16 threshold; + __u8 reset; + __u8 pad; +} __attribute__((packed)); + +/** + * struct pisp_be_tdn_output_buffer_config - PiSP Back End TDN output buffer + * @addr: TDN output buffer address + */ +struct pisp_be_tdn_output_buffer_config { /* low 32 bits followed by high 32 bits */ - uint32_t addr[2]; -} pisp_be_tdn_output_buffer_config; - -typedef struct { - uint16_t black_level; - uint8_t leakage; - uint8_t pad; - uint16_t noise_constant; - uint16_t noise_slope; - uint16_t noise_constant2; - uint16_t noise_slope2; -} pisp_be_sdn_config; - -typedef struct { + __u32 addr[2]; +} __attribute__((packed)); + +/** + * struct pisp_be_sdn_config - PiSP Back End SDN config + * + * Spatial Denoise configuration + * + * @black_level: Black level subtracted from pixel for noise estimation + * @leakage: Proportion of the original undenoised value to mix in + * denoised output + * @pad: Padding byte + * @noise_constant: Noise constant used for noise estimation + * @noise_slope: Noise slope value used for noise estimation + * @noise_constant2: Second noise constant used for noise estimation + * @noise_slope2: Second slope value used for noise estimation + */ +struct pisp_be_sdn_config { + __u16 black_level; + __u8 leakage; + __u8 pad; + __u16 noise_constant; + __u16 noise_slope; + __u16 noise_constant2; + __u16 noise_slope2; +} __attribute__((packed)); + +/** + * struct pisp_be_stitch_input_buffer_config - PiSP Back End Stitch input + * @addr: Stitch input buffer address + */ +struct pisp_be_stitch_input_buffer_config { /* low 32 bits followed by high 32 bits */ - uint32_t addr[2]; -} pisp_be_stitch_input_buffer_config; + __u32 addr[2]; +} __attribute__((packed)); #define PISP_BE_STITCH_STREAMING_LONG 0x8000 #define PISP_BE_STITCH_EXPOSURE_RATIO_MASK 0x7fff -typedef struct { - uint16_t threshold_lo; - uint8_t threshold_diff_power; - uint8_t pad; +/** + * struct pisp_be_stitch_config - PiSP Back End Stitch config + * + * Stitch block configuration + * + * @threshold_lo: Low threshold value + * @threshold_diff_power: Low and high threshold difference + * @pad: Padding bytes + * @exposure_ratio: Multiplier to convert long exposure pixels into + * short exposure pixels + * @motion_threshold_256: Motion threshold above which short exposure + * pixels are used + * @motion_threshold_recip: Reciprocal of motion_threshold_256 value + */ +struct pisp_be_stitch_config { + __u16 threshold_lo; + __u8 threshold_diff_power; + __u8 pad; /* top bit indicates whether streaming input is the long exposure */ - uint16_t exposure_ratio; + __u16 exposure_ratio; - uint8_t motion_threshold_256; - uint8_t motion_threshold_recip; -} pisp_be_stitch_config; + __u8 motion_threshold_256; + __u8 motion_threshold_recip; +} __attribute__((packed)); -typedef struct { +/** + * struct pisp_be_stitch_output_buffer_config - PiSP Back End Stitch output + * @addr: Stitch input buffer address + */ +struct pisp_be_stitch_output_buffer_config { /* low 32 bits followed by high 32 bits */ - uint32_t addr[2]; -} pisp_be_stitch_output_buffer_config; + __u32 addr[2]; +} __attribute__((packed)); -typedef struct { - uint16_t thresh; - uint8_t iir_strength; - uint8_t g_adjust; -} pisp_be_cdn_config; +/** + * struct pisp_be_cdn_config - PiSP Back End CDN config + * + * Colour Denoise configuration + * + * @thresh: Constant for noise estimation + * @iir_strength: Relative strength of the IIR part of the filter + * @g_adjust: Proportion of the change assigned to the G channel + */ +struct pisp_be_cdn_config { + __u16 thresh; + __u8 iir_strength; + __u8 g_adjust; +} __attribute__((packed)); #define PISP_BE_LSC_LOG_GRID_SIZE 5 #define PISP_BE_LSC_GRID_SIZE (1 << PISP_BE_LSC_LOG_GRID_SIZE) #define PISP_BE_LSC_STEP_PRECISION 18 -typedef struct { +/** + * struct pisp_be_lsc_config - PiSP Back End LSC config + * + * Lens Shading Correction configuration + * + * @grid_step_x: Reciprocal of cell size width + * @grid_step_y: Reciprocal of cell size height + * @lut_packed: Jointly-coded RGB gains for each LSC grid + */ +struct pisp_be_lsc_config { /* (1<<18) / grid_cell_width */ - uint16_t grid_step_x; + __u16 grid_step_x; /* (1<<18) / grid_cell_height */ - uint16_t grid_step_y; + __u16 grid_step_y; /* RGB gains jointly encoded in 32 bits */ - uint32_t lut_packed[PISP_BE_LSC_GRID_SIZE + 1] - [PISP_BE_LSC_GRID_SIZE + 1]; -} pisp_be_lsc_config; - -typedef struct { - uint16_t offset_x; - uint16_t offset_y; -} pisp_be_lsc_extra; +#define PISP_BE_LSC_LUT_SIZE (PISP_BE_LSC_GRID_SIZE + 1) + __u32 lut_packed[PISP_BE_LSC_LUT_SIZE][PISP_BE_LSC_LUT_SIZE]; +} __attribute__((packed)); + +/** + * struct pisp_be_lsc_extra - PiSP Back End LSC Extra config + * @offset_x: Horizontal offset into the LSC table of this tile + * @offset_y: Vertical offset into the LSC table of this tile + */ +struct pisp_be_lsc_extra { + __u16 offset_x; + __u16 offset_y; +} __attribute__((packed)); #define PISP_BE_CAC_LOG_GRID_SIZE 3 #define PISP_BE_CAC_GRID_SIZE (1 << PISP_BE_CAC_LOG_GRID_SIZE) #define PISP_BE_CAC_STEP_PRECISION 20 -typedef struct { +/** + * struct pisp_be_cac_config - PiSP Back End CAC config + * + * Chromatic Aberration Correction config + * + * @grid_step_x: Reciprocal of cell size width + * @grid_step_y: Reciprocal of cell size height + * @lut: Pixel shift for the CAC grid + */ +struct pisp_be_cac_config { /* (1<<20) / grid_cell_width */ - uint16_t grid_step_x; + __u16 grid_step_x; /* (1<<20) / grid_cell_height */ - uint16_t grid_step_y; + __u16 grid_step_y; /* [gridy][gridx][rb][xy] */ - int8_t lut[PISP_BE_CAC_GRID_SIZE + 1][PISP_BE_CAC_GRID_SIZE + 1][2][2]; -} pisp_be_cac_config; - -typedef struct { - uint16_t offset_x; - uint16_t offset_y; -} pisp_be_cac_extra; +#define PISP_BE_CAC_LUT_SIZE (PISP_BE_CAC_GRID_SIZE + 1) + __s8 lut[PISP_BE_CAC_LUT_SIZE][PISP_BE_CAC_LUT_SIZE][2][2]; +} __attribute__((packed)); + +/** + * struct pisp_be_cac_extra - PiSP Back End CAC extra config + * @offset_x: Horizontal offset into the CAC table of this tile + * @offset_y: Horizontal offset into the CAC table of this tile + */ +struct pisp_be_cac_extra { + __u16 offset_x; + __u16 offset_y; +} __attribute__((packed)); #define PISP_BE_DEBIN_NUM_COEFFS 4 -typedef struct { - int8_t coeffs[PISP_BE_DEBIN_NUM_COEFFS]; - int8_t h_enable; - int8_t v_enable; - int8_t pad[2]; -} pisp_be_debin_config; +/** + * struct pisp_be_debin_config - PiSP Back End Debin config + * + * Debinning configuration + * + * @coeffs: Filter coefficients for debinning + * @h_enable: Horizontal debinning enable + * @v_enable: Vertical debinning enable + * @pad: Padding bytes + */ +struct pisp_be_debin_config { + __s8 coeffs[PISP_BE_DEBIN_NUM_COEFFS]; + __s8 h_enable; + __s8 v_enable; + __s8 pad[2]; +} __attribute__((packed)); #define PISP_BE_TONEMAP_LUT_SIZE 64 -typedef struct { - uint16_t detail_constant; - uint16_t detail_slope; - uint16_t iir_strength; - uint16_t strength; - uint32_t lut[PISP_BE_TONEMAP_LUT_SIZE]; -} pisp_be_tonemap_config; - -typedef struct { - uint8_t sharper; - uint8_t fc_mode; - uint8_t pad[2]; -} pisp_be_demosaic_config; - -typedef struct { - int16_t coeffs[9]; - uint8_t pad[2]; - int32_t offsets[3]; -} pisp_be_ccm_config; - -typedef struct { - uint8_t shift_r; - uint8_t shift_g; - uint8_t shift_b; - uint8_t pad; -} pisp_be_sat_control_config; - -typedef struct { - uint8_t distance; - uint8_t pad[3]; -} pisp_be_false_colour_config; +/** + * struct pisp_be_tonemap_config - PiSP Back End Tonemap config + * + * Tonemapping configuration + * + * @detail_constant: Constant value for threshold calculation + * @detail_slope: Slope value for threshold calculation + * @iir_strength: Relative strength of the IIR fiter + * @strength: Strength factor + * @lut: Look-up table for tonemap curve + */ +struct pisp_be_tonemap_config { + __u16 detail_constant; + __u16 detail_slope; + __u16 iir_strength; + __u16 strength; + __u32 lut[PISP_BE_TONEMAP_LUT_SIZE]; +} __attribute__((packed)); + +/** + * struct pisp_be_demosaic_config - PiSP Back End Demosaic config + * + * Demosaic configuration + * + * @sharper: Use other Bayer channels to increase sharpness + * @fc_mode: Built-in false colour suppression mode + * @pad: Padding bytes + */ +struct pisp_be_demosaic_config { + __u8 sharper; + __u8 fc_mode; + __u8 pad[2]; +} __attribute__((packed)); + +/** + * struct pisp_be_ccm_config - PiSP Back End CCM config + * + * Colour Correction Matrix configuration + * + * @coeffs: Matrix coefficients + * @pad: Padding bytes + * @offsets: Offsets triplet + */ +struct pisp_be_ccm_config { + __s16 coeffs[9]; + __u8 pad[2]; + __s32 offsets[3]; +} __attribute__((packed)); + +/** + * struct pisp_be_sat_control_config - PiSP Back End SAT config + * + * Saturation Control configuration + * + * @shift_r: Left shift for Red colour channel + * @shift_g: Left shift for Green colour channel + * @shift_b: Left shift for Blue colour channel + * @pad: Padding byte + */ +struct pisp_be_sat_control_config { + __u8 shift_r; + __u8 shift_g; + __u8 shift_b; + __u8 pad; +} __attribute__((packed)); + +/** + * struct pisp_be_false_colour_config - PiSP Back End False Colour config + * + * False Colour configuration + * + * @distance: Distance of neighbouring pixels, either 1 or 2 + * @pad: Padding bytes + */ +struct pisp_be_false_colour_config { + __u8 distance; + __u8 pad[3]; +} __attribute__((packed)); #define PISP_BE_SHARPEN_SIZE 5 #define PISP_BE_SHARPEN_FUNC_NUM_POINTS 9 -typedef struct { - int8_t kernel0[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE]; - int8_t pad0[3]; - int8_t kernel1[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE]; - int8_t pad1[3]; - int8_t kernel2[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE]; - int8_t pad2[3]; - int8_t kernel3[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE]; - int8_t pad3[3]; - int8_t kernel4[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE]; - int8_t pad4[3]; - uint16_t threshold_offset0; - uint16_t threshold_slope0; - uint16_t scale0; - uint16_t pad5; - uint16_t threshold_offset1; - uint16_t threshold_slope1; - uint16_t scale1; - uint16_t pad6; - uint16_t threshold_offset2; - uint16_t threshold_slope2; - uint16_t scale2; - uint16_t pad7; - uint16_t threshold_offset3; - uint16_t threshold_slope3; - uint16_t scale3; - uint16_t pad8; - uint16_t threshold_offset4; - uint16_t threshold_slope4; - uint16_t scale4; - uint16_t pad9; - uint16_t positive_strength; - uint16_t positive_pre_limit; - uint16_t positive_func[PISP_BE_SHARPEN_FUNC_NUM_POINTS]; - uint16_t positive_limit; - uint16_t negative_strength; - uint16_t negative_pre_limit; - uint16_t negative_func[PISP_BE_SHARPEN_FUNC_NUM_POINTS]; - uint16_t negative_limit; - uint8_t enables; - uint8_t white; - uint8_t black; - uint8_t grey; -} pisp_be_sharpen_config; - -typedef struct { - uint8_t y_factor; - uint8_t c1_factor; - uint8_t c2_factor; - uint8_t pad; -} pisp_be_sh_fc_combine_config; +/** + * struct pisp_be_sharpen_config - PiSP Back End Sharpening config + * + * Sharpening configuration + * + * @kernel0: Coefficient for filter 0 + * @pad0: Padding byte + * @kernel1: Coefficient for filter 1 + * @pad1: Padding byte + * @kernel2: Coefficient for filter 2 + * @pad2: Padding byte + * @kernel3: Coefficient for filter 3 + * @pad3: Padding byte + * @kernel4: Coefficient for filter 4 + * @pad4: Padding byte + * @threshold_offset0: Offset for filter 0 response calculation + * @threshold_slope0: Slope multiplier for the filter 0 response calculation + * @scale0: Scale factor for filter 0 response calculation + * @pad5: Padding byte + * @threshold_offset1: Offset for filter 0 response calculation + * @threshold_slope1: Slope multiplier for the filter 0 response calculation + * @scale1: Scale factor for filter 0 response calculation + * @pad6: Padding byte + * @threshold_offset2: Offset for filter 0 response calculation + * @threshold_slope2: Slope multiplier for the filter 0 response calculation + * @scale2: Scale factor for filter 0 response calculation + * @pad7: Padding byte + * @threshold_offset3: Offset for filter 0 response calculation + * @threshold_slope3: Slope multiplier for the filter 0 response calculation + * @scale3: Scale factor for filter 0 response calculation + * @pad8: Padding byte + * @threshold_offset4: Offset for filter 0 response calculation + * @threshold_slope4: Slope multiplier for the filter 0 response calculation + * @scale4: Scale factor for filter 0 response calculation + * @pad9: Padding byte + * @positive_strength: Factor to scale the positive sharpening strength + * @positive_pre_limit: Maximum allowed possible positive sharpening value + * @positive_func: Gain factor applied to positive sharpening response + * @positive_limit: Final gain factor applied to positive sharpening + * @negative_strength: Factor to scale the negative sharpening strength + * @negative_pre_limit: Maximum allowed possible negative sharpening value + * @negative_func: Gain factor applied to negative sharpening response + * @negative_limit: Final gain factor applied to negative sharpening + * @enables: Filter enable mask + * @white: White output pixel filter mask + * @black: Black output pixel filter mask + * @grey: Grey output pixel filter mask + */ +struct pisp_be_sharpen_config { + __s8 kernel0[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE]; + __s8 pad0[3]; + __s8 kernel1[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE]; + __s8 pad1[3]; + __s8 kernel2[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE]; + __s8 pad2[3]; + __s8 kernel3[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE]; + __s8 pad3[3]; + __s8 kernel4[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE]; + __s8 pad4[3]; + __u16 threshold_offset0; + __u16 threshold_slope0; + __u16 scale0; + __u16 pad5; + __u16 threshold_offset1; + __u16 threshold_slope1; + __u16 scale1; + __u16 pad6; + __u16 threshold_offset2; + __u16 threshold_slope2; + __u16 scale2; + __u16 pad7; + __u16 threshold_offset3; + __u16 threshold_slope3; + __u16 scale3; + __u16 pad8; + __u16 threshold_offset4; + __u16 threshold_slope4; + __u16 scale4; + __u16 pad9; + __u16 positive_strength; + __u16 positive_pre_limit; + __u16 positive_func[PISP_BE_SHARPEN_FUNC_NUM_POINTS]; + __u16 positive_limit; + __u16 negative_strength; + __u16 negative_pre_limit; + __u16 negative_func[PISP_BE_SHARPEN_FUNC_NUM_POINTS]; + __u16 negative_limit; + __u8 enables; + __u8 white; + __u8 black; + __u8 grey; +} __attribute__((packed)); + +/** + * struct pisp_be_sh_fc_combine_config - PiSP Back End Sharpening and + * False Colour config + * + * Sharpening and False Colour configuration + * + * @y_factor: Control amount of desaturation of pixels being darkened + * @c1_factor: Control amount of brightening of a pixel for the Cb + * channel + * @c2_factor: Control amount of brightening of a pixel for the Cr + * channel + * @pad: Padding byte + */ +struct pisp_be_sh_fc_combine_config { + __u8 y_factor; + __u8 c1_factor; + __u8 c2_factor; + __u8 pad; +} __attribute__((packed)); #define PISP_BE_GAMMA_LUT_SIZE 64 -typedef struct { - uint32_t lut[PISP_BE_GAMMA_LUT_SIZE]; -} pisp_be_gamma_config; +/** + * struct pisp_be_gamma_config - PiSP Back End Gamma configuration + * @lut: Gamma curve look-up table + */ +struct pisp_be_gamma_config { + __u32 lut[PISP_BE_GAMMA_LUT_SIZE]; +} __attribute__((packed)); -typedef struct { - uint16_t offset_x, offset_y; - uint16_t width, height; -} pisp_be_crop_config; +/** + * struct pisp_be_crop_config - PiSP Back End Crop config + * + * Crop configuration + * + * @offset_x: Number of pixels cropped from the left of the tile + * @offset_y: Number of pixels cropped from the top of the tile + * @width: Width of the cropped tile output + * @height: Height of the cropped tile output + */ +struct pisp_be_crop_config { + __u16 offset_x, offset_y; + __u16 width, height; +} __attribute__((packed)); #define PISP_BE_RESAMPLE_FILTER_SIZE 96 -typedef struct { - uint16_t scale_factor_h, scale_factor_v; - int16_t coef[PISP_BE_RESAMPLE_FILTER_SIZE]; -} pisp_be_resample_config; - -typedef struct { - uint16_t scaled_width; - uint16_t scaled_height; - int16_t initial_phase_h[3]; - int16_t initial_phase_v[3]; -} pisp_be_resample_extra; - -typedef struct { - uint16_t scale_factor_h; - uint16_t scale_factor_v; - uint16_t scale_recip_h; - uint16_t scale_recip_v; -} pisp_be_downscale_config; - -typedef struct { - uint16_t scaled_width; - uint16_t scaled_height; -} pisp_be_downscale_extra; - -typedef struct { - uint8_t compute_signed; - uint8_t channel_mix[3]; - uint32_t stride; -} pisp_be_hog_config; - -typedef struct { - uint8_t r_qos; /* Read QoS */ - uint8_t r_cache_prot; /* Read { prot[2:0], cache[3:0] } */ - uint8_t w_qos; /* Write QoS */ - uint8_t w_cache_prot; /* Write { prot[2:0], cache[3:0] } */ -} pisp_be_axi_config; - -typedef enum { +/** + * struct pisp_be_resample_config - PiSP Back End Resampling config + * + * Resample configuration + * + * @scale_factor_h: Horizontal scale factor + * @scale_factor_v: Vertical scale factor + * @coef: Resample coefficients + */ +struct pisp_be_resample_config { + __u16 scale_factor_h, scale_factor_v; + __s16 coef[PISP_BE_RESAMPLE_FILTER_SIZE]; +} __attribute__((packed)); + +/** + * struct pisp_be_resample_extra - PiSP Back End Resample config + * + * Resample configuration + * + * @scaled_width: Width in pixels of the scaled output + * @scaled_height: Height in pixels of the scaled output + * @initial_phase_h: Initial horizontal phase + * @initial_phase_v: Initial vertical phase + */ +struct pisp_be_resample_extra { + __u16 scaled_width; + __u16 scaled_height; + __s16 initial_phase_h[3]; + __s16 initial_phase_v[3]; +} __attribute__((packed)); + +/** + * struct pisp_be_downscale_config - PiSP Back End Downscale config + * + * Downscale configuration + * + * @scale_factor_h: Horizontal scale factor + * @scale_factor_v: Vertical scale factor + * @scale_recip_h: Horizontal reciprocal factor + * @scale_recip_v: Vertical reciprocal factor + */ +struct pisp_be_downscale_config { + __u16 scale_factor_h; + __u16 scale_factor_v; + __u16 scale_recip_h; + __u16 scale_recip_v; +} __attribute__((packed)); + +/** + * struct pisp_be_downscale_extra - PiSP Back End Downscale Extra config + * @scaled_width: Scaled image width + * @scaled_height: Scaled image height + */ +struct pisp_be_downscale_extra { + __u16 scaled_width; + __u16 scaled_height; +} __attribute__((packed)); + +/** + * struct pisp_be_hog_config - PiSP Back End HOG config + * + * Histogram of Oriented Gradients configuration + * + * @compute_signed: Set 0 for unsigned gradients, 1 for signed + * @channel_mix: Channels proportions to use + * @stride: Stride in bytes between blocks directly below + */ +struct pisp_be_hog_config { + __u8 compute_signed; + __u8 channel_mix[3]; + __u32 stride; +} __attribute__((packed)); + +struct pisp_be_axi_config { + __u8 r_qos; /* Read QoS */ + __u8 r_cache_prot; /* Read { prot[2:0], cache[3:0] } */ + __u8 w_qos; /* Write QoS */ + __u8 w_cache_prot; /* Write { prot[2:0], cache[3:0] } */ +} __attribute__((packed)); + +/** + * enum pisp_be_transform - PiSP Back End Transform flags + * @PISP_BE_TRANSFORM_NONE: No transform + * @PISP_BE_TRANSFORM_HFLIP: Horizontal flip + * @PISP_BE_TRANSFORM_VFLIP: Vertical flip + * @PISP_BE_TRANSFORM_ROT180: 180 degress rotation + */ +enum pisp_be_transform { PISP_BE_TRANSFORM_NONE = 0x0, PISP_BE_TRANSFORM_HFLIP = 0x1, PISP_BE_TRANSFORM_VFLIP = 0x2, PISP_BE_TRANSFORM_ROT180 = (PISP_BE_TRANSFORM_HFLIP | PISP_BE_TRANSFORM_VFLIP) -} pisp_be_transform; - -typedef struct { - pisp_image_format_config image; - uint8_t transform; - uint8_t pad[3]; - uint16_t lo; - uint16_t hi; - uint16_t lo2; - uint16_t hi2; -} pisp_be_output_format_config; - -typedef struct { +}; + +struct pisp_be_output_format_config { + struct pisp_image_format_config image; + __u8 transform; + __u8 pad[3]; + __u16 lo; + __u16 hi; + __u16 lo2; + __u16 hi2; +} __attribute__((packed)); + +/** + * struct pisp_be_output_buffer_config - PiSP Back End Output buffer + * @addr: Output buffer address + */ +struct pisp_be_output_buffer_config { /* low 32 bits followed by high 32 bits (for each of 3 planes) */ - uint32_t addr[3][2]; -} pisp_be_output_buffer_config; + __u32 addr[3][2]; +} __attribute__((packed)); -typedef struct { +/** + * struct pisp_be_hog_buffer_config - PiSP Back End HOG buffer + * @addr: HOG buffer address + */ +struct pisp_be_hog_buffer_config { /* low 32 bits followed by high 32 bits */ - uint32_t addr[2]; -} pisp_be_hog_buffer_config; + __u32 addr[2]; +} __attribute__((packed)); -typedef struct { - /* For backward compatibility */ - uint8_t pad0[112]; +/** + * struct pisp_be_config - RaspberryPi PiSP Back End Processing configuration + * + * @input_buffer: Input buffer addresses + * @tdn_input_buffer: TDN input buffer addresses + * @stitch_input_buffer: Stitch input buffer addresses + * @tdn_output_buffer: TDN output buffer addresses + * @stitch_output_buffer: Stitch output buffer addresses + * @output_buffer: Output buffers addresses + * @hog_buffer: HOG buffer addresses + * @global: Global PiSP configuration + * @input_format: Input image format + * @decompress: Decompress configuration + * @dpc: Defective Pixel Correction configuration + * @geq: Green Equalisation configuration + * @tdn_input_format: Temporal Denoise input format + * @tdn_decompress: Temporal Denoise decompress configuration + * @tdn: Temporal Denoise configuration + * @tdn_compress: Temporal Denoise compress configuration + * @tdn_output_format: Temporal Denoise output format + * @sdn: Spatial Denoise configuration + * @blc: Black Level Correction configuration + * @stitch_compress: Stitch compress configuration + * @stitch_output_format: Stitch output format + * @stitch_input_format: Stitch input format + * @stitch_decompress: Stitch decompress configuration + * @stitch: Stitch configuration + * @lsc: Lens Shading Correction configuration + * @wbg: White Balance Gain configuration + * @cdn: Colour Denoise configuration + * @cac: Colour Aberration Correction configuration + * @debin: Debinning configuration + * @tonemap: Tonemapping configuration + * @demosaic: Demosaicing configuration + * @ccm: Colour Correction Matrix configuration + * @sat_control: Saturation Control configuration + * @ycbcr: YCbCr colour correction configuration + * @sharpen: Sharpening configuration + * @false_colour: False colour correction + * @sh_fc_combine: Sharpening and False Colour correction + * @ycbcr_inverse: Inverse YCbCr colour correction + * @gamma: Gamma curve configuration + * @csc: Color Space Conversion configuration + * @downscale: Downscale configuration + * @resample: Resampling configuration + * @output_format: Output format configuration + * @hog: HOG configuration + * @axi: AXI bus configuration + * @lsc_extra: LSC extra info + * @cac_extra: CAC extra info + * @downscale_extra: Downscaler extra info + * @resample_extra: Resample extra info + * @crop: Crop configuration + * @hog_format: HOG format info + * @dirty_flags_bayer: Bayer enable dirty flags + * (:c:type:`pisp_be_bayer_enable`) + * @dirty_flags_rgb: RGB enable dirty flags + * (:c:type:`pisp_be_rgb_enable`) + * @dirty_flags_extra: Extra dirty flags + */ +struct pisp_be_config { + /* I/O configuration: */ + struct pisp_be_input_buffer_config input_buffer; + struct pisp_be_tdn_input_buffer_config tdn_input_buffer; + struct pisp_be_stitch_input_buffer_config stitch_input_buffer; + struct pisp_be_tdn_output_buffer_config tdn_output_buffer; + struct pisp_be_stitch_output_buffer_config stitch_output_buffer; + struct pisp_be_output_buffer_config + output_buffer[PISP_BACK_END_NUM_OUTPUTS]; + struct pisp_be_hog_buffer_config hog_buffer; /* Processing configuration: */ - pisp_be_global_config global; - pisp_image_format_config input_format; - pisp_decompress_config decompress; - pisp_be_dpc_config dpc; - pisp_be_geq_config geq; - pisp_image_format_config tdn_input_format; - pisp_decompress_config tdn_decompress; - pisp_be_tdn_config tdn; - pisp_compress_config tdn_compress; - pisp_image_format_config tdn_output_format; - pisp_be_sdn_config sdn; - pisp_bla_config blc; - pisp_compress_config stitch_compress; - pisp_image_format_config stitch_output_format; - pisp_image_format_config stitch_input_format; - pisp_decompress_config stitch_decompress; - pisp_be_stitch_config stitch; - pisp_be_lsc_config lsc; - pisp_wbg_config wbg; - pisp_be_cdn_config cdn; - pisp_be_cac_config cac; - pisp_be_debin_config debin; - pisp_be_tonemap_config tonemap; - pisp_be_demosaic_config demosaic; - pisp_be_ccm_config ccm; - pisp_be_sat_control_config sat_control; - pisp_be_ccm_config ycbcr; - pisp_be_sharpen_config sharpen; - pisp_be_false_colour_config false_colour; - pisp_be_sh_fc_combine_config sh_fc_combine; - pisp_be_ccm_config ycbcr_inverse; - pisp_be_gamma_config gamma; - pisp_be_ccm_config csc[PISP_BACK_END_NUM_OUTPUTS]; - pisp_be_downscale_config downscale[PISP_BACK_END_NUM_OUTPUTS]; - pisp_be_resample_config resample[PISP_BACK_END_NUM_OUTPUTS]; - pisp_be_output_format_config + struct pisp_be_global_config global; + struct pisp_image_format_config input_format; + struct pisp_decompress_config decompress; + struct pisp_be_dpc_config dpc; + struct pisp_be_geq_config geq; + struct pisp_image_format_config tdn_input_format; + struct pisp_decompress_config tdn_decompress; + struct pisp_be_tdn_config tdn; + struct pisp_compress_config tdn_compress; + struct pisp_image_format_config tdn_output_format; + struct pisp_be_sdn_config sdn; + struct pisp_bla_config blc; + struct pisp_compress_config stitch_compress; + struct pisp_image_format_config stitch_output_format; + struct pisp_image_format_config stitch_input_format; + struct pisp_decompress_config stitch_decompress; + struct pisp_be_stitch_config stitch; + struct pisp_be_lsc_config lsc; + struct pisp_wbg_config wbg; + struct pisp_be_cdn_config cdn; + struct pisp_be_cac_config cac; + struct pisp_be_debin_config debin; + struct pisp_be_tonemap_config tonemap; + struct pisp_be_demosaic_config demosaic; + struct pisp_be_ccm_config ccm; + struct pisp_be_sat_control_config sat_control; + struct pisp_be_ccm_config ycbcr; + struct pisp_be_sharpen_config sharpen; + struct pisp_be_false_colour_config false_colour; + struct pisp_be_sh_fc_combine_config sh_fc_combine; + struct pisp_be_ccm_config ycbcr_inverse; + struct pisp_be_gamma_config gamma; + struct pisp_be_ccm_config csc[PISP_BACK_END_NUM_OUTPUTS]; + struct pisp_be_downscale_config downscale[PISP_BACK_END_NUM_OUTPUTS]; + struct pisp_be_resample_config resample[PISP_BACK_END_NUM_OUTPUTS]; + struct pisp_be_output_format_config output_format[PISP_BACK_END_NUM_OUTPUTS]; - pisp_be_hog_config hog; - pisp_be_axi_config axi; - /* For backward compatibility */ - uint8_t pad1[84]; -} pisp_be_config; - -static_assert(sizeof(pisp_be_config) == 6476, "pisp_be_config not packed as expected"); - -/* - * We also need a tile structure to describe the size of the tiles going - * through the pipeline. + struct pisp_be_hog_config hog; + struct pisp_be_axi_config axi; + /* Non-register fields: */ + struct pisp_be_lsc_extra lsc_extra; + struct pisp_be_cac_extra cac_extra; + struct pisp_be_downscale_extra + downscale_extra[PISP_BACK_END_NUM_OUTPUTS]; + struct pisp_be_resample_extra resample_extra[PISP_BACK_END_NUM_OUTPUTS]; + struct pisp_be_crop_config crop; + struct pisp_image_format_config hog_format; + __u32 dirty_flags_bayer; /* these use pisp_be_bayer_enable */ + __u32 dirty_flags_rgb; /* use pisp_be_rgb_enable */ + __u32 dirty_flags_extra; /* these use pisp_be_dirty_t */ +} __attribute__((packed)); + +/** + * enum pisp_tile_edge - PiSP Back End Tile position + * @PISP_LEFT_EDGE: Left edge tile + * @PISP_RIGHT_EDGE: Right edge tile + * @PISP_TOP_EDGE: Top edge tile + * @PISP_BOTTOM_EDGE: Bottom edge tile */ - -typedef enum { +enum pisp_tile_edge { PISP_LEFT_EDGE = (1 << 0), PISP_RIGHT_EDGE = (1 << 1), PISP_TOP_EDGE = (1 << 2), PISP_BOTTOM_EDGE = (1 << 3) -} pisp_tile_edge; - -typedef struct { - uint8_t edge; // enum pisp_tile_edge - uint8_t pad0[3]; - // 4 bytes - uint32_t input_addr_offset; - uint32_t input_addr_offset2; - uint16_t input_offset_x; - uint16_t input_offset_y; - uint16_t input_width; - uint16_t input_height; - // 20 bytes - uint32_t tdn_input_addr_offset; - uint32_t tdn_output_addr_offset; - uint32_t stitch_input_addr_offset; - uint32_t stitch_output_addr_offset; - // 36 bytes - uint32_t lsc_grid_offset_x; - uint32_t lsc_grid_offset_y; - // 44 bytes - uint32_t cac_grid_offset_x; - uint32_t cac_grid_offset_y; - // 52 bytes - uint16_t crop_x_start[PISP_BACK_END_NUM_OUTPUTS]; - uint16_t crop_x_end[PISP_BACK_END_NUM_OUTPUTS]; - uint16_t crop_y_start[PISP_BACK_END_NUM_OUTPUTS]; - uint16_t crop_y_end[PISP_BACK_END_NUM_OUTPUTS]; - // 68 bytes +}; + +/** + * struct pisp_tile - Raspberry Pi PiSP Back End tile configuration + * + * Tile parameters: each set of tile parameters is a 160-bytes block of data + * which contains the tile processing parameters. + * + * @edge: Edge tile flag + * @pad0: Padding bytes + * @input_addr_offset: Top-left pixel offset, in bytes + * @input_addr_offset2: Top-left pixel offset, in bytes for the second/ + * third image planes + * @input_offset_x: Horizontal offset in pixels of this tile in the + * input image + * @input_offset_y: Vertical offset in pixels of this tile in the + * input image + * @input_width: Width in pixels of this tile + * @input_height: Height in pixels of the this tile + * @tdn_input_addr_offset: TDN input image offset, in bytes + * @tdn_output_addr_offset: TDN output image offset, in bytes + * @stitch_input_addr_offset: Stitch input image offset, in bytes + * @stitch_output_addr_offset: Stitch output image offset, in bytes + * @lsc_grid_offset_x: Horizontal offset in the LSC table for this tile + * @lsc_grid_offset_y: Vertical offset in the LSC table for this tile + * @cac_grid_offset_x: Horizontal offset in the CAC table for this tile + * @cac_grid_offset_y: Horizontal offset in the CAC table for this tile + * @crop_x_start: Number of pixels cropped from the left of the + * tile + * @crop_x_end: Number of pixels cropped from the right of the + * tile + * @crop_y_start: Number of pixels cropped from the top of the + * tile + * @crop_y_end: Number of pixels cropped from the bottom of the + * tile + * @downscale_phase_x: Initial horizontal phase in pixels + * @downscale_phase_y: Initial vertical phase in pixels + * @resample_in_width: Width in pixels of the tile entering the + * Resample block + * @resample_in_height: Height in pixels of the tile entering the + * Resample block + * @resample_phase_x: Initial horizontal phase for the Resample block + * @resample_phase_y: Initial vertical phase for the Resample block + * @output_offset_x: Horizontal offset in pixels where the tile will + * be written into the output image + * @output_offset_y: Vertical offset in pixels where the tile will be + * written into the output image + * @output_width: Width in pixels in the output image of this tile + * @output_height: Height in pixels in the output image of this tile + * @output_addr_offset: Offset in bytes into the output buffer + * @output_addr_offset2: Offset in bytes into the output buffer for the + * second and third plane + * @output_hog_addr_offset: Offset in bytes into the HOG buffer where + * results of this tile are to be written + */ +struct pisp_tile { + __u8 edge; /* enum pisp_tile_edge */ + __u8 pad0[3]; + /* 4 bytes */ + __u32 input_addr_offset; + __u32 input_addr_offset2; + __u16 input_offset_x; + __u16 input_offset_y; + __u16 input_width; + __u16 input_height; + /* 20 bytes */ + __u32 tdn_input_addr_offset; + __u32 tdn_output_addr_offset; + __u32 stitch_input_addr_offset; + __u32 stitch_output_addr_offset; + /* 36 bytes */ + __u32 lsc_grid_offset_x; + __u32 lsc_grid_offset_y; + /* 44 bytes */ + __u32 cac_grid_offset_x; + __u32 cac_grid_offset_y; + /* 52 bytes */ + __u16 crop_x_start[PISP_BACK_END_NUM_OUTPUTS]; + __u16 crop_x_end[PISP_BACK_END_NUM_OUTPUTS]; + __u16 crop_y_start[PISP_BACK_END_NUM_OUTPUTS]; + __u16 crop_y_end[PISP_BACK_END_NUM_OUTPUTS]; + /* 68 bytes */ /* Ordering is planes then branches */ - uint16_t downscale_phase_x[3 * PISP_BACK_END_NUM_OUTPUTS]; - uint16_t downscale_phase_y[3 * PISP_BACK_END_NUM_OUTPUTS]; - // 92 bytes - uint16_t resample_in_width[PISP_BACK_END_NUM_OUTPUTS]; - uint16_t resample_in_height[PISP_BACK_END_NUM_OUTPUTS]; - // 100 bytes + __u16 downscale_phase_x[3 * PISP_BACK_END_NUM_OUTPUTS]; + __u16 downscale_phase_y[3 * PISP_BACK_END_NUM_OUTPUTS]; + /* 92 bytes */ + __u16 resample_in_width[PISP_BACK_END_NUM_OUTPUTS]; + __u16 resample_in_height[PISP_BACK_END_NUM_OUTPUTS]; + /* 100 bytes */ /* Ordering is planes then branches */ - uint16_t resample_phase_x[3 * PISP_BACK_END_NUM_OUTPUTS]; - uint16_t resample_phase_y[3 * PISP_BACK_END_NUM_OUTPUTS]; - // 124 bytes - uint16_t output_offset_x[PISP_BACK_END_NUM_OUTPUTS]; - uint16_t output_offset_y[PISP_BACK_END_NUM_OUTPUTS]; - uint16_t output_width[PISP_BACK_END_NUM_OUTPUTS]; - uint16_t output_height[PISP_BACK_END_NUM_OUTPUTS]; - // 140 bytes - uint32_t output_addr_offset[PISP_BACK_END_NUM_OUTPUTS]; - uint32_t output_addr_offset2[PISP_BACK_END_NUM_OUTPUTS]; - // 156 bytes - uint32_t output_hog_addr_offset; - // 160 bytes -} pisp_tile; - -static_assert(sizeof(pisp_tile) == 160, "pisp_tile not packed as expected"); - -typedef struct { - pisp_be_config config; - pisp_tile tiles[PISP_BACK_END_NUM_TILES]; - int num_tiles; -} pisp_be_tiles_config; + __u16 resample_phase_x[3 * PISP_BACK_END_NUM_OUTPUTS]; + __u16 resample_phase_y[3 * PISP_BACK_END_NUM_OUTPUTS]; + /* 124 bytes */ + __u16 output_offset_x[PISP_BACK_END_NUM_OUTPUTS]; + __u16 output_offset_y[PISP_BACK_END_NUM_OUTPUTS]; + __u16 output_width[PISP_BACK_END_NUM_OUTPUTS]; + __u16 output_height[PISP_BACK_END_NUM_OUTPUTS]; + /* 140 bytes */ + __u32 output_addr_offset[PISP_BACK_END_NUM_OUTPUTS]; + __u32 output_addr_offset2[PISP_BACK_END_NUM_OUTPUTS]; + /* 156 bytes */ + __u32 output_hog_addr_offset; + /* 160 bytes */ +} __attribute__((packed)); + +/** + * struct pisp_be_tiles_config - Raspberry Pi PiSP Back End configuration + * @tiles: Tile descriptors + * @num_tiles: Number of tiles + * @config: PiSP Back End configuration + */ +struct pisp_be_tiles_config { + struct pisp_be_config config; + struct pisp_tile tiles[PISP_BACK_END_NUM_TILES]; + __u32 num_tiles; +} __attribute__((packed)); #endif /* _PISP_BE_CONFIG_H_ */ diff --git a/src/libpisp/common/meson.build b/src/libpisp/common/meson.build index 5798802..ea327c6 100644 --- a/src/libpisp/common/meson.build +++ b/src/libpisp/common/meson.build @@ -10,7 +10,6 @@ pisp_sources += files([ common_headers = files([ 'pisp_common.h', 'logging.hpp', - 'pisp_types.h', 'shm_mutex.hpp', 'utils.hpp', 'version.hpp', diff --git a/src/libpisp/common/pisp_common.h b/src/libpisp/common/pisp_common.h index a8d6b39..2bbff9f 100644 --- a/src/libpisp/common/pisp_common.h +++ b/src/libpisp/common/pisp_common.h @@ -1,73 +1,202 @@ /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* - * Copyright (C) 2021 - 2023, Raspberry Pi Ltd + * RP1 PiSP common definitions. + * + * Copyright (C) 2021 - Raspberry Pi Ltd. * - * pisp_common.h - Raspberry Pi PiSP common configuration definitions */ #ifndef _PISP_COMMON_H_ #define _PISP_COMMON_H_ #include -#include "pisp_types.h" - -typedef struct { - uint16_t black_level_r; - uint16_t black_level_gr; - uint16_t black_level_gb; - uint16_t black_level_b; - uint16_t output_black_level; - uint8_t pad[2]; -} pisp_bla_config; - -typedef struct { - uint16_t gain_r; - uint16_t gain_g; - uint16_t gain_b; - uint8_t pad[2]; -} pisp_wbg_config; - -typedef struct { +struct pisp_image_format_config { + /* size in pixels */ + __u16 width; + __u16 height; + /* must match struct pisp_image_format below */ + __u32 format; + __s32 stride; + /* some planar image formats will need a second stride */ + __s32 stride2; +} __attribute__((packed)); + +enum pisp_bayer_order { + /* + * Note how bayer_order&1 tells you if G is on the even pixels of the + * checkerboard or not, and bayer_order&2 tells you if R is on the even + * rows or is swapped with B. Note that if the top (of the 8) bits is + * set, this denotes a monochrome or greyscale image, and the lower bits + * should all be ignored. + */ + PISP_BAYER_ORDER_RGGB = 0, + PISP_BAYER_ORDER_GBRG = 1, + PISP_BAYER_ORDER_BGGR = 2, + PISP_BAYER_ORDER_GRBG = 3, + PISP_BAYER_ORDER_GREYSCALE = 128 +}; + +enum pisp_image_format { + /* + * Precise values are mostly tbd. Generally these will be portmanteau + * values comprising bit fields and flags. This format must be shared + * throughout the PiSP. + */ + PISP_IMAGE_FORMAT_BPS_8 = 0x00000000, + PISP_IMAGE_FORMAT_BPS_10 = 0x00000001, + PISP_IMAGE_FORMAT_BPS_12 = 0x00000002, + PISP_IMAGE_FORMAT_BPS_16 = 0x00000003, + PISP_IMAGE_FORMAT_BPS_MASK = 0x00000003, + + PISP_IMAGE_FORMAT_PLANARITY_INTERLEAVED = 0x00000000, + PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR = 0x00000010, + PISP_IMAGE_FORMAT_PLANARITY_PLANAR = 0x00000020, + PISP_IMAGE_FORMAT_PLANARITY_MASK = 0x00000030, + + PISP_IMAGE_FORMAT_SAMPLING_444 = 0x00000000, + PISP_IMAGE_FORMAT_SAMPLING_422 = 0x00000100, + PISP_IMAGE_FORMAT_SAMPLING_420 = 0x00000200, + PISP_IMAGE_FORMAT_SAMPLING_MASK = 0x00000300, + + PISP_IMAGE_FORMAT_ORDER_NORMAL = 0x00000000, + PISP_IMAGE_FORMAT_ORDER_SWAPPED = 0x00001000, + + PISP_IMAGE_FORMAT_SHIFT_0 = 0x00000000, + PISP_IMAGE_FORMAT_SHIFT_1 = 0x00010000, + PISP_IMAGE_FORMAT_SHIFT_2 = 0x00020000, + PISP_IMAGE_FORMAT_SHIFT_3 = 0x00030000, + PISP_IMAGE_FORMAT_SHIFT_4 = 0x00040000, + PISP_IMAGE_FORMAT_SHIFT_5 = 0x00050000, + PISP_IMAGE_FORMAT_SHIFT_6 = 0x00060000, + PISP_IMAGE_FORMAT_SHIFT_7 = 0x00070000, + PISP_IMAGE_FORMAT_SHIFT_8 = 0x00080000, + PISP_IMAGE_FORMAT_SHIFT_MASK = 0x000f0000, + + PISP_IMAGE_FORMAT_BPP_32 = 0x00100000, + + PISP_IMAGE_FORMAT_UNCOMPRESSED = 0x00000000, + PISP_IMAGE_FORMAT_COMPRESSION_MODE_1 = 0x01000000, + PISP_IMAGE_FORMAT_COMPRESSION_MODE_2 = 0x02000000, + PISP_IMAGE_FORMAT_COMPRESSION_MODE_3 = 0x03000000, + PISP_IMAGE_FORMAT_COMPRESSION_MASK = 0x03000000, + + PISP_IMAGE_FORMAT_HOG_SIGNED = 0x04000000, + PISP_IMAGE_FORMAT_HOG_UNSIGNED = 0x08000000, + PISP_IMAGE_FORMAT_INTEGRAL_IMAGE = 0x10000000, + PISP_IMAGE_FORMAT_WALLPAPER_ROLL = 0x20000000, + PISP_IMAGE_FORMAT_THREE_CHANNEL = 0x40000000, + + /* Lastly a few specific instantiations of the above. */ + PISP_IMAGE_FORMAT_SINGLE_16 = PISP_IMAGE_FORMAT_BPS_16, + PISP_IMAGE_FORMAT_THREE_16 = PISP_IMAGE_FORMAT_BPS_16 | + PISP_IMAGE_FORMAT_THREE_CHANNEL +}; + +#define PISP_IMAGE_FORMAT_BPS_8(fmt) \ + (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_8) +#define PISP_IMAGE_FORMAT_BPS_10(fmt) \ + (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_10) +#define PISP_IMAGE_FORMAT_BPS_12(fmt) \ + (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_12) +#define PISP_IMAGE_FORMAT_BPS_16(fmt) \ + (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_16) +#define PISP_IMAGE_FORMAT_BPS(fmt) \ + (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) ? \ + 8 + (2 << (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) - 1)) : 8) +#define PISP_IMAGE_FORMAT_SHIFT(fmt) \ + (((fmt) & PISP_IMAGE_FORMAT_SHIFT_MASK) / PISP_IMAGE_FORMAT_SHIFT_1) +#define PISP_IMAGE_FORMAT_THREE_CHANNEL(fmt) \ + ((fmt) & PISP_IMAGE_FORMAT_THREE_CHANNEL) +#define PISP_IMAGE_FORMAT_SINGLE_CHANNEL(fmt) \ + (!((fmt) & PISP_IMAGE_FORMAT_THREE_CHANNEL)) +#define PISP_IMAGE_FORMAT_COMPRESSED(fmt) \ + (((fmt) & PISP_IMAGE_FORMAT_COMPRESSION_MASK) != \ + PISP_IMAGE_FORMAT_UNCOMPRESSED) +#define PISP_IMAGE_FORMAT_SAMPLING_444(fmt) \ + (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == \ + PISP_IMAGE_FORMAT_SAMPLING_444) +#define PISP_IMAGE_FORMAT_SAMPLING_422(fmt) \ + (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == \ + PISP_IMAGE_FORMAT_SAMPLING_422) +#define PISP_IMAGE_FORMAT_SAMPLING_420(fmt) \ + (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == \ + PISP_IMAGE_FORMAT_SAMPLING_420) +#define PISP_IMAGE_FORMAT_ORDER_NORMAL(fmt) \ + (!((fmt) & PISP_IMAGE_FORMAT_ORDER_SWAPPED)) +#define PISP_IMAGE_FORMAT_ORDER_SWAPPED(fmt) \ + ((fmt) & PISP_IMAGE_FORMAT_ORDER_SWAPPED) +#define PISP_IMAGE_FORMAT_INTERLEAVED(fmt) \ + (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == \ + PISP_IMAGE_FORMAT_PLANARITY_INTERLEAVED) +#define PISP_IMAGE_FORMAT_SEMIPLANAR(fmt) \ + (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == \ + PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR) +#define PISP_IMAGE_FORMAT_PLANAR(fmt) \ + (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == \ + PISP_IMAGE_FORMAT_PLANARITY_PLANAR) +#define PISP_IMAGE_FORMAT_WALLPAPER(fmt) \ + ((fmt) & PISP_IMAGE_FORMAT_WALLPAPER_ROLL) +#define PISP_IMAGE_FORMAT_BPP_32(fmt) ((fmt) & PISP_IMAGE_FORMAT_BPP_32) +#define PISP_IMAGE_FORMAT_HOG(fmt) \ + ((fmt) & \ + (PISP_IMAGE_FORMAT_HOG_SIGNED | PISP_IMAGE_FORMAT_HOG_UNSIGNED)) + +#define PISP_WALLPAPER_WIDTH 128 /* in bytes */ + +struct pisp_bla_config { + __u16 black_level_r; + __u16 black_level_gr; + __u16 black_level_gb; + __u16 black_level_b; + __u16 output_black_level; + __u8 pad[2]; +} __attribute__((packed)); + +struct pisp_wbg_config { + __u16 gain_r; + __u16 gain_g; + __u16 gain_b; + __u8 pad[2]; +} __attribute__((packed)); + +struct pisp_compress_config { /* value subtracted from incoming data */ - uint16_t offset; - uint8_t pad; + __u16 offset; + __u8 pad; /* 1 => Companding; 2 => Delta (recommended); 3 => Combined (for HDR) */ - uint8_t mode; -} pisp_compress_config; + __u8 mode; +} __attribute__((packed)); -typedef struct { +struct pisp_decompress_config { /* value added to reconstructed data */ - uint16_t offset; - uint8_t pad; + __u16 offset; + __u8 pad; /* 1 => Companding; 2 => Delta (recommended); 3 => Combined (for HDR) */ - uint8_t mode; -} pisp_decompress_config; + __u8 mode; +} __attribute__((packed)); -typedef enum { - /* round down bursts to end at a 32-byte boundary, to align following bursts */ +enum pisp_axi_flags { + /* + * round down bursts to end at a 32-byte boundary, to align following + * bursts + */ PISP_AXI_FLAG_ALIGN = 128, - /* for FE writer: force WSTRB high, to pad output to 16-byte boundary */ + /* for FE writer: force WSTRB high, to pad output to 16-byte boundary */ PISP_AXI_FLAG_PAD = 64, /* for FE writer: Use Output FIFO level to trigger "panic" */ - PISP_AXI_FLAG_PANIC = 32 -} pisp_axi_flags; + PISP_AXI_FLAG_PANIC = 32, +}; -typedef struct { - /* burst length minus one, which must be in the range 0:15; OR'd with flags */ - uint8_t maxlen_flags; +struct pisp_axi_config { + /* + * burst length minus one, which must be in the range 0:15; OR'd with + * flags + */ + __u8 maxlen_flags; /* { prot[2:0], cache[3:0] } fields, echoed on AXI bus */ - uint8_t cache_prot; + __u8 cache_prot; /* QoS field(s) (4x4 bits for FE writer; 4 bits for other masters) */ - uint16_t qos; -} pisp_axi_config; - -/* The metadata format identifier for BE configuration buffers. */ -#define V4L2_META_FMT_RPI_BE_CFG v4l2_fourcc('R', 'P', 'B', 'C') - -/* The metadata format identifier for FE configuration buffers. */ -#define V4L2_META_FMT_RPI_FE_CFG v4l2_fourcc('R', 'P', 'F', 'C') - -/* The metadata format identifier for FE configuration buffers. */ -#define V4L2_META_FMT_RPI_FE_STATS v4l2_fourcc('R', 'P', 'F', 'S') + __u16 qos; +} __attribute__((packed)); #endif /* _PISP_COMMON_H_ */ diff --git a/src/libpisp/common/pisp_types.h b/src/libpisp/common/pisp_types.h deleted file mode 100644 index 2b95387..0000000 --- a/src/libpisp/common/pisp_types.h +++ /dev/null @@ -1,155 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ -/* - * Copyright (C) 2021 - 2023, Raspberry Pi Ltd - * - * pisp_types.h - Raspberry Pi PiSP common types - */ -#pragma once - -#include -#include - -/* This definition must match the format description in the hardware exactly! */ -typedef struct { - /* size in pixels */ - uint16_t width, height; - /* must match struct pisp_image_format below */ - uint32_t format; - int32_t stride; - /* some planar image formats will need a second stride */ - int32_t stride2; -} pisp_image_format_config; - -static_assert(sizeof(pisp_image_format_config) == 16, "pisp_image_format_config not packed as expected"); - -typedef enum { - PISP_FAIL = -1, // generic failure code - PISP_SUCCESS = 0 - // other more specific failure codes here... -} pisp_status; - -typedef enum { - /* - * Note how bayer_order&1 tells you if G is on the even pixels of the - * checkerboard or not, and bayer_order&2 tells you if R is on the even - * rows or is swapped with B. Note that if the top (of the 8) bits is - * set, this denotes a monochrome or greyscale image, and the lower bits - * should all be ignored. - */ - PISP_BAYER_ORDER_RGGB = 0, - PISP_BAYER_ORDER_GBRG = 1, - PISP_BAYER_ORDER_BGGR = 2, - PISP_BAYER_ORDER_GRBG = 3, - PISP_BAYER_ORDER_GREYSCALE = 128 -} pisp_bayer_order; - -typedef enum { - /* - * Precise values are mostly tbd. Generally these will be portmanteau - * values comprising bit fields and flags. This format must be shared - * throughout the PiSP. - */ - PISP_IMAGE_FORMAT_BPS_8 = 0x00000000, - PISP_IMAGE_FORMAT_BPS_10 = 0x00000001, - PISP_IMAGE_FORMAT_BPS_12 = 0x00000002, - PISP_IMAGE_FORMAT_BPS_16 = 0x00000003, - PISP_IMAGE_FORMAT_BPS_MASK = 0x00000003, - - PISP_IMAGE_FORMAT_PLANARITY_INTERLEAVED = 0x00000000, - PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR = 0x00000010, - PISP_IMAGE_FORMAT_PLANARITY_PLANAR = 0x00000020, - PISP_IMAGE_FORMAT_PLANARITY_MASK = 0x00000030, - - PISP_IMAGE_FORMAT_SAMPLING_444 = 0x00000000, - PISP_IMAGE_FORMAT_SAMPLING_422 = 0x00000100, - PISP_IMAGE_FORMAT_SAMPLING_420 = 0x00000200, - PISP_IMAGE_FORMAT_SAMPLING_MASK = 0x00000300, - - PISP_IMAGE_FORMAT_ORDER_NORMAL = 0x00000000, - PISP_IMAGE_FORMAT_ORDER_SWAPPED = 0x00001000, - - PISP_IMAGE_FORMAT_SHIFT_0 = 0x00000000, - PISP_IMAGE_FORMAT_SHIFT_1 = 0x00010000, - PISP_IMAGE_FORMAT_SHIFT_2 = 0x00020000, - PISP_IMAGE_FORMAT_SHIFT_3 = 0x00030000, - PISP_IMAGE_FORMAT_SHIFT_4 = 0x00040000, - PISP_IMAGE_FORMAT_SHIFT_5 = 0x00050000, - PISP_IMAGE_FORMAT_SHIFT_6 = 0x00060000, - PISP_IMAGE_FORMAT_SHIFT_7 = 0x00070000, - PISP_IMAGE_FORMAT_SHIFT_8 = 0x00080000, - PISP_IMAGE_FORMAT_SHIFT_MASK = 0x000f0000, - - PISP_IMAGE_FORMAT_BPP_32 = 0x00100000, - PISP_IMAGE_FORMAT_X_VALUE = 0x00200000, - - PISP_IMAGE_FORMAT_UNCOMPRESSED = 0x00000000, - PISP_IMAGE_FORMAT_COMPRESSION_MODE_1 = 0x01000000, - PISP_IMAGE_FORMAT_COMPRESSION_MODE_2 = 0x02000000, - PISP_IMAGE_FORMAT_COMPRESSION_MODE_3 = 0x03000000, - PISP_IMAGE_FORMAT_COMPRESSION_MASK = 0x03000000, - - PISP_IMAGE_FORMAT_HOG_SIGNED = 0x04000000, - PISP_IMAGE_FORMAT_HOG_UNSIGNED = 0x08000000, - PISP_IMAGE_FORMAT_INTEGRAL_IMAGE = 0x10000000, - PISP_IMAGE_FORMAT_WALLPAPER_ROLL = 0x20000000, - PISP_IMAGE_FORMAT_THREE_CHANNEL = 0x40000000, - - /* Lastly a few specific instantiations of the above. */ - PISP_IMAGE_FORMAT_SINGLE_16 = PISP_IMAGE_FORMAT_BPS_16, - PISP_IMAGE_FORMAT_THREE_16 = - PISP_IMAGE_FORMAT_BPS_16 | PISP_IMAGE_FORMAT_THREE_CHANNEL -} pisp_image_format; - -#define PISP_IMAGE_FORMAT_bps_8(fmt) \ - (((fmt)&PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_8) -#define PISP_IMAGE_FORMAT_bps_10(fmt) \ - (((fmt)&PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_10) -#define PISP_IMAGE_FORMAT_bps_12(fmt) \ - (((fmt)&PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_12) -#define PISP_IMAGE_FORMAT_bps_16(fmt) \ - (((fmt)&PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_16) -#define PISP_IMAGE_FORMAT_bps(fmt) \ - (((fmt)&PISP_IMAGE_FORMAT_BPS_MASK) ? \ - 8 + (2 << (((fmt)&PISP_IMAGE_FORMAT_BPS_MASK) - 1)) : \ - 8) -#define PISP_IMAGE_FORMAT_shift(fmt) \ - (((fmt)&PISP_IMAGE_FORMAT_SHIFT_MASK) / PISP_IMAGE_FORMAT_SHIFT_1) -#define PISP_IMAGE_FORMAT_three_channel(fmt) \ - ((fmt)&PISP_IMAGE_FORMAT_THREE_CHANNEL) -#define PISP_IMAGE_FORMAT_single_channel(fmt) \ - (!((fmt)&PISP_IMAGE_FORMAT_THREE_CHANNEL)) -#define PISP_IMAGE_FORMAT_compressed(fmt) \ - (((fmt)&PISP_IMAGE_FORMAT_COMPRESSION_MASK) != \ - PISP_IMAGE_FORMAT_UNCOMPRESSED) -#define PISP_IMAGE_FORMAT_sampling_444(fmt) \ - (((fmt)&PISP_IMAGE_FORMAT_SAMPLING_MASK) == \ - PISP_IMAGE_FORMAT_SAMPLING_444) -#define PISP_IMAGE_FORMAT_sampling_422(fmt) \ - (((fmt)&PISP_IMAGE_FORMAT_SAMPLING_MASK) == \ - PISP_IMAGE_FORMAT_SAMPLING_422) -#define PISP_IMAGE_FORMAT_sampling_420(fmt) \ - (((fmt)&PISP_IMAGE_FORMAT_SAMPLING_MASK) == \ - PISP_IMAGE_FORMAT_SAMPLING_420) -#define PISP_IMAGE_FORMAT_order_normal(fmt) \ - (!((fmt)&PISP_IMAGE_FORMAT_ORDER_SWAPPED)) -#define PISP_IMAGE_FORMAT_order_swapped(fmt) \ - ((fmt)&PISP_IMAGE_FORMAT_ORDER_SWAPPED) -#define PISP_IMAGE_FORMAT_bpp_32(fmt) ((fmt)&PISP_IMAGE_FORMAT_BPP_32) -#define PISP_IMAGE_FORMAT_x_value(fmt) (((fmt)&PISP_IMAGE_FORMAT_X_VALUE) ? 255 : 0) - -#define PISP_IMAGE_FORMAT_interleaved(fmt) \ - (((fmt)&PISP_IMAGE_FORMAT_PLANARITY_MASK) == \ - PISP_IMAGE_FORMAT_PLANARITY_INTERLEAVED) -#define PISP_IMAGE_FORMAT_semiplanar(fmt) \ - (((fmt)&PISP_IMAGE_FORMAT_PLANARITY_MASK) == \ - PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR) -#define PISP_IMAGE_FORMAT_planar(fmt) \ - (((fmt)&PISP_IMAGE_FORMAT_PLANARITY_MASK) == \ - PISP_IMAGE_FORMAT_PLANARITY_PLANAR) -#define PISP_IMAGE_FORMAT_wallpaper(fmt) \ - ((fmt)&PISP_IMAGE_FORMAT_WALLPAPER_ROLL) -#define PISP_IMAGE_FORMAT_HOG(fmt) \ - ((fmt) & \ - (PISP_IMAGE_FORMAT_HOG_SIGNED | PISP_IMAGE_FORMAT_HOG_UNSIGNED)) - -#define PISP_WALLPAPER_WIDTH 128 // in bytes diff --git a/src/libpisp/common/pisp_utils.cpp b/src/libpisp/common/pisp_utils.cpp index b0cbd73..862167d 100644 --- a/src/libpisp/common/pisp_utils.cpp +++ b/src/libpisp/common/pisp_utils.cpp @@ -4,6 +4,9 @@ * * pisp_utils.cpp - PiSP buffer helper utilities */ +#include +#include + #include "backend/pisp_be_config.h" #include "pisp_common.h" @@ -43,8 +46,9 @@ uint32_t compute_x_offset(uint32_t /* pisp_image_format */ format, int x) else x_offset = x; - if ((format & PISP_IMAGE_FORMAT_THREE_CHANNEL) && PISP_IMAGE_FORMAT_interleaved(format)) { - if (PISP_IMAGE_FORMAT_sampling_422(format)) + if ((format & PISP_IMAGE_FORMAT_THREE_CHANNEL) && PISP_IMAGE_FORMAT_INTERLEAVED(format)) + { + if (PISP_IMAGE_FORMAT_SAMPLING_422(format)) x_offset *= 2; else x_offset *= 3; @@ -55,16 +59,16 @@ uint32_t compute_x_offset(uint32_t /* pisp_image_format */ format, int x) void compute_stride_align(pisp_image_format_config &config, int align) { - if (PISP_IMAGE_FORMAT_wallpaper(config.format)) + if (PISP_IMAGE_FORMAT_WALLPAPER(config.format)) { config.stride2 = config.stride = config.height * PISP_WALLPAPER_WIDTH; - if (PISP_IMAGE_FORMAT_sampling_420(config.format)) + if (PISP_IMAGE_FORMAT_SAMPLING_420(config.format)) config.stride2 /= 2; return; } uint16_t width = config.width; - if (PISP_IMAGE_FORMAT_compressed(config.format)) + if (PISP_IMAGE_FORMAT_COMPRESSED(config.format)) width = (width + 7) & ~7; // compression uses blocks of 8 samples int32_t computed_stride = compute_x_offset(config.format, width); @@ -77,13 +81,13 @@ void compute_stride_align(pisp_image_format_config &config, int align) switch (config.format & PISP_IMAGE_FORMAT_PLANARITY_MASK) { case PISP_IMAGE_FORMAT_PLANARITY_PLANAR: - if (PISP_IMAGE_FORMAT_sampling_422(config.format) || PISP_IMAGE_FORMAT_sampling_420(config.format)) + if (PISP_IMAGE_FORMAT_SAMPLING_422(config.format) || PISP_IMAGE_FORMAT_SAMPLING_420(config.format)) config.stride2 = config.stride >> 1; - else if (PISP_IMAGE_FORMAT_three_channel(config.format)) + else if (PISP_IMAGE_FORMAT_THREE_CHANNEL(config.format)) config.stride2 = config.stride; break; case PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR: - PISP_ASSERT(PISP_IMAGE_FORMAT_sampling_422(config.format) || PISP_IMAGE_FORMAT_sampling_420(config.format)); + PISP_ASSERT(PISP_IMAGE_FORMAT_SAMPLING_422(config.format) || PISP_IMAGE_FORMAT_SAMPLING_420(config.format)); config.stride2 = config.stride; break; } @@ -109,18 +113,18 @@ void compute_optimal_stride(pisp_image_format_config &config) void compute_addr_offset(const pisp_image_format_config &config, int x, int y, uint32_t *addr_offset, uint32_t *addr_offset2) { - if (PISP_IMAGE_FORMAT_wallpaper(config.format)) + if (PISP_IMAGE_FORMAT_WALLPAPER(config.format)) { int pixels_in_roll = - PISP_IMAGE_FORMAT_bps_8(config.format) + PISP_IMAGE_FORMAT_BPS_8(config.format) ? PISP_WALLPAPER_WIDTH - : (PISP_IMAGE_FORMAT_bps_16(config.format) ? PISP_WALLPAPER_WIDTH / 2 : PISP_WALLPAPER_WIDTH / 4 * 3); + : (PISP_IMAGE_FORMAT_BPS_16(config.format) ? PISP_WALLPAPER_WIDTH / 2 : PISP_WALLPAPER_WIDTH / 4 * 3); int pixel_offset_in_roll = x % pixels_in_roll; int pixel_offset_in_bytes; - if (PISP_IMAGE_FORMAT_bps_8(config.format)) + if (PISP_IMAGE_FORMAT_BPS_8(config.format)) pixel_offset_in_bytes = pixel_offset_in_roll; - else if (PISP_IMAGE_FORMAT_bps_16(config.format)) + else if (PISP_IMAGE_FORMAT_BPS_16(config.format)) pixel_offset_in_bytes = pixel_offset_in_roll * 2; else { @@ -131,7 +135,7 @@ void compute_addr_offset(const pisp_image_format_config &config, int x, int y, u int num_rolls = x / pixels_in_roll; *addr_offset = num_rolls * config.stride + y * PISP_WALLPAPER_WIDTH + pixel_offset_in_bytes; - if (PISP_IMAGE_FORMAT_sampling_420(config.format)) + if (PISP_IMAGE_FORMAT_SAMPLING_420(config.format)) *addr_offset2 = num_rolls * config.stride2 + y / 2 * PISP_WALLPAPER_WIDTH + pixel_offset_in_bytes; else *addr_offset2 = *addr_offset; @@ -141,12 +145,12 @@ void compute_addr_offset(const pisp_image_format_config &config, int x, int y, u uint32_t x_byte_offset = compute_x_offset(config.format, x); *addr_offset = y * config.stride + x_byte_offset; - if (addr_offset2 && !PISP_IMAGE_FORMAT_interleaved(config.format)) + if (addr_offset2 && !PISP_IMAGE_FORMAT_INTERLEAVED(config.format)) { - if (PISP_IMAGE_FORMAT_sampling_420(config.format)) + if (PISP_IMAGE_FORMAT_SAMPLING_420(config.format)) y /= 2; - if (PISP_IMAGE_FORMAT_planar(config.format) && !PISP_IMAGE_FORMAT_sampling_444(config.format)) + if (PISP_IMAGE_FORMAT_PLANAR(config.format) && !PISP_IMAGE_FORMAT_SAMPLING_444(config.format)) x_byte_offset /= 2; *addr_offset2 = y * config.stride2 + x_byte_offset; @@ -157,7 +161,7 @@ int num_planes(pisp_image_format format) { int planes = 1; - if (PISP_IMAGE_FORMAT_three_channel(format)) + if (PISP_IMAGE_FORMAT_THREE_CHANNEL(format)) { switch (format & PISP_IMAGE_FORMAT_PLANARITY_MASK) { @@ -178,21 +182,21 @@ int num_planes(pisp_image_format format) std::size_t get_plane_size(const pisp_image_format_config &config, int plane) { - uint64_t stride = abs(plane ? config.stride2 : config.stride); // in case vflipped? + uint64_t stride = std::abs(plane ? config.stride2 : config.stride); // in case vflipped? uint64_t plane_size = 0; - if (PISP_IMAGE_FORMAT_wallpaper(config.format)) + if (PISP_IMAGE_FORMAT_WALLPAPER(config.format)) { int pixels_in_roll = - PISP_IMAGE_FORMAT_bps_8(config.format) + PISP_IMAGE_FORMAT_BPS_8(config.format) ? PISP_WALLPAPER_WIDTH - : (PISP_IMAGE_FORMAT_bps_16(config.format) ? PISP_WALLPAPER_WIDTH / 2 : PISP_WALLPAPER_WIDTH / 4 * 3); + : (PISP_IMAGE_FORMAT_BPS_16(config.format) ? PISP_WALLPAPER_WIDTH / 2 : PISP_WALLPAPER_WIDTH / 4 * 3); std::size_t num_rolls = (config.width + pixels_in_roll - 1) / pixels_in_roll; plane_size = num_rolls * stride; } else { - std::size_t height = plane && PISP_IMAGE_FORMAT_sampling_420(config.format) ? config.height >> 1 + std::size_t height = plane && PISP_IMAGE_FORMAT_SAMPLING_420(config.format) ? config.height >> 1 : config.height; plane_size = height * stride; } diff --git a/src/libpisp/frontend/frontend.cpp b/src/libpisp/frontend/frontend.cpp index 54b663a..9f7ed88 100644 --- a/src/libpisp/frontend/frontend.cpp +++ b/src/libpisp/frontend/frontend.cpp @@ -97,13 +97,13 @@ void finalise_compression(pisp_fe_config const &fe_config, int i) uint32_t fmt = fe_config.ch[i].output.format.format; uint32_t enables = fe_config.global.enables; - if (PISP_IMAGE_FORMAT_compressed(fmt) && !(enables & block_enable(PISP_FE_ENABLE_COMPRESS0, i))) + if (PISP_IMAGE_FORMAT_COMPRESSED(fmt) && !(enables & block_enable(PISP_FE_ENABLE_COMPRESS0, i))) PISP_LOG(fatal, "FrontEnd::finalise: output compressed but compression not enabled"); - if (!PISP_IMAGE_FORMAT_compressed(fmt) && (enables & block_enable(PISP_FE_ENABLE_COMPRESS0, i))) + if (!PISP_IMAGE_FORMAT_COMPRESSED(fmt) && (enables & block_enable(PISP_FE_ENABLE_COMPRESS0, i))) PISP_LOG(fatal, "FrontEnd::finalise: output uncompressed but compression enabled"); - if ((enables & block_enable(PISP_FE_ENABLE_COMPRESS0, i)) && !PISP_IMAGE_FORMAT_bps_8(fmt)) + if ((enables & block_enable(PISP_FE_ENABLE_COMPRESS0, i)) && !PISP_IMAGE_FORMAT_BPS_8(fmt)) PISP_LOG(fatal, "FrontEnd::finalise: compressed output is not 8 bit"); } @@ -399,7 +399,7 @@ void FrontEnd::Prepare(pisp_fe_config *config) { pisp_image_format_config &image_config = fe_config_.ch[i].output.format; - getOutputSize(i, image_config.width, image_config.height); + fixOutputSize(i); if (!image_config.stride) compute_stride_align(image_config, align_); } @@ -414,27 +414,29 @@ void FrontEnd::Prepare(pisp_fe_config *config) fe_config_.dirty_flags = fe_config_.dirty_flags_extra = 0; } -void FrontEnd::getOutputSize(unsigned int output_num, uint16_t &width, uint16_t &height) const +void FrontEnd::fixOutputSize(unsigned int output_num) { PISP_ASSERT(output_num < variant_.FrontEndNumBranches(0)); - width = height = 0; + pisp_image_format_config &image_config = fe_config_.ch[output_num].output.format; + + image_config.width = image_config.height = 0; if (fe_config_.global.enables & block_enable(PISP_FE_ENABLE_OUTPUT0, output_num)) { - width = fe_config_.input.format.width; - height = fe_config_.input.format.height; + image_config.width = fe_config_.input.format.width; + image_config.height = fe_config_.input.format.height; if (fe_config_.global.enables & block_enable(PISP_FE_ENABLE_CROP0, output_num)) { - width = fe_config_.ch[output_num].crop.width; - height = fe_config_.ch[output_num].crop.height; + image_config.width = fe_config_.ch[output_num].crop.width; + image_config.width = fe_config_.ch[output_num].crop.height; } if (fe_config_.global.enables & block_enable(PISP_FE_ENABLE_DOWNSCALE0, output_num)) { - width = fe_config_.ch[output_num].downscale.output_width; - height = fe_config_.ch[output_num].downscale.output_height; + image_config.width = fe_config_.ch[output_num].downscale.output_width; + image_config.height = fe_config_.ch[output_num].downscale.output_height; } } } diff --git a/src/libpisp/frontend/frontend.hpp b/src/libpisp/frontend/frontend.hpp index cc1e64c..dc8f042 100644 --- a/src/libpisp/frontend/frontend.hpp +++ b/src/libpisp/frontend/frontend.hpp @@ -10,7 +10,7 @@ #include #include -#include "common/pisp_types.h" +#include "common/pisp_common.h" #include "common/shm_mutex.hpp" #include "variants/variant.hpp" @@ -72,7 +72,7 @@ class FrontEnd final } private: - void getOutputSize(unsigned int output_num, uint16_t &width, uint16_t &height) const; + void fixOutputSize(unsigned int output_num); const PiSPVariant variant_; pisp_fe_config fe_config_; diff --git a/src/meson.build b/src/meson.build index b0d9f80..54d10cf 100644 --- a/src/meson.build +++ b/src/meson.build @@ -30,6 +30,9 @@ endif add_project_arguments(logging_args, language : 'cpp') +# Needed to avoid (erroneous) warnings on the use of addresses of fields in __attribute__((packed)) structs. +add_project_arguments('-Wno-address-of-packed-member', language : 'cpp') + meson.add_dist_script(meson.project_source_root() / 'utils' / 'gen-dist.sh') # Generate a version string: