CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/GPU/Common/ReinterpretFramebuffer.cpp
Views: 1401
#include <cstdarg>12#include "Common/GPU/Shader.h"3#include "Common/GPU/ShaderWriter.h"4#include "Common/Log.h"5#include "Common/GPU/thin3d.h"6#include "Core/System.h"7#include "GPU/Common/ReinterpretFramebuffer.h"8#include "GPU/Common/FramebufferManagerCommon.h"9#include "GPU/Common/TextureCacheCommon.h"1011static const VaryingDef varyings[1] = {12{ "vec2", "v_texcoord", Draw::SEM_TEXCOORD0, 0, "highp" },13};1415static const SamplerDef samplers[1] = {16{ 0, "tex", SamplerFlags::ARRAY_ON_VULKAN }17};1819// Requires full size integer math. It would be possible to make a floating point-only version with lots of20// modulo and stuff, might do it one day.21Draw2DPipelineInfo GenerateReinterpretFragmentShader(ShaderWriter &writer, GEBufferFormat from, GEBufferFormat to) {22writer.HighPrecisionFloat();23writer.DeclareSamplers(samplers);2425if (writer.Lang().bitwiseOps) {26switch (from) {27case GE_FORMAT_4444:28writer.C("uint packColor(vec4 val) {\n");29writer.C(" return uint(val.r * 15.99) | (uint(val.g * 15.99) << 0x4u) | (uint(val.b * 15.99) << 0x8u) | (uint(val.a * 15.99) << 0xCu);\n");30writer.C("}\n");31break;32case GE_FORMAT_5551:33writer.C("uint packColor(vec4 val) {\n");34writer.C(" uint color = uint(val.r * 31.99) | (uint(val.g * 31.99) << 0x5u) | (uint(val.b * 31.99) << 0xAu);\n");35writer.C(" if (val.a >= 0.5) color |= 0x8000U;\n");36writer.C(" return color;\n");37writer.C("}\n");38break;39case GE_FORMAT_565:40writer.C("uint packColor(vec4 val) {\n");41writer.C(" return uint(val.r * 31.99) | (uint(val.g * 63.99) << 0x5u) | (uint(val.b * 31.99) << 0xBu);\n");42writer.C("}\n");43break;44case GE_FORMAT_8888:45writer.C("uint packColor(vec2 val) {\n");46writer.C(" return uint(val.r * 255.99) | (uint(val.g * 255.99) << 8u);\n");47writer.C("}\n");48break;49default:50_assert_(false);51break;52}53} else {54// Floating point can comfortably represent integers up to 16 million, we only need 65536 since these textures are 16-bit.55switch (from) {56case GE_FORMAT_4444:57writer.C("float packColor(vec4 val) {\n");58writer.C(" return (floor(val.r * 15.99) + floor(val.g * 15.99) * 16.0) + (floor(val.b * 15.99) * 256.0 + floor(val.a * 15.99) * 4096.0);\n");59writer.C("}\n");60break;61case GE_FORMAT_5551:62writer.C("float packColor(vec4 val) {\n");63writer.C(" float color = floor(val.r * 31.99) + floor(val.g * 31.99) * 32.0 + floor(val.b * 31.99) * 1024.0;\n");64writer.C(" if (val.a >= 0.5) color += 32768.0;\n");65writer.C(" return color;\n");66writer.C("}\n");67break;68case GE_FORMAT_565:69writer.C("float packColor(vec4 val) {\n");70writer.C(" return floor(val.r * 31.99) + floor(val.g * 63.99) * 32.0 + floor(val.b * 31.99) * 2048.0;\n");71writer.C("}\n");72break;73case GE_FORMAT_8888:74writer.C("float packColor(vec2 val) {\n");75writer.C(" return floor(val.r * 255.99) + floor(val.g * 255.99) * 256.0;\n");76writer.C("}\n");77break;78default:79_assert_(false);80break;81}82}8384if (writer.Lang().bitwiseOps) {85switch (to) {86case GE_FORMAT_4444:87writer.C("vec4 unpackColor(uint color) {\n");88writer.C(" vec4 outColor = vec4(float(color & 0xFu), float((color >> 0x4u) & 0xFu), float((color >> 0x8u) & 0xFu), float((color >> 0xCu) & 0xFu));\n");89writer.C(" outColor *= 1.0 / 15.0;\n");90writer.C(" return outColor;\n");91writer.C("}\n");92break;93case GE_FORMAT_5551:94writer.C("vec4 unpackColor(uint color) {\n");95writer.C(" vec4 outColor = vec4(float(color & 0x1Fu), float((color >> 0x5u) & 0x1Fu), float((color >> 0xAu) & 0x1Fu), 0.0);\n");96writer.C(" outColor.rgb *= 1.0 / 31.0;\n");97writer.C(" outColor.a = float(color >> 0xFu);\n");98writer.C(" return outColor;\n");99writer.C("}\n");100break;101case GE_FORMAT_565:102writer.C("vec4 unpackColor(uint color) {\n");103writer.C(" vec4 outColor = vec4(float(color & 0x1Fu), float((color >> 0x5u) & 0x3Fu), float((color >> 0xBu) & 0x1Fu), 1.0);\n");104writer.C(" outColor.rb *= 1.0 / 31.0;\n");105writer.C(" outColor.g *= 1.0 / 63.0;\n");106writer.C(" return outColor;\n");107writer.C("}\n");108break;109case GE_FORMAT_8888:110writer.C("vec4 unpackColor(uint colorLeft, uint colorRight) {\n");111writer.C(" vec4 outColor = vec4(float(colorLeft & 0xFFu), float((colorLeft >> 0x8u) & 0xFFu),\n");112writer.C(" float(colorRight & 0xFFu), float((colorRight >> 0x8u) & 0xFFu));\n");113writer.C(" outColor *= 1.0 / 255.0;\n");114writer.C(" return outColor;\n");115writer.C("}\n");116break;117default:118_assert_(false);119break;120}121} else {122switch (to) {123case GE_FORMAT_4444:124writer.C("vec4 unpackColor(float color) {\n");125writer.C(" vec4 outColor = vec4(mod(floor(color), 16.0), mod(floor(color / 16.0), 16.0),");126writer.C(" mod(floor(color / 256.0), 16.0), mod(floor(color / 4096.0), 16.0)); \n");127writer.C(" outColor *= 1.0 / 15.0;\n");128writer.C(" return outColor;\n");129writer.C("}\n");130break;131case GE_FORMAT_5551:132writer.C("vec4 unpackColor(float color) {\n");133writer.C(" vec4 outColor = vec4(mod(floor(color), 32.0), mod(floor(color / 32.0), 32.0), mod(floor(color / 1024.0), 32.0), 0.0);\n");134writer.C(" outColor.rgb *= 1.0 / 31.0;\n");135writer.C(" outColor.a = floor(color / 32768.0);\n");136writer.C(" return outColor;\n");137writer.C("}\n");138break;139case GE_FORMAT_565:140writer.C("vec4 unpackColor(float color) {\n");141writer.C(" vec4 outColor = vec4(mod(floor(color), 32.0), mod(floor(color / 32.0), 64.0), mod(floor(color / 2048.0), 32.0), 0.0);\n");142writer.C(" outColor.rb *= 1.0 / 31.0;\n");143writer.C(" outColor.g *= 1.0 / 63.0;\n");144writer.C(" outColor.a = 1.0;\n");145writer.C(" return outColor;\n");146writer.C("}\n");147break;148case GE_FORMAT_8888:149writer.C("vec4 unpackColor(float colorLeft, float colorRight) {\n");150writer.C(" vec4 outColor = vec4(mod(floor(colorLeft), 256.0), mod(floor(colorLeft / 256.0), 256.0),\n");151writer.C(" mod(floor(colorRight), 256.0), mod(floor(colorRight / 256.0), 256.0));\n");152writer.C(" outColor *= 1.0 / 255.0;\n");153writer.C(" return outColor;\n");154writer.C("}\n");155break;156default:157_assert_(false);158break;159}160}161162writer.BeginFSMain(g_draw2Duniforms, varyings);163164if (IsBufferFormat16Bit(from) && IsBufferFormat16Bit(to)) {165writer.C(" vec4 val = ").SampleTexture2D("tex", "v_texcoord.xy").C(";\n");166writer.C(" vec4 outColor = unpackColor(packColor(val));\n");167} else if (IsBufferFormat16Bit(from) && !IsBufferFormat16Bit(to)) {168// 16-to-32-bit (two pixels, draw size is halved)169170writer.C(" vec4 valLeft = ").SampleTexture2D("tex", "v_texcoord.xy + vec2(-0.25 / texSize.x, 0.0)").C(";\n");171writer.C(" vec4 valRight = ").SampleTexture2D("tex", "v_texcoord.xy + vec2(0.25 / texSize.x, 0.0)").C(";\n");172writer.C(" vec4 outColor = unpackColor(packColor(valLeft), packColor(valRight));\n");173174_assert_("not yet implemented");175} else if (!IsBufferFormat16Bit(from) && IsBufferFormat16Bit(to)) {176// 32-to-16-bit (half of the pixel, draw size is doubled).177178writer.C(" vec4 val = ").SampleTexture2D("tex", "v_texcoord.xy").C(";\n");179writer.C(" float u = mod(floor(v_texcoord.x * texSize.x * 2.0), 2.0);\n");180writer.C(" vec4 outColor = unpackColor(u == 0.0 ? packColor(val.rg) : packColor(val.ba));\n");181}182183writer.EndFSMain("outColor");184185return Draw2DPipelineInfo{186"reinterpret",187RASTER_COLOR,188RASTER_COLOR,189};190}191192193194