// GENERATED FILE - DO NOT EDIT. // Generated by gen_vk_internal_shaders.py. // // Copyright 2018 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // shaders/gen/EtcToBc.comp.00000001.inc: // Pre-generated shader for the ANGLE Vulkan back-end. #pragma once constexpr uint8_t kEtcToBc_comp_00000001[] = …; // Generated from: // // #version 450 core // // #extension GL_GOOGLE_include_directive : require // // #extension GL_KHR_shader_subgroup_clustered : enable // #extension GL_KHR_shader_subgroup_shuffle : enable // // layout(local_size_x = 64, local_size_y = 1, local_size_z = 1)in; // layout(binding = 0)uniform highp usamplerBuffer uInputBuffer; // layout(binding = 1, rgba32ui)writeonly uniform uimage2D uOutput; // // layout(push_constant)uniform imagInfo { // // uint offsetX; // uint offsetY; // int texelOffset; // uint width; // uint height; // uint alphaBits; // uint isSigned; // uint isEacRg; // }; // // #line 1 "shaders/src/third_party/etc_decoder/etc_decoder.h" // // const ivec2 etc1_color_modifier_table[8]= ivec2[]( // ivec2(2, 8), // ivec2(5, 17), // ivec2(9, 29), // ivec2(13, 42), // ivec2(18, 60), // ivec2(24, 80), // ivec2(33, 106), // ivec2(47, 183)); // // const ivec4 etc2_alpha_modifier_table[16]= ivec4[]( // ivec4(2, 5, 8, 14), // ivec4(2, 6, 9, 12), // ivec4(1, 4, 7, 12), // ivec4(1, 3, 5, 12), // ivec4(2, 5, 7, 11), // ivec4(2, 6, 8, 10), // ivec4(3, 6, 7, 10), // ivec4(2, 4, 7, 10), // ivec4(1, 5, 7, 9), // ivec4(1, 4, 7, 9), // ivec4(1, 3, 7, 9), // ivec4(1, 4, 6, 9), // ivec4(2, 3, 6, 9), // ivec4(0, 1, 2, 9), // ivec4(3, 5, 7, 8), // ivec4(2, 4, 6, 8) // ); // // const int etc2_distance_table[8]= int[](3, 6, 11, 16, 23, 32, 41, 64); // // int decode_etc2_alpha(uvec2 payload, int linear_pixel) // { // int bit_offset = 45 - 3 * linear_pixel; // // int base = isSigned != 0 ? bitfieldExtract(int(payload . y), 24, 8): int(bitfieldExtract(payload . y, 24, 8)); // // int multiplier = int(bitfieldExtract(payload . y, 20, 4)); // int table = int(bitfieldExtract(payload . y, 16, 4)); // // int lsb_index = int(bitfieldExtract(payload[bit_offset >> 5], bit_offset & 31, 2)); // bit_offset += 2; // int msb = int((payload[bit_offset >> 5]>>(bit_offset & 31))& 1u); // int mod = etc2_alpha_modifier_table[table][lsb_index]^(msb - 1); // // int a = base * 8 + 4; // a += multiplier != 0 ? mod * multiplier * 8 : mod; // int minValue = isSigned != 0 ? - 1023 : 0; // int maxValue = isSigned != 0 ? 1023 : 2047; // a = clamp(a, minValue, maxValue); // float scale = isSigned != 0 ? 127.0f : 255.0f; // return int(a / float(maxValue)* scale + 0.5f); // // } // // ivec4 DecodeRGB(ivec2 pixel_coord, uvec2 color_payload, int linear_pixel, inout bool punchthrough){ // int alpha_result = 0xff; // ivec3 rgb_result; // ivec3 base_rgb; // uint flip = color_payload . y & 1u; // uint subblock = uint((pixel_coord[flip]& 2)>> 1); // bool etc1_compat = false; // // if(alphaBits != 1 &&(color_payload . y & 2u)== 0u) // { // // etc1_compat = true; // base_rgb = ivec3(color_payload . yyy >>(uvec3(28, 20, 12)- 4u * subblock)); // base_rgb &= 0xf; // base_rgb *= 0x11; // } // else // { // int r = int(bitfieldExtract(color_payload . y, 27, 5)); // int rd = bitfieldExtract(int(color_payload . y), 24, 3); // int g = int(bitfieldExtract(color_payload . y, 19, 5)); // int gd = bitfieldExtract(int(color_payload . y), 16, 3); // int b = int(bitfieldExtract(color_payload . y, 11, 5)); // int bd = bitfieldExtract(int(color_payload . y), 8, 3); // // int r1 = r + rd; // int g1 = g + gd; // int b1 = b + bd; // // if(uint(r1)> 31u) // { // int r1 = int(bitfieldExtract(color_payload . y, 56 - 32, 2))| // (int(bitfieldExtract(color_payload . y, 59 - 32, 2))<< 2); // int g1 = int(bitfieldExtract(color_payload . y, 52 - 32, 4)); // int b1 = int(bitfieldExtract(color_payload . y, 48 - 32, 4)); // int r2 = int(bitfieldExtract(color_payload . y, 44 - 32, 4)); // int g2 = int(bitfieldExtract(color_payload . y, 40 - 32, 4)); // int b2 = int(bitfieldExtract(color_payload . y, 36 - 32, 4)); // uint da =(bitfieldExtract(color_payload . y, 34 - 32, 2)<< 1)| // (color_payload . y & 1u); // int dist = etc2_distance_table[da]; // // int msb = int((color_payload . x >>(15 + linear_pixel))& 2u); // int lsb = int((color_payload . x >> linear_pixel)& 1u); // int index = msb | lsb; // // if(punchthrough) // punchthrough = index == 2; // // if(index == 0) // { // rgb_result = ivec3(r1, g1, b1); // rgb_result *= 0x11; // } // else // { // int mod = 2 - index; // ivec3 rgb = ivec3(r2, g2, b2)* 0x11 + mod * dist; // rgb_result = ivec3(clamp(rgb, ivec3(0), ivec3(255))); // } // } // else if(uint(g1)> 31u) // { // int r1 = int(bitfieldExtract(color_payload . y, 59 - 32, 4)); // int g1 =(int(bitfieldExtract(color_payload . y, 56 - 32, 3))<< 1)| // int((color_payload . y >> 20u)& 1u); // int b1 = int(bitfieldExtract(color_payload . y, 47 - 32, 3))| // int((color_payload . y >> 16u)& 8u); // int r2 = int(bitfieldExtract(color_payload . y, 43 - 32, 4)); // int g2 = int(bitfieldExtract(color_payload . y, 39 - 32, 4)); // int b2 = int(bitfieldExtract(color_payload . y, 35 - 32, 4)); // uint da = color_payload . y & 4u; // uint db = color_payload . y & 1u; // uint d = da + 2u * db; // d += uint((r1 * 0x10000 + g1 * 0x100 + b1)>=(r2 * 0x10000 + g2 * 0x100 + b2)); // int dist = etc2_distance_table[d]; // int msb = int((color_payload . x >>(15 + linear_pixel))& 2u); // int lsb = int((color_payload . x >> linear_pixel)& 1u); // // if(punchthrough) // punchthrough =(msb + lsb)== 2; // // ivec3 base = msb != 0 ? ivec3(r2, g2, b2): ivec3(r1, g1, b1); // base *= 0x11; // int mod = 1 - 2 * lsb; // base += mod * dist; // rgb_result = ivec3(clamp(base, ivec3(0), ivec3(0xff))); // } // else if(uint(b1)> 31u) // { // // int r = int(bitfieldExtract(color_payload . y, 57 - 32, 6)); // int g = int(bitfieldExtract(color_payload . y, 49 - 32, 6))| // (int(color_payload . y >> 18)& 0x40); // int b = int(bitfieldExtract(color_payload . y, 39 - 32, 3))| // (int(bitfieldExtract(color_payload . y, 43 - 32, 2))<< 3)| // (int(color_payload . y >> 11)& 0x20); // int rh = int(color_payload . y & 1u)| // (int(bitfieldExtract(color_payload . y, 2, 5))<< 1); // int rv = int(bitfieldExtract(color_payload . x, 13, 6)); // int gh = int(bitfieldExtract(color_payload . x, 25, 7)); // int gv = int(bitfieldExtract(color_payload . x, 6, 7)); // int bh = int(bitfieldExtract(color_payload . x, 19, 6)); // int bv = int(bitfieldExtract(color_payload . x, 0, 6)); // // r =(r << 2)|(r >> 4); // rh =(rh << 2)|(rh >> 4); // rv =(rv << 2)|(rv >> 4); // g =(g << 1)|(g >> 6); // gh =(gh << 1)|(gh >> 6); // gv =(gv << 1)|(gv >> 6); // b =(b << 2)|(b >> 4); // bh =(bh << 2)|(bh >> 4); // bv =(bv << 2)|(bv >> 4); // // ivec3 rgb = ivec3(r, g, b); // ivec3 dx = ivec3(rh, gh, bh)- rgb; // ivec3 dy = ivec3(rv, gv, bv)- rgb; // dx *= int(pixel_coord . x); // dy *= int(pixel_coord . y); // rgb = rgb +((dx + dy + 2)>> 2); // rgb = clamp(rgb, ivec3(0), ivec3(255)); // rgb_result = ivec3(rgb); // // punchthrough = false; // // } // else // { // // etc1_compat = true; // base_rgb = ivec3(r, g, b)+ int(subblock)* ivec3(rd, gd, bd); // base_rgb =(base_rgb << 3)|(base_rgb >> 2); // } // } // // if(etc1_compat) // { // uint etc1_table_index = bitfieldExtract(color_payload . y, 5 - 3 * int(subblock != 0u), 3); // int msb = int((color_payload . x >>(15 + linear_pixel))& 2u); // int lsb = int((color_payload . x >> linear_pixel)& 1u); // int sgn = 1 - msb; // // if(punchthrough) // { // sgn *= lsb; // punchthrough =(msb + lsb)== 2; // } // // int offset = etc1_color_modifier_table[etc1_table_index][lsb]* sgn; // base_rgb = clamp(base_rgb + offset, ivec3(0), ivec3(255)); // rgb_result = ivec3(base_rgb); // } // // if(alphaBits == 1 && punchthrough) // { // rgb_result = ivec3(0); // alpha_result = 0; // } // // return ivec4(rgb_result . r, rgb_result . g, rgb_result . b, alpha_result); // } // #line 77 "shaders/src/EtcToBc.comp" // // ivec2 build_coord() // { // uvec2 base =(gl_WorkGroupID . xy)* 8; // uint blockid = gl_LocalInvocationID . x >> 4u; // uint blockxy = gl_LocalInvocationID . x & 0xfu; // base . x += 4 *(blockid & 0x1); // base . y += 2 *(blockid & 0x2); // base += uvec2(blockxy & 0x3, blockxy >> 0x2); // return ivec2(base); // } // // uint flip_endian(uint v) // { // uvec4 words = uvec4(v)>> uvec4(0, 8, 16, 24); // words &= 0xffu; // return(words . x << 24u)|(words . y << 16u)|(words . z << 8u)|(words . w << 0u); // } // // uvec2 flip_endian(uvec2 v) // { // return uvec2(flip_endian(v . y), flip_endian(v . x)); // } // // uint GetIndicesRGB(vec3 color, vec3 minColor, vec3 maxColor, bool transparent) // { // vec3 dir = maxColor - minColor; // float distMin = dot(minColor, dir); // float distMax = dot(maxColor, dir); // float dist = dot(color, dir); // int ind = int(round(clamp((dist - distMin)/(distMax - distMin), 0.0, 1.0)*(transparent ? 2.0 : 3.0))); // // return bitfieldExtract(transparent ? 0x18u : 0x2du, ind * 2, 2); // } // // void ComputeMaxMinColor(uvec3 rgbColor, inout uvec3 minColor, inout uvec3 maxColor){ // ivec3 dx; // if(alphaBits == 1){ // int count = subgroupClusteredAdd(1, 16); // ivec3 avg = ivec3((subgroupClusteredAdd(rgbColor, 16)* 2 + count)/(2 * count)); // dx = ivec3(rgbColor)- avg; // } // else { // dx = ivec3(rgbColor)- ivec3(subgroupClusteredAdd(rgbColor, 16)+ 8 >> 4); // } // vec3 cov0 = vec3(subgroupClusteredAdd(dx . r * dx, 16)); // vec3 cov1 = vec3(subgroupClusteredAdd(dx . ggb * dx . gbb, 16)); // vec3 vg = vec3(subgroupClusteredMax(rgbColor, 16)- subgroupClusteredMin(rgbColor, 16)); // // mat3 covMat = mat3(cov0, // vec3(cov0 . y, cov1 . xy), // vec3(cov0 . z, cov1 . yz)); // // float eigenvalue = 0.0f; // for(int i = 0;i < 4;i ++){ // vg = covMat * vg; // eigenvalue = sqrt(dot(vg, vg)); // if(eigenvalue > 0.0f){ // float invNorm = 1.0f / eigenvalue; // vg *= invNorm; // } // } // const float kDefaultLuminanceThreshold = 4.0f * 255; // const float kQuantizeRange = 0.512f; // // if(eigenvalue < kDefaultLuminanceThreshold){ // vg = vec3(0.299f, 0.587f, 0.114f); // } // else { // float magn = max(max(abs(vg . r), abs(vg . g)), abs(vg . b)); // vg *= kQuantizeRange / magn; // } // float dist = dot(vec3(rgbColor), vg); // float min_dist = subgroupClusteredMin(dist, 16); // float max_dist = subgroupClusteredMax(dist, 16); // uvec2 indices = uvec2(dist == min_dist ? gl_SubgroupInvocationID : 0, // dist == max_dist ? gl_SubgroupInvocationID : 0); // uvec2 minMaxIndex = subgroupClusteredMax(indices, 16); // minColor = subgroupShuffle(rgbColor, minMaxIndex . x); // maxColor = subgroupShuffle(rgbColor, minMaxIndex . y); // } // // uint GetIndicesAlpha(int alpha, int minAlpha, int maxAlpha) // { // float dist = float(maxAlpha - minAlpha); // int ind = int(round(clamp((alpha - minAlpha)/ dist * 7.0f, 0.0, 7.0))); // // return bitfieldExtract(0x2345671u, ind * 4, 4); // } // // void ComputeMaxMin(int alpha, inout int minAlpha, inout int maxAlpha){ // minAlpha = subgroupClusteredMin(alpha, 16); // maxAlpha = subgroupClusteredMax(alpha, 16); // } // uvec2 EncodeBC4(int value, uint pid){ // int minValue, maxValue; // ComputeMaxMin(value, minValue, maxValue); // uint indices = 0; // if(minValue != maxValue) // indices = GetIndicesAlpha(value, minValue, maxValue); // // uvec2 mask = uvec2(pid <= 5 ? indices <<(16 + 3 * pid): 0x0, // pid >= 5 ?(indices << 29)>>(45 - 3 * pid): 0x0); // // mask = subgroupClusteredOr(mask, 16); // return uvec2((maxValue & 0xff)|((minValue & 0xff)<< 8)| mask . x, mask . y); // } // // uvec3 scaleColorToRGB565(uvec3 color){ // return uvec3(round(vec3(color)* vec3(31.0 / 255.0, 63.0 / 255.0, 31.0 / 255.0))); // } // // uvec3 convertRGB565ToRGB888(uvec3 color){ // return uvec3(color . x << 3 |(color . x >> 2), // color . y << 2 |(color . y >> 4), // color . z << 3 |(color . z >> 2)); // } // // uint packRGB565(uvec3 color565){ // return color565 . r << 11 |(color565 . g << 5)| color565 . b; // } // // void modifyMinMax(inout uvec3 minColor, inout uvec3 maxColor){ // uvec3 minColor565 = scaleColorToRGB565(minColor); // uvec3 maxColor565 = scaleColorToRGB565(maxColor); // if(all(equal(minColor565, maxColor565))){ // uvec3 simulatedColor = convertRGB565ToRGB888(minColor565); // ivec3 signMax = sign(ivec3(maxColor)- ivec3(simulatedColor)); // ivec3 signMin = sign(ivec3(minColor)- ivec3(simulatedColor)); // bvec3 needCorrect = greaterThan(signMax * signMin, ivec3(0, 0, 0)); // bvec3 positive = greaterThan(signMin, ivec3(0, 0, 0)); // maxColor565 . r += needCorrect . r && positive . r ? 1 : 0; // maxColor565 . g += needCorrect . g && positive . g ? 1 : 0; // maxColor565 . b += needCorrect . b && positive . b ? 1 : 0; // minColor565 . r -= needCorrect . r && ! positive . r ? 1 : 0; // minColor565 . g -= needCorrect . g && ! positive . g ? 1 : 0; // minColor565 . b -= needCorrect . b && ! positive . b ? 1 : 0; // } // minColor = minColor565; // maxColor = maxColor565; // } // // void swap(inout uint a, inout uint b){ // uint t = a; // a = b; // b = t; // } // // void main() // { // ivec2 coord = build_coord(); // if(any(greaterThanEqual(coord, ivec2(width, height)))) // return; // // ivec2 tile_coord = coord >> 2; // ivec2 pixel_coord = coord & 3; // int linear_pixel = 4 * pixel_coord . x + pixel_coord . y; // int pid = 4 * pixel_coord . y + pixel_coord . x; // uvec4 payload = texelFetch(uInputBuffer, tile_coord . y * int((width + 3)>> 2)+ tile_coord . x + texelOffset); // // ivec4 result; // // result . r = decode_etc2_alpha(flip_endian(payload . xy), linear_pixel); // if(isEacRg != 0){ // result . g = decode_etc2_alpha(flip_endian(payload . zw), linear_pixel); // } // // uvec4 finalResult; // // finalResult . rg = EncodeBC4(result . r, pid); // if(isEacRg != 0) // finalResult . ba = EncodeBC4(result . g, pid); // // if(pid == 0){ // tile_coord += ivec2(offsetX / 4, offsetY / 4); // imageStore(uOutput, tile_coord, finalResult); // } // // }