Use Draw2D for depal shaders (except the actual blit, for now)

This commit is contained in:
Henrik Rydgård
2022-08-23 11:11:04 +02:00
parent 60e129d88e
commit 5084743bbb
23 changed files with 71 additions and 132 deletions
+3
View File
@@ -94,6 +94,9 @@ public:
void EndVSMain(Slice<VaryingDef> varyings);
void EndFSMain(const char *vec4_color_variable, FSFlags flags);
const ShaderLanguageDesc &Lang() const {
return lang_;
}
void Rewind(size_t offset) {
p_ -= offset;
+3 -16
View File
@@ -27,8 +27,6 @@
#include "GPU/Common/GPUStateUtils.h"
#include "GPU/Common/DepalettizeShaderCommon.h"
#define WRITE p+=sprintf
static const InputDef vsInputs[2] = {
{ "vec2", "a_position", Draw::SEM_POSITION, },
{ "vec2", "a_texcoord0", Draw::SEM_TEXCOORD0, },
@@ -323,8 +321,7 @@ void GenerateDepalSmoothed(ShaderWriter &writer, const DepalConfig &config) {
writer.C(" vec4 outColor = ").SampleTexture2D("pal", "vec2(coord, 0.0)").C(";\n");
}
void GenerateDepalFs(char *buffer, const DepalConfig &config, const ShaderLanguageDesc &lang) {
ShaderWriter writer(buffer, lang, ShaderStage::Fragment);
void GenerateDepalFs(ShaderWriter &writer, const DepalConfig &config) {
writer.DeclareSamplers(samplers);
writer.HighPrecisionFloat();
writer.BeginFSMain(Slice<UniformDef>::empty(), varyings, FSFLAG_NONE);
@@ -333,7 +330,7 @@ void GenerateDepalFs(char *buffer, const DepalConfig &config, const ShaderLangua
// need two variants.
GenerateDepalSmoothed(writer, config);
} else {
switch (lang.shaderLanguage) {
switch (writer.Lang().shaderLanguage) {
case HLSL_D3D9:
case GLSL_1xx:
GenerateDepalShaderFloat(writer, config);
@@ -344,18 +341,8 @@ void GenerateDepalFs(char *buffer, const DepalConfig &config, const ShaderLangua
GenerateDepalShader300(writer, config);
break;
default:
_assert_msg_(false, "Depal shader language not supported: %d", (int)lang.shaderLanguage);
_assert_msg_(false, "Shader language not supported for depal: %d", (int)writer.Lang().shaderLanguage);
}
}
writer.EndFSMain("outColor", FSFLAG_NONE);
}
void GenerateVs(char *buffer, const ShaderLanguageDesc &lang) {
ShaderWriter writer(buffer, lang, ShaderStage::Vertex, nullptr, 0);
writer.BeginVSMain(vsInputs, Slice<UniformDef>::empty(), varyings);
writer.C(" v_texcoord = a_texcoord0;\n");
writer.C(" gl_Position = vec4(a_position, 0.0, 1.0);\n");
writer.EndVSMain(varyings);
}
#undef WRITE
+3 -2
View File
@@ -22,6 +22,8 @@
#include "Common/GPU/Shader.h"
#include "GPU/ge_constants.h"
class ShaderWriter;
static const int DEPAL_TEXTURE_OLD_AGE = 120;
struct DepalConfig {
@@ -34,5 +36,4 @@ struct DepalConfig {
bool smoothedDepal;
};
void GenerateDepalFs(char *buffer, const DepalConfig &config, const ShaderLanguageDesc &lang);
void GenerateVs(char *buffer, const ShaderLanguageDesc &lang);
void GenerateDepalFs(ShaderWriter &writer, const DepalConfig &config);
+2 -2
View File
@@ -196,7 +196,6 @@ Draw2DPipeline *Draw2D::Create2DPipeline(std::function<Draw2DPipelineInfo (Shade
Draw2DPipelineInfo info = generate(writer);
ShaderModule *fs = draw_->CreateShaderModule(ShaderStage::Fragment, shaderLanguageDesc.shaderLanguage, (const uint8_t *)fsCode, strlen(fsCode), "draw2d_fs");
delete[] fsCode;
_assert_(fs);
@@ -243,7 +242,8 @@ Draw2DPipeline *Draw2D::Create2DPipeline(std::function<Draw2DPipelineInfo (Shade
return new Draw2DPipeline {
pipeline,
info
info,
fsCode,
};
}
+3
View File
@@ -32,13 +32,16 @@ inline RasterChannel Draw2DSourceChannel(Draw2DShader shader) {
struct Draw2DPipelineInfo {
RasterChannel readChannel;
RasterChannel writeChannel;
bool secondTexture;
};
struct Draw2DPipeline {
Draw::Pipeline *pipeline;
Draw2DPipelineInfo info;
char *code;
void Release() {
pipeline->Release();
delete[] code;
delete this;
}
};
+4
View File
@@ -369,6 +369,10 @@ public:
}
void ReinterpretFramebuffer(VirtualFramebuffer *vfb, GEBufferFormat oldFormat, GEBufferFormat newFormat);
Draw2D *GetDraw2D() {
return &draw2D_;
}
protected:
virtual void PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h);
void SetViewport2D(int x, int y, int w, int h);
+4 -4
View File
@@ -105,8 +105,8 @@ inline int dimHeight(u16 dim) {
// Vulkan color formats:
// TODO
TextureCacheCommon::TextureCacheCommon(Draw::DrawContext *draw)
: draw_(draw) {
TextureCacheCommon::TextureCacheCommon(Draw::DrawContext *draw, Draw2D *draw2D)
: draw_(draw), draw2D_(draw2D) {
decimationCounter_ = TEXCACHE_DECIMATION_INTERVAL;
// TODO: Clamp down to 256/1KB? Need to check mipmapShareClut and clamp loadclut.
@@ -124,7 +124,7 @@ TextureCacheCommon::TextureCacheCommon(Draw::DrawContext *draw)
replacer_.Init();
textureShaderCache_ = new TextureShaderCache(draw);
textureShaderCache_ = new TextureShaderCache(draw, draw2D_);
}
TextureCacheCommon::~TextureCacheCommon() {
@@ -1885,7 +1885,7 @@ static bool CanUseSmoothDepal(const GPUgstate &gstate, GEBufferFormat framebuffe
}
void TextureCacheCommon::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, RasterChannel channel) {
TextureShader *textureShader = nullptr;
Draw2DPipeline *textureShader = nullptr;
uint32_t clutMode = gstate.clutformat & 0xFFFFFF;
bool depth = channel == RASTER_DEPTH;
+5 -1
View File
@@ -31,6 +31,8 @@
#include "GPU/Common/TextureScalerCommon.h"
#include "GPU/Common/TextureShaderCommon.h"
class Draw2D;
enum FramebufferNotification {
NOTIFY_FB_CREATED,
NOTIFY_FB_UPDATED,
@@ -271,7 +273,7 @@ struct BuildTexturePlan {
class TextureCacheCommon {
public:
TextureCacheCommon(Draw::DrawContext *draw);
TextureCacheCommon(Draw::DrawContext *draw, Draw2D *draw2D);
virtual ~TextureCacheCommon();
void LoadClut(u32 clutAddr, u32 loadBytes);
@@ -400,6 +402,8 @@ protected:
}
Draw::DrawContext *draw_;
Draw2D *draw2D_;
TextureReplacer replacer_;
TextureScalerCommon scaler_;
FramebufferManagerCommon *framebufferManager_;
+21 -68
View File
@@ -23,6 +23,7 @@
#include "Common/GPU/ShaderWriter.h"
#include "Common/Data/Convert/ColorConv.h"
#include "Core/Reporting.h"
#include "GPU/Common/Draw2D.h"
#include "GPU/Common/DrawEngineCommon.h"
#include "GPU/Common/TextureCacheCommon.h"
#include "GPU/Common/TextureShaderCommon.h"
@@ -37,7 +38,7 @@ static const SamplerDef samplers[2] = {
{ "pal" },
};
TextureShaderCache::TextureShaderCache(Draw::DrawContext *draw) : draw_(draw) { }
TextureShaderCache::TextureShaderCache(Draw::DrawContext *draw, Draw2D *draw2D) : draw_(draw), draw2D_(draw2D) { }
TextureShaderCache::~TextureShaderCache() {
DeviceLost();
@@ -139,10 +140,6 @@ void TextureShaderCache::Clear() {
delete tex->second;
}
texCache_.clear();
if (vertexShader_) {
vertexShader_->Release();
vertexShader_ = nullptr;
}
if (nearestSampler_) {
nearestSampler_->Release();
nearestSampler_ = nullptr;
@@ -153,18 +150,6 @@ void TextureShaderCache::Clear() {
}
}
void TextureShaderCache::Decimate() {
for (auto tex = texCache_.begin(); tex != texCache_.end(); ) {
if (tex->second->lastFrame + DEPAL_TEXTURE_OLD_AGE < gpuStats.numFlips) {
tex->second->texture->Release();
delete tex->second;
texCache_.erase(tex++);
} else {
++tex;
}
}
}
Draw::SamplerState *TextureShaderCache::GetSampler(bool linearFilter) {
if (linearFilter) {
if (!linearSampler_) {
@@ -189,55 +174,19 @@ Draw::SamplerState *TextureShaderCache::GetSampler(bool linearFilter) {
}
}
TextureShader *TextureShaderCache::CreateShader(const char *fs) {
using namespace Draw;
if (!vertexShader_) {
char *buffer = new char[4096];
GenerateVs(buffer, draw_->GetShaderLanguageDesc());
vertexShader_ = draw_->CreateShaderModule(ShaderStage::Vertex, draw_->GetShaderLanguageDesc().shaderLanguage, (const uint8_t *)buffer, strlen(buffer), "depal_vs");
delete[] buffer;
void TextureShaderCache::Decimate() {
for (auto tex = texCache_.begin(); tex != texCache_.end(); ) {
if (tex->second->lastFrame + DEPAL_TEXTURE_OLD_AGE < gpuStats.numFlips) {
tex->second->texture->Release();
delete tex->second;
texCache_.erase(tex++);
} else {
++tex;
}
}
ShaderModule *fragShader = draw_->CreateShaderModule(ShaderStage::Fragment, draw_->GetShaderLanguageDesc().shaderLanguage, (const uint8_t *)fs, strlen(fs), "depal_fs");
static const InputLayoutDesc desc = {
{
{ 16, false },
},
{
{ 0, SEM_POSITION, DataFormat::R32G32_FLOAT, 0 },
{ 0, SEM_TEXCOORD0, DataFormat::R32G32_FLOAT, 8 },
},
};
InputLayout *inputLayout = draw_->CreateInputLayout(desc);
BlendState *blendOff = draw_->CreateBlendState({ false, 0xF });
DepthStencilStateDesc dsDesc{};
DepthStencilState *noDepthStencil = draw_->CreateDepthStencilState(dsDesc);
RasterState *rasterNoCull = draw_->CreateRasterState({});
PipelineDesc depalPipelineDesc{
Primitive::TRIANGLE_STRIP, // Could have use a single triangle too (in which case we'd use LIST here) but want to be prepared to do subrectangles.
{ vertexShader_, fragShader },
inputLayout, noDepthStencil, blendOff, rasterNoCull, nullptr, samplers
};
Pipeline *pipeline = draw_->CreateGraphicsPipeline(depalPipelineDesc);
inputLayout->Release();
blendOff->Release();
noDepthStencil->Release();
rasterNoCull->Release();
fragShader->Release();
_assert_(pipeline);
TextureShader *depal = new TextureShader();
depal->pipeline = pipeline;
depal->code = fs; // to std::string
return depal;
}
TextureShader *TextureShaderCache::GetDepalettizeShader(uint32_t clutMode, GETextureFormat textureFormat, GEBufferFormat bufferFormat, bool smoothedDepal) {
Draw2DPipeline *TextureShaderCache::GetDepalettizeShader(uint32_t clutMode, GETextureFormat textureFormat, GEBufferFormat bufferFormat, bool smoothedDepal) {
using namespace Draw;
// Generate an ID for depal shaders.
@@ -245,7 +194,6 @@ TextureShader *TextureShaderCache::GetDepalettizeShader(uint32_t clutMode, GETex
auto shader = depalCache_.find(id);
if (shader != depalCache_.end()) {
TextureShader *depal = shader->second;
return shader->second;
}
@@ -260,8 +208,13 @@ TextureShader *TextureShaderCache::GetDepalettizeShader(uint32_t clutMode, GETex
config.smoothedDepal = smoothedDepal;
char *buffer = new char[4096];
GenerateDepalFs(buffer, config, draw_->GetShaderLanguageDesc());
TextureShader *ts = CreateShader(buffer);
Draw2DPipeline *ts = draw2D_->Create2DPipeline([=](ShaderWriter &writer) -> Draw2DPipelineInfo {
GenerateDepalFs(writer, config);
return Draw2DPipelineInfo{
config.bufferFormat == GE_FORMAT_DEPTH16 ? RASTER_DEPTH : RASTER_COLOR,
RASTER_COLOR,
};
});
delete[] buffer;
depalCache_[id] = ts;
@@ -293,7 +246,7 @@ std::string TextureShaderCache::DebugGetShaderString(std::string idstr, DebugSha
}
}
void TextureShaderCache::ApplyShader(TextureShader *shader, float bufferW, float bufferH, int renderW, int renderH, const KnownVertexBounds &bounds, u32 uoff, u32 voff) {
void TextureShaderCache::ApplyShader(Draw2DPipeline *pipeline, float bufferW, float bufferH, int renderW, int renderH, const KnownVertexBounds &bounds, u32 uoff, u32 voff) {
Draw2DVertex verts[4] = {
{-1, -1, 0, 0 },
{ 1, -1, 1, 0 },
@@ -335,7 +288,7 @@ void TextureShaderCache::ApplyShader(TextureShader *shader, float bufferW, float
}
Draw::Viewport vp{ 0.0f, 0.0f, (float)renderW, (float)renderH, 0.0f, 1.0f };
draw_->BindPipeline(shader->pipeline);
draw_->BindPipeline(pipeline->pipeline);
draw_->SetViewports(1, &vp);
draw_->SetScissorRect(0, 0, renderW, renderH);
draw_->DrawUP((const uint8_t *)verts, 4);
+5 -13
View File
@@ -29,12 +29,6 @@
#include "GPU/Common/ShaderCommon.h"
#include "GPU/Common/DepalettizeShaderCommon.h"
class TextureShader {
public:
Draw::Pipeline *pipeline;
std::string code;
};
class ClutTexture {
public:
Draw::Texture *texture;
@@ -46,15 +40,15 @@ public:
// Caches both shaders and palette textures.
class TextureShaderCache {
public:
TextureShaderCache(Draw::DrawContext *draw);
TextureShaderCache(Draw::DrawContext *draw, Draw2D *draw2D);
~TextureShaderCache();
TextureShader *GetDepalettizeShader(uint32_t clutMode, GETextureFormat texFormat, GEBufferFormat pixelFormat, bool smoothedDepal);
Draw2DPipeline *GetDepalettizeShader(uint32_t clutMode, GETextureFormat texFormat, GEBufferFormat pixelFormat, bool smoothedDepal);
ClutTexture GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut);
Draw::SamplerState *GetSampler(bool linearFilter);
void ApplyShader(TextureShader *shader, float bufferW, float bufferH, int renderW, int renderH, const KnownVertexBounds &bounds, u32 uoff, u32 voff);
void ApplyShader(Draw2DPipeline *pipeline, float bufferW, float bufferH, int renderW, int renderH, const KnownVertexBounds &bounds, u32 uoff, u32 voff);
void Clear();
void Decimate();
@@ -65,13 +59,11 @@ public:
void DeviceRestore(Draw::DrawContext *draw);
private:
TextureShader *CreateShader(const char *fs);
Draw::DrawContext *draw_;
Draw::ShaderModule *vertexShader_ = nullptr;
Draw::SamplerState *nearestSampler_ = nullptr;
Draw::SamplerState *linearSampler_ = nullptr;
Draw2D *draw2D_;
std::map<u32, TextureShader *> depalCache_;
std::map<u32, Draw2DPipeline *> depalCache_;
std::map<u32, ClutTexture *> texCache_;
};
+1 -1
View File
@@ -60,7 +60,7 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
shaderManagerD3D11_ = new ShaderManagerD3D11(draw, device_, context_, featureLevel);
framebufferManagerD3D11_ = new FramebufferManagerD3D11(draw);
framebufferManager_ = framebufferManagerD3D11_;
textureCacheD3D11_ = new TextureCacheD3D11(draw);
textureCacheD3D11_ = new TextureCacheD3D11(draw, framebufferManager_->GetDraw2D());
textureCache_ = textureCacheD3D11_;
drawEngineCommon_ = &drawEngine_;
shaderManager_ = shaderManagerD3D11_;
+2 -2
View File
@@ -127,8 +127,8 @@ ID3D11SamplerState *SamplerCacheD3D11::GetOrCreateSampler(ID3D11Device *device,
return sampler;
}
TextureCacheD3D11::TextureCacheD3D11(Draw::DrawContext *draw)
: TextureCacheCommon(draw) {
TextureCacheD3D11::TextureCacheD3D11(Draw::DrawContext *draw, Draw2D *draw2D)
: TextureCacheCommon(draw, draw2D) {
device_ = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE);
context_ = (ID3D11DeviceContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT);
+1 -1
View File
@@ -43,7 +43,7 @@ private:
class TextureCacheD3D11 : public TextureCacheCommon {
public:
TextureCacheD3D11(Draw::DrawContext *draw);
TextureCacheD3D11(Draw::DrawContext *draw, Draw2D *draw2D);
~TextureCacheD3D11();
void StartFrame() override;
+1 -1
View File
@@ -58,7 +58,7 @@ GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
shaderManagerDX9_ = new ShaderManagerDX9(draw, device_);
framebufferManagerDX9_ = new FramebufferManagerDX9(draw);
framebufferManager_ = framebufferManagerDX9_;
textureCacheDX9_ = new TextureCacheDX9(draw);
textureCacheDX9_ = new TextureCacheDX9(draw, framebufferManager_->GetDraw2D());
textureCache_ = textureCacheDX9_;
drawEngineCommon_ = &drawEngine_;
shaderManager_ = shaderManagerDX9_;
+2 -2
View File
@@ -59,8 +59,8 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
D3DDECL_END()
};
TextureCacheDX9::TextureCacheDX9(Draw::DrawContext *draw)
: TextureCacheCommon(draw) {
TextureCacheDX9::TextureCacheDX9(Draw::DrawContext *draw, Draw2D *draw2D)
: TextureCacheCommon(draw, draw2D) {
lastBoundTexture = INVALID_TEX;
isBgraBackend_ = true;
+1 -1
View File
@@ -31,7 +31,7 @@ class ShaderManagerDX9;
class TextureCacheDX9 : public TextureCacheCommon {
public:
TextureCacheDX9(Draw::DrawContext *draw);
TextureCacheDX9(Draw::DrawContext *draw, Draw2D *draw2D);
~TextureCacheDX9();
void StartFrame() override;
+1 -1
View File
@@ -60,7 +60,7 @@ GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
shaderManagerGL_ = new ShaderManagerGLES(draw);
framebufferManagerGL_ = new FramebufferManagerGLES(draw);
framebufferManager_ = framebufferManagerGL_;
textureCacheGL_ = new TextureCacheGLES(draw);
textureCacheGL_ = new TextureCacheGLES(draw, framebufferManager_->GetDraw2D());
textureCache_ = textureCacheGL_;
drawEngineCommon_ = &drawEngine_;
shaderManager_ = shaderManagerGL_;
+2 -2
View File
@@ -45,8 +45,8 @@
#include <emmintrin.h>
#endif
TextureCacheGLES::TextureCacheGLES(Draw::DrawContext *draw)
: TextureCacheCommon(draw) {
TextureCacheGLES::TextureCacheGLES(Draw::DrawContext *draw, Draw2D *draw2D)
: TextureCacheCommon(draw, draw2D) {
render_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
nextTexture_ = nullptr;
+1 -1
View File
@@ -34,7 +34,7 @@ class GLRTexture;
class TextureCacheGLES : public TextureCacheCommon {
public:
TextureCacheGLES(Draw::DrawContext *draw);
TextureCacheGLES(Draw::DrawContext *draw, Draw2D *draw2D);
~TextureCacheGLES();
void Clear(bool delete_them) override;
+1 -1
View File
@@ -63,7 +63,7 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
pipelineManager_ = new PipelineManagerVulkan(vulkan);
framebufferManagerVulkan_ = new FramebufferManagerVulkan(draw);
framebufferManager_ = framebufferManagerVulkan_;
textureCacheVulkan_ = new TextureCacheVulkan(draw, vulkan);
textureCacheVulkan_ = new TextureCacheVulkan(draw, framebufferManager_->GetDraw2D(), vulkan);
textureCache_ = textureCacheVulkan_;
drawEngineCommon_ = &drawEngine_;
shaderManager_ = shaderManagerVulkan_;
+2 -2
View File
@@ -184,8 +184,8 @@ std::vector<std::string> SamplerCache::DebugGetSamplerIDs() const {
return ids;
}
TextureCacheVulkan::TextureCacheVulkan(Draw::DrawContext *draw, VulkanContext *vulkan)
: TextureCacheCommon(draw),
TextureCacheVulkan::TextureCacheVulkan(Draw::DrawContext *draw, Draw2D *draw2D, VulkanContext *vulkan)
: TextureCacheCommon(draw, draw2D),
computeShaderManager_(vulkan),
samplerCache_(vulkan) {
DeviceRestore(draw);
+1 -1
View File
@@ -54,7 +54,7 @@ private:
class TextureCacheVulkan : public TextureCacheCommon {
public:
TextureCacheVulkan(Draw::DrawContext *draw, VulkanContext *vulkan);
TextureCacheVulkan(Draw::DrawContext *draw, Draw2D *draw2D, VulkanContext *vulkan);
~TextureCacheVulkan();
void StartFrame() override;
+2 -10
View File
@@ -292,7 +292,8 @@ bool TestDepalShaders() {
config.bufferFormat = GE_FORMAT_8888;
config.textureFormat = GE_TFMT_CLUT32;
GenerateDepalFs(buffer, config, desc);
ShaderWriter writer(buffer, desc, ShaderStage::Fragment);
GenerateDepalFs(writer, config);
if (!TestCompileShader(buffer, languages[k], ShaderStage::Fragment, &errorMessage)) {
printf("Error compiling depal shader:\n\n%s\n\n%s\n", LineNumberString(buffer).c_str(), errorMessage.c_str());
failed = true;
@@ -300,15 +301,6 @@ bool TestDepalShaders() {
} else {
printf("===\n%s\n===\n", buffer);
}
GenerateVs(buffer, desc);
if (!TestCompileShader(buffer, languages[k], ShaderStage::Vertex, &errorMessage)) {
printf("Error compiling depal shader:\n\n%s\n\n%s\n", LineNumberString(buffer).c_str(), errorMessage.c_str());
failed = true;
return false;
} else {
printf("===\n%s\n===\n", buffer);
}
}
delete[] buffer;