"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/compiler/nir/nir_convert_ycbcr.c" (16 Sep 2020, 5699 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "nir_convert_ycbcr.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright © 2017 Intel Corporation
    3  *
    4  * Permission is hereby granted, free of charge, to any person obtaining a
    5  * copy of this software and associated documentation files (the "Software"),
    6  * to deal in the Software without restriction, including without limitation
    7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    8  * and/or sell copies of the Software, and to permit persons to whom the
    9  * Software is furnished to do so, subject to the following conditions:
   10  *
   11  * The above copyright notice and this permission notice (including the next
   12  * paragraph) shall be included in all copies or substantial portions of the
   13  * Software.
   14  *
   15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   21  * IN THE SOFTWARE.
   22  */
   23 
   24 #include "nir_vulkan.h"
   25 #include <math.h>
   26 
   27 static nir_ssa_def *
   28 y_range(nir_builder *b,
   29         nir_ssa_def *y_channel,
   30         int bpc,
   31         VkSamplerYcbcrRange range)
   32 {
   33    switch (range) {
   34    case VK_SAMPLER_YCBCR_RANGE_ITU_FULL:
   35       return y_channel;
   36    case VK_SAMPLER_YCBCR_RANGE_ITU_NARROW:
   37       return nir_fmul(b,
   38                       nir_fadd(b,
   39                                nir_fmul(b, y_channel,
   40                                         nir_imm_float(b, pow(2, bpc) - 1)),
   41                                nir_imm_float(b, -16.0f * pow(2, bpc - 8))),
   42                       nir_frcp(b, nir_imm_float(b, 219.0f * pow(2, bpc - 8))));
   43    default:
   44       unreachable("missing Ycbcr range");
   45       return NULL;
   46    }
   47 }
   48 
   49 static nir_ssa_def *
   50 chroma_range(nir_builder *b,
   51              nir_ssa_def *chroma_channel,
   52              int bpc,
   53              VkSamplerYcbcrRange range)
   54 {
   55    switch (range) {
   56    case VK_SAMPLER_YCBCR_RANGE_ITU_FULL:
   57       return nir_fadd(b, chroma_channel,
   58                       nir_imm_float(b, -pow(2, bpc - 1) / (pow(2, bpc) - 1.0f)));
   59    case VK_SAMPLER_YCBCR_RANGE_ITU_NARROW:
   60       return nir_fmul(b,
   61                       nir_fadd(b,
   62                                nir_fmul(b, chroma_channel,
   63                                         nir_imm_float(b, pow(2, bpc) - 1)),
   64                                nir_imm_float(b, -128.0f * pow(2, bpc - 8))),
   65                       nir_frcp(b, nir_imm_float(b, 224.0f * pow(2, bpc - 8))));
   66    default:
   67       unreachable("missing Ycbcr range");
   68       return NULL;
   69    }
   70 }
   71 
   72 typedef struct nir_const_value_3_4 {
   73    nir_const_value v[3][4];
   74 } nir_const_value_3_4;
   75 
   76 static const nir_const_value_3_4 *
   77 ycbcr_model_to_rgb_matrix(VkSamplerYcbcrModelConversion model)
   78 {
   79    switch (model) {
   80    case VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601: {
   81       static const nir_const_value_3_4 bt601 = { {
   82          { { .f32 =  1.402f             }, { .f32 = 1.0f }, { .f32 =  0.0f               }, { .f32 = 0.0f } },
   83          { { .f32 = -0.714136286201022f }, { .f32 = 1.0f }, { .f32 = -0.344136286201022f }, { .f32 = 0.0f } },
   84          { { .f32 =  0.0f               }, { .f32 = 1.0f }, { .f32 =  1.772f             }, { .f32 = 0.0f } },
   85       } };
   86 
   87       return &bt601;
   88    }
   89    case VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709: {
   90       static const nir_const_value_3_4 bt709 = { {
   91          { { .f32 =  1.5748031496063f   }, { .f32 = 1.0f }, { .f32 =  0.0f               }, { .f32 = 0.0f } },
   92          { { .f32 = -0.468125209181067f }, { .f32 = 1.0f }, { .f32 = -0.187327487470334f }, { .f32 = 0.0f } },
   93          { { .f32 =  0.0f               }, { .f32 = 1.0f }, { .f32 =  1.85563184264242f  }, { .f32 = 0.0f } },
   94       } };
   95 
   96       return &bt709;
   97    }
   98    case VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020: {
   99       static const nir_const_value_3_4 bt2020 = { {
  100          { { .f32 =  1.4746f            }, { .f32 = 1.0f }, { .f32 =  0.0f               }, { .f32 = 0.0f } },
  101          { { .f32 = -0.571353126843658f }, { .f32 = 1.0f }, { .f32 = -0.164553126843658f }, { .f32 = 0.0f } },
  102          { { .f32 =  0.0f               }, { .f32 = 1.0f }, { .f32 =  1.8814f            }, { .f32 = 0.0f } },
  103       } };
  104 
  105       return &bt2020;
  106    }
  107    default:
  108       unreachable("missing Ycbcr model");
  109       return NULL;
  110    }
  111 }
  112 
  113 nir_ssa_def *
  114 nir_convert_ycbcr_to_rgb(nir_builder *b,
  115                          VkSamplerYcbcrModelConversion model,
  116                          VkSamplerYcbcrRange range,
  117                          nir_ssa_def *raw_channels,
  118                          uint32_t *bpcs)
  119 {
  120    nir_ssa_def *expanded_channels =
  121       nir_vec4(b,
  122                chroma_range(b, nir_channel(b, raw_channels, 0), bpcs[0], range),
  123                y_range(b, nir_channel(b, raw_channels, 1), bpcs[1], range),
  124                chroma_range(b, nir_channel(b, raw_channels, 2), bpcs[2], range),
  125                nir_channel(b, raw_channels, 3));
  126 
  127    if (model == VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY)
  128       return expanded_channels;
  129 
  130    const nir_const_value_3_4 *conversion_matrix =
  131       ycbcr_model_to_rgb_matrix(model);
  132 
  133    nir_ssa_def *converted_channels[] = {
  134       nir_fdot4(b, expanded_channels, nir_build_imm(b, 4, 32, conversion_matrix->v[0])),
  135       nir_fdot4(b, expanded_channels, nir_build_imm(b, 4, 32, conversion_matrix->v[1])),
  136       nir_fdot4(b, expanded_channels, nir_build_imm(b, 4, 32, conversion_matrix->v[2]))
  137    };
  138 
  139    return nir_vec4(b,
  140                    converted_channels[0], converted_channels[1],
  141                    converted_channels[2], nir_channel(b, raw_channels, 3));
  142 }