Path: blob/master/GPU/Common/ReinterpretFramebuffer.cpp
3186 views
#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 "GPU/Common/ReinterpretFramebuffer.h"78static const VaryingDef varyings[1] = {9{ "vec2", "v_texcoord", Draw::SEM_TEXCOORD0, 0, "highp" },10};1112static const SamplerDef samplers[1] = {13{ 0, "tex", SamplerFlags::ARRAY_ON_VULKAN }14};1516// Requires full size integer math. It would be possible to make a floating point-only version with lots of17// modulo and stuff, might do it one day.18Draw2DPipelineInfo GenerateReinterpretFragmentShader(ShaderWriter &writer, GEBufferFormat from, GEBufferFormat to) {19writer.HighPrecisionFloat();20writer.DeclareSamplers(samplers);2122if (writer.Lang().bitwiseOps) {23switch (from) {24case GE_FORMAT_4444:25writer.C("uint packColor(vec4 val) {\n");26writer.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");27writer.C("}\n");28break;29case GE_FORMAT_5551:30writer.C("uint packColor(vec4 val) {\n");31writer.C(" uint color = uint(val.r * 31.99) | (uint(val.g * 31.99) << 0x5u) | (uint(val.b * 31.99) << 0xAu);\n");32writer.C(" if (val.a >= 0.5) color |= 0x8000U;\n");33writer.C(" return color;\n");34writer.C("}\n");35break;36case GE_FORMAT_565:37writer.C("uint packColor(vec4 val) {\n");38writer.C(" return uint(val.r * 31.99) | (uint(val.g * 63.99) << 0x5u) | (uint(val.b * 31.99) << 0xBu);\n");39writer.C("}\n");40break;41case GE_FORMAT_8888:42writer.C("uint packColor(vec2 val) {\n");43writer.C(" return uint(val.r * 255.99) | (uint(val.g * 255.99) << 8u);\n");44writer.C("}\n");45break;46default:47_assert_(false);48break;49}50} else {51// Floating point can comfortably represent integers up to 16 million, we only need 65536 since these textures are 16-bit.52switch (from) {53case GE_FORMAT_4444:54writer.C("float packColor(vec4 val) {\n");55writer.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");56writer.C("}\n");57break;58case GE_FORMAT_5551:59writer.C("float packColor(vec4 val) {\n");60writer.C(" float color = floor(val.r * 31.99) + floor(val.g * 31.99) * 32.0 + floor(val.b * 31.99) * 1024.0;\n");61writer.C(" if (val.a >= 0.5) color += 32768.0;\n");62writer.C(" return color;\n");63writer.C("}\n");64break;65case GE_FORMAT_565:66writer.C("float packColor(vec4 val) {\n");67writer.C(" return floor(val.r * 31.99) + floor(val.g * 63.99) * 32.0 + floor(val.b * 31.99) * 2048.0;\n");68writer.C("}\n");69break;70case GE_FORMAT_8888:71writer.C("float packColor(vec2 val) {\n");72writer.C(" return floor(val.r * 255.99) + floor(val.g * 255.99) * 256.0;\n");73writer.C("}\n");74break;75default:76_assert_(false);77break;78}79}8081if (writer.Lang().bitwiseOps) {82switch (to) {83case GE_FORMAT_4444:84writer.C("vec4 unpackColor(uint color) {\n");85writer.C(" vec4 outColor = vec4(float(color & 0xFu), float((color >> 0x4u) & 0xFu), float((color >> 0x8u) & 0xFu), float((color >> 0xCu) & 0xFu));\n");86writer.C(" outColor *= 1.0 / 15.0;\n");87writer.C(" return outColor;\n");88writer.C("}\n");89break;90case GE_FORMAT_5551:91writer.C("vec4 unpackColor(uint color) {\n");92writer.C(" vec4 outColor = vec4(float(color & 0x1Fu), float((color >> 0x5u) & 0x1Fu), float((color >> 0xAu) & 0x1Fu), 0.0);\n");93writer.C(" outColor.rgb *= 1.0 / 31.0;\n");94writer.C(" outColor.a = float(color >> 0xFu);\n");95writer.C(" return outColor;\n");96writer.C("}\n");97break;98case GE_FORMAT_565:99writer.C("vec4 unpackColor(uint color) {\n");100writer.C(" vec4 outColor = vec4(float(color & 0x1Fu), float((color >> 0x5u) & 0x3Fu), float((color >> 0xBu) & 0x1Fu), 1.0);\n");101writer.C(" outColor.rb *= 1.0 / 31.0;\n");102writer.C(" outColor.g *= 1.0 / 63.0;\n");103writer.C(" return outColor;\n");104writer.C("}\n");105break;106case GE_FORMAT_8888:107writer.C("vec4 unpackColor(uint colorLeft, uint colorRight) {\n");108writer.C(" vec4 outColor = vec4(float(colorLeft & 0xFFu), float((colorLeft >> 0x8u) & 0xFFu),\n");109writer.C(" float(colorRight & 0xFFu), float((colorRight >> 0x8u) & 0xFFu));\n");110writer.C(" outColor *= 1.0 / 255.0;\n");111writer.C(" return outColor;\n");112writer.C("}\n");113break;114default:115_assert_(false);116break;117}118} else {119switch (to) {120case GE_FORMAT_4444:121writer.C("vec4 unpackColor(float color) {\n");122writer.C(" vec4 outColor = vec4(mod(floor(color), 16.0), mod(floor(color / 16.0), 16.0),");123writer.C(" mod(floor(color / 256.0), 16.0), mod(floor(color / 4096.0), 16.0)); \n");124writer.C(" outColor *= 1.0 / 15.0;\n");125writer.C(" return outColor;\n");126writer.C("}\n");127break;128case GE_FORMAT_5551:129writer.C("vec4 unpackColor(float color) {\n");130writer.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");131writer.C(" outColor.rgb *= 1.0 / 31.0;\n");132writer.C(" outColor.a = floor(color / 32768.0);\n");133writer.C(" return outColor;\n");134writer.C("}\n");135break;136case GE_FORMAT_565:137writer.C("vec4 unpackColor(float color) {\n");138writer.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");139writer.C(" outColor.rb *= 1.0 / 31.0;\n");140writer.C(" outColor.g *= 1.0 / 63.0;\n");141writer.C(" outColor.a = 1.0;\n");142writer.C(" return outColor;\n");143writer.C("}\n");144break;145case GE_FORMAT_8888:146writer.C("vec4 unpackColor(float colorLeft, float colorRight) {\n");147writer.C(" vec4 outColor = vec4(mod(floor(colorLeft), 256.0), mod(floor(colorLeft / 256.0), 256.0),\n");148writer.C(" mod(floor(colorRight), 256.0), mod(floor(colorRight / 256.0), 256.0));\n");149writer.C(" outColor *= 1.0 / 255.0;\n");150writer.C(" return outColor;\n");151writer.C("}\n");152break;153default:154_assert_(false);155break;156}157}158159writer.BeginFSMain(g_draw2Duniforms, varyings);160161if (IsBufferFormat16Bit(from) && IsBufferFormat16Bit(to)) {162writer.C(" vec4 val = ").SampleTexture2D("tex", "v_texcoord.xy").C(";\n");163writer.C(" vec4 outColor = unpackColor(packColor(val));\n");164} else if (IsBufferFormat16Bit(from) && !IsBufferFormat16Bit(to)) {165// 16-to-32-bit (two pixels, draw size is halved)166167writer.C(" vec4 valLeft = ").SampleTexture2D("tex", "v_texcoord.xy + vec2(-0.25 / texSize.x, 0.0)").C(";\n");168writer.C(" vec4 valRight = ").SampleTexture2D("tex", "v_texcoord.xy + vec2(0.25 / texSize.x, 0.0)").C(";\n");169writer.C(" vec4 outColor = unpackColor(packColor(valLeft), packColor(valRight));\n");170171_assert_("not yet implemented");172} else if (!IsBufferFormat16Bit(from) && IsBufferFormat16Bit(to)) {173// 32-to-16-bit (half of the pixel, draw size is doubled).174175writer.C(" vec4 val = ").SampleTexture2D("tex", "v_texcoord.xy").C(";\n");176writer.C(" float u = mod(floor(v_texcoord.x * texSize.x * 2.0), 2.0);\n");177writer.C(" vec4 outColor = unpackColor(u == 0.0 ? packColor(val.rg) : packColor(val.ba));\n");178}179180writer.EndFSMain("outColor");181182return Draw2DPipelineInfo{183"reinterpret",184RASTER_COLOR,185RASTER_COLOR,186};187}188189190191