Merge pull request #13613 from hrydgard/shader-writer

Shader writer utility, other cleanups
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2020-11-02 13:32:35 +01:00
commit bd066b4e55
28 files changed
+360 -165

No files matched your search

+2
View File
@@ -1356,6 +1356,8 @@ set(GPU_SOURCES
GPU/Common/ShaderUniforms.h
GPU/Common/ShaderCommon.cpp
GPU/Common/ShaderCommon.h
GPU/Common/ShaderWriter.cpp
GPU/Common/ShaderWriter.h
GPU/Common/ShaderTranslation.cpp
GPU/Common/ShaderTranslation.h
GPU/Common/SplineCommon.cpp
+6
View File
@@ -450,6 +450,12 @@ void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &sou
MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, dest, std::min((int)destSize, size));
}
void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const char *source) {
int len = (int)strlen(source) + 1; // include trailing zero
int size = (int)MultiByteToWideChar(CP_UTF8, 0, source, len, NULL, 0);
MultiByteToWideChar(CP_UTF8, 0, source, len, dest, std::min((int)destSize, size));
}
std::wstring ConvertUTF8ToWString(const std::string &source) {
int len = (int)source.size();
int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0);
+1
View File
@@ -83,6 +83,7 @@ bool UTF8StringHasNonASCII(const char *utf8string);
std::string ConvertWStringToUTF8(const std::wstring &wstr);
std::string ConvertWStringToUTF8(const wchar_t *wstr);
void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source);
void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const char *source);
std::wstring ConvertUTF8ToWString(const std::string &source);
#else
+7 -2
View File
@@ -213,7 +213,11 @@ VulkanRenderManager::VulkanRenderManager(VulkanContext *vulkan) : vulkan_(vulkan
}
}
void VulkanRenderManager::CreateBackbuffers() {
bool VulkanRenderManager::CreateBackbuffers() {
if (!vulkan_->GetSwapchain()) {
ERROR_LOG(G3D, "No swapchain - can't create backbuffers");
return false;
}
VkResult res = vkGetSwapchainImagesKHR(vulkan_->GetDevice(), vulkan_->GetSwapchain(), &swapchainImageCount_, nullptr);
_dbg_assert_(res == VK_SUCCESS);
@@ -222,7 +226,7 @@ void VulkanRenderManager::CreateBackbuffers() {
if (res != VK_SUCCESS) {
ERROR_LOG(G3D, "vkGetSwapchainImagesKHR failed");
delete[] swapchainImages;
return;
return false;
}
VkCommandBuffer cmdInit = GetInitCmd();
@@ -283,6 +287,7 @@ void VulkanRenderManager::CreateBackbuffers() {
INFO_LOG(G3D, "Starting Vulkan submission thread (threadInitFrame_ = %d)", vulkan_->GetCurFrame());
thread_ = std::thread(&VulkanRenderManager::ThreadFunc, this);
}
return true;
}
void VulkanRenderManager::StopThread() {
+1 -1
View File
@@ -289,7 +289,7 @@ public:
return renderStepOffset_ + (int)steps_.size();
}
void CreateBackbuffers();
bool CreateBackbuffers();
void DestroyBackbuffers();
bool HasBackbuffers() {
+49
View File
@@ -0,0 +1,49 @@
#include <cstdarg>
#include "GPU/Common/ColorReinterpret.h"
#include "GPU/Common/ShaderWriter.h"
// TODO: We could have an option to preserve any extra color precision. But gonna start without it.
// Requires full size integer math.
bool GenerateReinterpretFragmentShader(char *buffer, GEBufferFormat from, GEBufferFormat to, const ShaderLanguageDesc &lang) {
if (!lang.bitwiseOps) {
return false;
}
ShaderWriter writer(buffer, lang, ShaderStage::Fragment);
switch (from) {
case GE_FORMAT_4444:
writer.W(" uint color = uint(in.r * 15.99) | (uint(in.g * 15.99) << 4) | (uint(in.b * 15.99) << 8) | (uint(in.a * 15.99) << 12);\n");
break;
case GE_FORMAT_5551:
writer.W(" uint color = uint(in.r * 31.99) | (uint(in.g * 31.99) << 5) | (uint(in.b * 31.99) << 10);\n");
writer.W(" if (in.a > 128.0) color |= 0x8000;\n");
break;
case GE_FORMAT_565:
writer.W(" uint color = uint(in.r * 31.99) | (uint(in.g * 63.99) << 5) | (uint(in.b * 31.99) << 11);\n");
break;
default: _assert_(false);
}
switch (to) {
case GE_FORMAT_4444:
writer.W(" vec4 output = vec4(float(color & 0xF), float((color >> 4) & 0xF), float((color >> 8) & 0xF), float((color >> 12) & 0xF));\n");
writer.W(" output *= 1.0 / 15.0;\n");
break;
case GE_FORMAT_5551:
writer.W(" vec4 output = vec4(float(color & 0x1F), float((color >> 5) & 0x1F), float((color >> 10) & 0x1F), 0.0);\n");
writer.W(" output.rgb *= 1.0 / 31.0;\n");
writer.W(" output.a = float(color >> 15);\n");
break;
case GE_FORMAT_565:
writer.W(" vec4 output = vec4(float(color & 0x1F), float((color >> 5) & 0x3F), float((color >> 11) & 0x1F), 1.0);\n");
writer.W(" output.rb *= 1.0 / 31.0;\n");
writer.W(" output.g *= 1.0 / 63.0;\n");
break;
default: _assert_(false);
}
writer.W("}");
return true;
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "Common/Log.h"
#include "GPU/ge_constants.h"
#include "GPU/GPUCommon.h"
#include "GPU/Common/ShaderWriter.h"
+9 -66
View File
@@ -27,44 +27,11 @@
#include "GPU/Common/ShaderId.h"
#include "GPU/Common/ShaderUniforms.h"
#include "GPU/Common/FragmentShaderGenerator.h"
#include "GPU/Common/ShaderWriter.h"
#include "GPU/ge_constants.h"
#include "GPU/GPUState.h"
#define WRITE p+=sprintf
const char *vulkan_glsl_preamble_fs =
"#version 450\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
"#extension GL_ARB_shading_language_420pack : enable\n"
"#extension GL_ARB_conservative_depth : enable\n"
"#extension GL_ARB_shader_image_load_store : enable\n"
"#define splat3(x) vec3(x)\n"
"#define lowp\n"
"#define mediump\n"
"#define highp\n"
"#define DISCARD discard\n"
"\n";
const char *hlsl_preamble_fs =
"#define vec2 float2\n"
"#define vec3 float3\n"
"#define vec4 float4\n"
"#define uvec3 uint3\n"
"#define ivec3 int3\n"
"#define ivec4 int4\n"
"#define mat4 float4x4\n"
"#define mat3x4 float4x3\n" // note how the conventions are backwards
"#define splat3(x) float3(x, x, x)\n"
"#define mix lerp\n"
"#define mod(x, y) fmod(x, y)\n";
const char *hlsl_d3d11_preamble_fs =
"#define DISCARD discard\n"
"#define DISCARD_BELOW(x) clip(x);\n";
const char *hlsl_d3d9_preamble_fs =
"#define DISCARD clip(-1)\n"
"#define DISCARD_BELOW(x) clip(x)\n";
#define WRITE(p, ...) p.F(__VA_ARGS__)
bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLanguageDesc &compat, uint64_t *uniformMask, std::string *errorString) {
*uniformMask = 0;
@@ -83,45 +50,21 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
ReplaceAlphaType stencilToAlpha = static_cast<ReplaceAlphaType>(id.Bits(FS_BIT_STENCIL_TO_ALPHA, 2));
char *p = buffer;
switch (compat.shaderLanguage) {
case ShaderLanguage::GLSL_VULKAN:
WRITE(p, "%s", vulkan_glsl_preamble_fs);
break;
case ShaderLanguage::HLSL_D3D11:
WRITE(p, "%s", hlsl_preamble_fs);
WRITE(p, "%s", hlsl_d3d11_preamble_fs);
break;
case ShaderLanguage::HLSL_D3D9:
WRITE(p, "%s", hlsl_preamble_fs);
WRITE(p, "%s", hlsl_d3d9_preamble_fs);
break;
default:
// OpenGL
WRITE(p, "#version %d%s\n", compat.glslVersionNumber, compat.gles && compat.glslES30 ? " es" : "");
WRITE(p, "#define DISCARD discard\n");
std::vector<const char*> gl_exts;
if (ShaderLanguageIsOpenGL(compat.shaderLanguage)) {
if (stencilToAlpha == REPLACE_ALPHA_DUALSOURCE && gl_extensions.EXT_blend_func_extended) {
WRITE(p, "#extension GL_EXT_blend_func_extended : require\n");
gl_exts.push_back("#extension GL_EXT_blend_func_extended : require");
}
if (gl_extensions.EXT_gpu_shader4) {
WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n");
gl_exts.push_back("#extension GL_EXT_gpu_shader4 : enable");
}
if (compat.framebufferFetchExtension) {
WRITE(p, "%s\n", compat.framebufferFetchExtension);
gl_exts.push_back(compat.framebufferFetchExtension);
}
if (!compat.gles) {
WRITE(p, "#define lowp\n");
WRITE(p, "#define mediump\n");
WRITE(p, "#define highp\n");
} else {
WRITE(p, "precision lowp float;\n");
}
WRITE(p, "#define splat3(x) vec3(x)\n");
}
ShaderWriter p(buffer, compat, ShaderStage::Fragment, gl_exts.data(), gl_exts.size());
bool lmode = id.Bit(FS_BIT_LMODE);
bool doTexture = id.Bit(FS_BIT_DO_TEXTURE);
bool enableFog = id.Bit(FS_BIT_ENABLE_FOG);
+6 -3
View File
@@ -265,10 +265,13 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
if (v->fb_address == params.fb_address) {
vfb = v;
// Update fb stride in case it changed
if (vfb->fb_stride != params.fb_stride || vfb->format != params.fmt) {
vfbFormatChanged = true;
if (vfb->fb_stride != params.fb_stride) {
vfb->fb_stride = params.fb_stride;
vfbFormatChanged = true;
}
if (vfb->format != params.fmt) {
vfb->format = params.fmt;
vfbFormatChanged = true;
}
if (vfb->z_address == 0 && vfb->z_stride == 0 && params.z_stride != 0) {
@@ -1087,7 +1090,7 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w,
shaderManager_->DirtyLastShader();
char tag[256];
snprintf(tag, sizeof(tag), "%08x_%08x_%dx%d", vfb->fb_address, vfb->z_address, w, h);
snprintf(tag, sizeof(tag), "%08x_%08x_%dx%d_%s", vfb->fb_address, vfb->z_address, w, h, GeBufferFormatToString((GEBufferFormat)vfb->colorDepth));
vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)vfb->colorDepth, tag });
if (old.fbo) {
INFO_LOG(FRAMEBUF, "Resizing FBO for %08x : %dx%dx%s", vfb->fb_address, w, h, GeBufferFormatToString(vfb->format));
+6 -1
View File
@@ -55,7 +55,7 @@ struct VirtualFramebuffer {
int fb_stride;
int z_stride;
GEBufferFormat format; // virtual, right now they are all RGBA8888
GEBufferFormat format; // virtual, in reality they are all RGBA8888 for better quality but we can reinterpret that as necessary
// width/height: The detected size of the current framebuffer, in original PSP pixels.
u16 width;
@@ -424,4 +424,9 @@ protected:
FBO_OLD_AGE = 5,
FBO_OLD_USAGE_FLAG = 15,
};
// Thin3D stuff for reinterpreting image data between the various 16-bit formats.
// Safe, not optimal - there might be input attachment tricks, etc, but we can't use them
// since we don't want N different implementations.
Draw::Pipeline *reinterpretFromTo_[3][3];
};
+1 -1
View File
@@ -411,7 +411,7 @@ void PresentationCommon::CreateDeviceObjects() {
vdata_ = draw_->CreateBuffer(sizeof(Vertex) * 8, BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA);
// TODO: Use 4 and a strip?
// TODO: Use a triangle strip? Makes the UV rotation slightly more complex.
idata_ = draw_->CreateBuffer(sizeof(uint16_t) * 6, BufferUsageFlag::DYNAMIC | BufferUsageFlag::INDEXDATA);
uint16_t indexes[] = { 0, 1, 2, 0, 2, 3 };
draw_->UpdateBuffer(idata_, (const uint8_t *)indexes, 0, sizeof(indexes), Draw::UPDATE_DISCARD);
+5
View File
@@ -52,6 +52,11 @@ enum DebugShaderStringType {
SHADER_STRING_STATS = 2,
};
enum class ShaderStage {
Vertex,
Fragment
};
// Shared between the backends. Not all are necessarily used by each backend, but this lets us share
// more code than before.
enum : uint64_t {
+124
View File
@@ -0,0 +1,124 @@
#include "GPU/Common/ShaderWriter.h"
const char *vulkan_glsl_preamble_fs =
"#version 450\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
"#extension GL_ARB_shading_language_420pack : enable\n"
"#extension GL_ARB_conservative_depth : enable\n"
"#extension GL_ARB_shader_image_load_store : enable\n"
"#define splat3(x) vec3(x)\n"
"#define lowp\n"
"#define mediump\n"
"#define highp\n"
"#define DISCARD discard\n"
"\n";
const char *hlsl_preamble_fs =
"#define vec2 float2\n"
"#define vec3 float3\n"
"#define vec4 float4\n"
"#define uvec3 uint3\n"
"#define ivec3 int3\n"
"#define ivec4 int4\n"
"#define mat4 float4x4\n"
"#define mat3x4 float4x3\n" // note how the conventions are backwards
"#define splat3(x) float3(x, x, x)\n"
"#define mix lerp\n"
"#define mod(x, y) fmod(x, y)\n";
const char *hlsl_d3d11_preamble_fs =
"#define DISCARD discard\n"
"#define DISCARD_BELOW(x) clip(x);\n";
const char *hlsl_d3d9_preamble_fs =
"#define DISCARD clip(-1)\n"
"#define DISCARD_BELOW(x) clip(x)\n";
const char *vulkan_glsl_preamble_vs =
"#version 450\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
"#extension GL_ARB_shading_language_420pack : enable\n"
"#define mul(x, y) ((x) * (y))\n"
"#define splat3(x) vec3(x)\n"
"#define lowp\n"
"#define mediump\n"
"#define highp\n"
"\n";
const char *hlsl_preamble_vs =
"#define vec2 float2\n"
"#define vec3 float3\n"
"#define vec4 float4\n"
"#define ivec2 int2\n"
"#define ivec4 int4\n"
"#define mat4 float4x4\n"
"#define mat3x4 float4x3\n" // note how the conventions are backwards
"#define splat3(x) vec3(x, x, x)\n"
"#define lowp\n"
"#define mediump\n"
"#define highp\n"
"\n";
// Unsafe. But doesn't matter, we'll use big buffers for shader gen.
void ShaderWriter::F(const char *format, ...) {
va_list args;
va_start(args, format);
p_ += vsprintf(p_, format, args);
va_end(args);
}
void ShaderWriter::Preamble(const char **gl_extensions, size_t num_gl_extensions) {
switch (lang_.shaderLanguage) {
case GLSL_VULKAN:
switch (stage_) {
case ShaderStage::Vertex:
W(vulkan_glsl_preamble_vs);
break;
case ShaderStage::Fragment:
W(vulkan_glsl_preamble_fs);
break;
}
break;
case HLSL_D3D11:
case HLSL_D3D9:
switch (stage_) {
case ShaderStage::Vertex:
W(hlsl_preamble_vs);
break;
case ShaderStage::Fragment:
W(hlsl_preamble_fs);
if (lang_.shaderLanguage == HLSL_D3D9) {
W(hlsl_d3d9_preamble_fs);
} else {
W(hlsl_d3d11_preamble_fs);
}
break;
}
break;
default: // OpenGL
F("#version %d%s\n", lang_.glslVersionNumber, lang_.gles && lang_.glslES30 ? " es" : "");
switch (stage_) {
case ShaderStage::Fragment:
C("#define DISCARD discard\n");
if (lang_.gles) {
C("precision lowp float;\n");
}
break;
case ShaderStage::Vertex:
if (lang_.gles) {
C("precision highp float;\n");
}
break;
}
for (size_t i = 0; i < num_gl_extensions; i++) {
F("%s\n", gl_extensions[i]);
}
if (!lang_.gles) {
C("#define lowp\n");
C("#define mediump\n");
C("#define highp\n");
}
C("#define splat3(x) vec3(x)\n");
C("#define mul(x, y) ((x) * (y))\n");
break;
}
}
+51
View File
@@ -0,0 +1,51 @@
#pragma once
#include "Common/Log.h"
#include "GPU/ge_constants.h"
#include "GPU/GPUCommon.h"
#include "GPU/Common/ShaderCommon.h"
// Helps generate a shader compatible with all backends.
// Using #defines and magic in this class, we partially define our own shader language that basically looks
// like GLSL, but has a few little oddities like splat3.
class ShaderWriter {
public:
ShaderWriter(char *buffer, const ShaderLanguageDesc &lang, ShaderStage stage, const char **gl_extensions, size_t num_gl_extensions) : p_(buffer), lang_(lang), stage_(stage) {
Preamble(gl_extensions, num_gl_extensions);
}
// I tried to call all three write functions "W", but only MSVC
// managed to disentangle the ambiguities, so had to give up on that.
// Assumes the input is zero-terminated.
// C : Copies a buffer directly to the stream.
template<size_t T>
void C(const char(&text)[T]) {
memcpy(p_, text, T);
p_ += T;
}
// W: Writes a zero-terminated string to the stream.
void W(const char *text) {
size_t len = strlen(text);
memcpy(p_, text, len + 1);
p_ += len;
}
// F: Formats into the buffer.
void F(const char *format, ...);
// void BeginMain();
// void EndMain();
char *GetPos() {
return p_;
}
private:
void Preamble(const char **gl_extensions, size_t num_gl_extensions);
char *p_;
const ShaderLanguageDesc &lang_;
const ShaderStage stage_;
};
+11 -3
View File
@@ -471,11 +471,16 @@ TexCacheEntry *TextureCacheCommon::SetTexture() {
// No texture found, or changed (depending on entry).
// Check for framebuffers.
TextureDefinition def{};
TextureDefinition def;
def.addr = texaddr;
def.dim = dim;
def.format = format;
def.bufw = bufw;
def.swizzled = gstate.isTextureSwizzled();
if (texaddr == 0x40cc000) {
texaddr = texaddr;
}
std::vector<AttachCandidate> candidates = GetFramebufferCandidates(def, 0);
if (candidates.size() > 0) {
@@ -851,9 +856,11 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(
// NOTE: This check is okay because the first texture formats are the same as the buffer formats.
if (entry.format != (GETextureFormat)framebuffer->format) {
WARN_LOG_ONCE(diffFormat1, G3D, "Texturing from framebuffer with different formats %s != %s", GeTextureFormatToString(entry.format), GeBufferFormatToString(framebuffer->format));
return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH };
} else {
return FramebufferMatchInfo{ FramebufferMatch::VALID };
} else {
// TODO: Here we should either change the format of the framebuffer, reinterpreting it,
// or read from it while reinterpreting it. Not sure which is generally best.
return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH };
}
} else {
// Apply to buffered mode only.
@@ -1007,6 +1014,7 @@ bool TextureCacheCommon::SetOffsetTexture(u32 yOffset) {
def.format = fmt;
def.bufw = GetTextureBufw(0, texaddr, fmt);
def.dim = gstate.getTextureDimension(0);
def.swizzled = gstate.isTextureSwizzled();
std::vector<AttachCandidate> candidates = GetFramebufferCandidates(def, texaddrOffset);
if (candidates.size() > 0) {
+1
View File
@@ -98,6 +98,7 @@ struct TextureDefinition {
GETextureFormat format;
u32 dim;
u32 bufw;
bool swizzled;
};
+8 -48
View File
@@ -26,12 +26,13 @@
#include "GPU/GPUState.h"
#include "GPU/Common/ShaderId.h"
#include "GPU/Common/ShaderUniforms.h"
#include "GPU/Common/ShaderWriter.h"
#include "GPU/Common/VertexDecoderCommon.h"
#include "GPU/Common/VertexShaderGenerator.h"
#undef WRITE
#define WRITE p+=sprintf
#define WRITE(p, ...) p.F(__VA_ARGS__)
static const char * const boneWeightAttrDecl[9] = {
"#ERROR#",
@@ -122,30 +123,8 @@ static const char * const boneWeightDecl[9] = {
"layout(location = 3) in vec4 w1;\nlayout(location = 4) in vec4 w2;\n",
};
const char *vulkan_glsl_preamble_vs =
"#version 450\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
"#extension GL_ARB_shading_language_420pack : enable\n"
"#define mul(x, y) ((x) * (y))\n"
"#define splat3(x) vec3(x)\n"
"#define lowp\n"
"#define mediump\n"
"#define highp\n"
"\n";
const char *hlsl_preamble_vs =
"#define vec2 float2\n"
"#define vec3 float3\n"
"#define vec4 float4\n"
"#define ivec2 int2\n"
"#define ivec4 int4\n"
"#define mat4 float4x4\n"
"#define mat3x4 float4x3\n" // note how the conventions are backwards
"#define splat3(x) vec3(x, x, x)\n"
"#define lowp\n"
"#define mediump\n"
"#define highp\n"
"\n";
extern const char *vulkan_glsl_preamble_vs;
extern const char *hlsl_preamble_vs;
bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguageDesc &compat, uint32_t *attrMask, uint64_t *uniformMask, std::string *errorString) {
*attrMask = 0;
@@ -154,32 +133,13 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
bool highpFog = false;
bool highpTexcoord = false;
char *p = buffer;
if (compat.shaderLanguage == GLSL_VULKAN) {
WRITE(p, "%s", vulkan_glsl_preamble_vs);
} else if (compat.shaderLanguage == HLSL_D3D11 || compat.shaderLanguage == HLSL_D3D9) {
WRITE(p, "%s", hlsl_preamble_vs);
} else if (ShaderLanguageIsOpenGL(compat.shaderLanguage)) {
if (compat.gles) {
// PowerVR needs highp to do the fog in MHU correctly.
// Others don't, and some can't handle highp in the fragment shader.
highpFog = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_BAD) ? true : false;
highpTexcoord = highpFog;
}
WRITE(p, "#version %d%s\n", compat.glslVersionNumber, compat.gles && compat.glslES30 ? " es" : "");
std::vector<const char*> gl_exts;
if (ShaderLanguageIsOpenGL(compat.shaderLanguage)) {
if (gl_extensions.EXT_gpu_shader4) {
WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n");
gl_exts.push_back("#extension GL_EXT_gpu_shader4 : enable");
}
if (compat.gles) {
WRITE(p, "precision highp float;\n");
} else {
WRITE(p, "#define lowp\n");
WRITE(p, "#define mediump\n");
WRITE(p, "#define highp\n");
}
WRITE(p, "#define splat3(x) vec3(x)\n");
WRITE(p, "#define mul(x, y) ((x) * (y))\n");
}
ShaderWriter p(buffer, compat, ShaderStage::Vertex, gl_exts.data(), gl_exts.size());
bool isModeThrough = id.Bit(VS_BIT_IS_THROUGH);
bool lmode = id.Bit(VS_BIT_LMODE);
+1
View File
@@ -496,6 +496,7 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {
// Don't scale the PPGe texture.
if (entry->addr > 0x05000000 && entry->addr < PSP_GetKernelMemoryEnd())
scaleFactor = 1;
if ((entry->status & TexCacheEntry::STATUS_CHANGE_FREQUENT) != 0 && scaleFactor != 1) {
// Remember for later that we /wanted/ to scale this texture.
entry->status |= TexCacheEntry::STATUS_TO_SCALE;
+7 -6
View File
@@ -492,9 +492,6 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) {
}
}
// If GLES3 is available, we can preallocate the storage, which makes texture loading more efficient.
Draw::DataFormat dstFmt = GetDestFormat(GETextureFormat(entry->format), gstate.getClutPaletteFormat());
int scaleFactor = standardScaleFactor_;
// Rachet down scale factor in low-memory mode.
@@ -535,7 +532,10 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) {
texelsScaledThisFrame_ += w * h;
}
}
// If GLES3 is available, we can preallocate the storage, which makes texture loading more efficient.
Draw::DataFormat dstFmt = GetDestFormat(GETextureFormat(entry->format), gstate.getClutPaletteFormat());
// GLES2 doesn't have support for a "Max lod" which is critical as PSP games often
// don't specify mips all the way down. As a result, we either need to manually generate
// the bottom few levels or rely on OpenGL's autogen mipmaps instead, which might not
@@ -546,10 +546,11 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) {
// NOTE: Since the level is not part of the cache key, we assume it never changes.
u8 level = std::max(0, gstate.getTexLevelOffset16() / 16);
LoadTextureLevel(*entry, replaced, level, scaleFactor, dstFmt);
} else
} else {
LoadTextureLevel(*entry, replaced, 0, scaleFactor, dstFmt);
}
// Mipmapping only enable when texture scaling disable
// Mipmapping is only enabled when texture scaling is disabled.
int texMaxLevel = 0;
bool genMips = false;
if (maxLevel > 0 && scaleFactor == 1) {
+2
View File
@@ -351,6 +351,7 @@
<ClInclude Include="Common\ShaderId.h" />
<ClInclude Include="Common\ShaderTranslation.h" />
<ClInclude Include="Common\ShaderUniforms.h" />
<ClInclude Include="Common\ShaderWriter.h" />
<ClInclude Include="Common\SoftwareTransformCommon.h" />
<ClInclude Include="Common\SplineCommon.h" />
<ClInclude Include="Common\StencilCommon.h" />
@@ -488,6 +489,7 @@
<ClCompile Include="Common\ShaderId.cpp" />
<ClCompile Include="Common\ShaderTranslation.cpp" />
<ClCompile Include="Common\ShaderUniforms.cpp" />
<ClCompile Include="Common\ShaderWriter.cpp" />
<ClCompile Include="Common\SplineCommon.cpp" />
<ClCompile Include="Common\StencilCommon.cpp" />
<ClCompile Include="Common\TextureDecoderNEON.cpp">
+6
View File
@@ -270,6 +270,9 @@
<ClInclude Include="Common\VertexShaderGenerator.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\ShaderWriter.h">
<Filter>Common</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Math3D.cpp">
@@ -539,5 +542,8 @@
<ClCompile Include="Common\VertexShaderGenerator.cpp">
<Filter>Common</Filter>
</ClCompile>
<ClCompile Include="Common\ShaderWriter.cpp">
<Filter>Common</Filter>
</ClCompile>
</ItemGroup>
</Project>
+2
View File
@@ -392,6 +392,7 @@
<ClInclude Include="..\..\GPU\Common\ShaderId.h" />
<ClInclude Include="..\..\GPU\Common\ShaderTranslation.h" />
<ClInclude Include="..\..\GPU\Common\ShaderUniforms.h" />
<ClInclude Include="..\..\GPU\Common\ShaderWriter.h" />
<ClInclude Include="..\..\GPU\Common\SoftwareLighting.h" />
<ClInclude Include="..\..\GPU\Common\SoftwareTransformCommon.h" />
<ClInclude Include="..\..\GPU\Common\SplineCommon.h" />
@@ -449,6 +450,7 @@
<ClCompile Include="..\..\GPU\Common\ShaderId.cpp" />
<ClCompile Include="..\..\GPU\Common\ShaderTranslation.cpp" />
<ClCompile Include="..\..\GPU\Common\ShaderUniforms.cpp" />
<ClCompile Include="..\..\GPU\Common\ShaderWriter.cpp" />
<ClCompile Include="..\..\GPU\Common\SoftwareTransformCommon.cpp" />
<ClCompile Include="..\..\GPU\Common\SplineCommon.cpp" />
<ClCompile Include="..\..\GPU\Common\StencilCommon.cpp" />
+2
View File
@@ -57,6 +57,7 @@
<ClCompile Include="..\..\GPU\Software\RasterizerRectangle.cpp" />
<ClCompile Include="..\..\GPU\Common\FragmentShaderGenerator.cpp" />
<ClCompile Include="..\..\GPU\Common\VertexShaderGenerator.cpp" />
<ClCompile Include="..\..\GPU\Common\ShaderWriter.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\GPU\Common\DepalettizeShaderCommon.h" />
@@ -114,5 +115,6 @@
<ClInclude Include="..\..\GPU\Software\RasterizerRectangle.h" />
<ClInclude Include="..\..\GPU\Common\FragmentShaderGenerator.h" />
<ClInclude Include="..\..\GPU\Common\VertexShaderGenerator.h" />
<ClInclude Include="..\..\GPU\Common\ShaderWriter.h" />
</ItemGroup>
</Project>
+39 -29
View File
@@ -21,6 +21,7 @@
#include <vector>
#include "Common/Data/Text/Parsers.h"
#include "Common/Data/Encoding/Utf8.h"
#include "Common/ColorConv.h"
#include "Common/StringUtils.h"
#include "Core/Config.h"
@@ -274,10 +275,10 @@ void CGEDebugger::SetupPreviews() {
}
}
void CGEDebugger::DescribePrimaryPreview(const GPUgstate &state, wchar_t desc[256]) {
void CGEDebugger::DescribePrimaryPreview(const GPUgstate &state, char desc[256]) {
if (showClut_) {
// In this case, we're showing the texture here.
_snwprintf(desc, 256, L"Texture L%d: 0x%08x (%dx%d)", textureLevel_, state.getTextureAddress(textureLevel_), state.getTextureWidth(textureLevel_), state.getTextureHeight(textureLevel_));
snprintf(desc, 256, "Texture L%d: 0x%08x (%dx%d)", textureLevel_, state.getTextureAddress(textureLevel_), state.getTextureWidth(textureLevel_), state.getTextureHeight(textureLevel_));
return;
}
@@ -285,24 +286,24 @@ void CGEDebugger::DescribePrimaryPreview(const GPUgstate &state, wchar_t desc[25
switch (PrimaryDisplayType(fbTabs->CurrentTabIndex())) {
case PRIMARY_FRAMEBUF:
_snwprintf(desc, 256, L"Color: 0x%08x (%dx%d) fmt %i", state.getFrameBufRawAddress(), primaryBuffer_->GetStride(), primaryBuffer_->GetHeight(), state.FrameBufFormat());
snprintf(desc, 256, "Color: 0x%08x (%dx%d) fmt %s", state.getFrameBufRawAddress(), primaryBuffer_->GetStride(), primaryBuffer_->GetHeight(), GeBufferFormatToString(state.FrameBufFormat()));
break;
case PRIMARY_DEPTHBUF:
_snwprintf(desc, 256, L"Depth: 0x%08x (%dx%d)", state.getDepthBufRawAddress(), primaryBuffer_->GetStride(), primaryBuffer_->GetHeight());
snprintf(desc, 256, "Depth: 0x%08x (%dx%d)", state.getDepthBufRawAddress(), primaryBuffer_->GetStride(), primaryBuffer_->GetHeight());
break;
case PRIMARY_STENCILBUF:
_snwprintf(desc, 256, L"Stencil: 0x%08x (%dx%d)", state.getFrameBufRawAddress(), primaryBuffer_->GetStride(), primaryBuffer_->GetHeight());
snprintf(desc, 256, "Stencil: 0x%08x (%dx%d)", state.getFrameBufRawAddress(), primaryBuffer_->GetStride(), primaryBuffer_->GetHeight());
break;
}
}
void CGEDebugger::DescribeSecondPreview(const GPUgstate &state, wchar_t desc[256]) {
void CGEDebugger::DescribeSecondPreview(const GPUgstate &state, char desc[256]) {
if (showClut_) {
_snwprintf(desc, 256, L"CLUT: 0x%08x (%d)", state.getClutAddress(), state.getClutPaletteFormat());
snprintf(desc, 256, "CLUT: 0x%08x (%d)", state.getClutAddress(), state.getClutPaletteFormat());
} else {
_snwprintf(desc, 256, L"Texture L%d: 0x%08x (%dx%d)", textureLevel_, state.getTextureAddress(textureLevel_), state.getTextureWidth(textureLevel_), state.getTextureHeight(textureLevel_));
snprintf(desc, 256, "Texture L%d: 0x%08x (%dx%d)", textureLevel_, state.getTextureAddress(textureLevel_), state.getTextureWidth(textureLevel_), state.getTextureHeight(textureLevel_));
}
}
@@ -414,9 +415,12 @@ void CGEDebugger::UpdatePrimaryPreview(const GPUgstate &state) {
primaryWindow->SetFlags(flags);
primaryWindow->Draw(primaryBuffer_->GetData(), primaryBuffer_->GetStride(), primaryBuffer_->GetHeight(), primaryBuffer_->GetFlipped(), fmt);
wchar_t desc[256];
char desc[256];
wchar_t w_desc[256];
DescribePrimaryPreview(state, desc);
SetDlgItemText(m_hDlg, IDC_GEDBG_FRAMEBUFADDR, desc);
ConvertUTF8ToWString(w_desc, ARRAY_SIZE(w_desc), desc);
SetDlgItemText(m_hDlg, IDC_GEDBG_FRAMEBUFADDR, w_desc);
} else if (primaryWindow != nullptr) {
primaryWindow->Clear();
primaryBuffer_ = nullptr;
@@ -452,9 +456,11 @@ void CGEDebugger::UpdateSecondPreview(const GPUgstate &state) {
secondWindow->Draw(secondBuffer_->GetData(), secondBuffer_->GetStride(), secondBuffer_->GetHeight(), secondBuffer_->GetFlipped(), fmt);
}
wchar_t desc[256];
char desc[256];
DescribeSecondPreview(state, desc);
SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, desc);
wchar_t w_desc[256];
ConvertUTF8ToWString(w_desc, ARRAY_SIZE(w_desc), desc);
SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, w_desc);
} else if (secondWindow != nullptr) {
secondWindow->Clear();
secondBuffer_ = nullptr;
@@ -474,7 +480,7 @@ void CGEDebugger::PrimaryPreviewHover(int x, int y) {
SetupPreviews();
wchar_t desc[256] = {0};
char desc[256] = {0};
if (!primaryWindow->HasTex()) {
desc[0] = 0;
@@ -491,7 +497,10 @@ void CGEDebugger::PrimaryPreviewHover(int x, int y) {
DescribePixel(pix, primaryBuffer_->GetFormat(), x, y, desc);
}
SetDlgItemText(m_hDlg, IDC_GEDBG_FRAMEBUFADDR, desc);
wchar_t w_desc[256];
ConvertUTF8ToWString(w_desc, ARRAY_SIZE(w_desc), desc);
SetDlgItemText(m_hDlg, IDC_GEDBG_FRAMEBUFADDR, w_desc);
}
void CGEDebugger::SecondPreviewHover(int x, int y) {
@@ -499,7 +508,7 @@ void CGEDebugger::SecondPreviewHover(int x, int y) {
return;
}
wchar_t desc[256] = {0};
char desc[256] = {0};
if (!secondWindow->HasTex()) {
desc[0] = 0;
@@ -519,11 +528,12 @@ void CGEDebugger::SecondPreviewHover(int x, int y) {
DescribePixel(pix, secondBuffer_->GetFormat(), x, y, desc);
}
}
SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, desc);
wchar_t w_desc[256];
ConvertUTF8ToWString(w_desc, ARRAY_SIZE(w_desc), desc);
SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, w_desc);
}
void CGEDebugger::DescribePixel(u32 pix, GPUDebugBufferFormat fmt, int x, int y, wchar_t desc[256]) {
void CGEDebugger::DescribePixel(u32 pix, GPUDebugBufferFormat fmt, int x, int y, char desc[256]) {
switch (fmt) {
case GPU_DBG_FORMAT_565:
case GPU_DBG_FORMAT_565_REV:
@@ -539,18 +549,18 @@ void CGEDebugger::DescribePixel(u32 pix, GPUDebugBufferFormat fmt, int x, int y,
break;
case GPU_DBG_FORMAT_16BIT:
_snwprintf(desc, 256, L"%d,%d: %d / %f", x, y, pix, pix * (1.0f / 65535.0f));
snprintf(desc, 256, "%d,%d: %d / %f", x, y, pix, pix * (1.0f / 65535.0f));
break;
case GPU_DBG_FORMAT_8BIT:
_snwprintf(desc, 256, L"%d,%d: %d / %f", x, y, pix, pix * (1.0f / 255.0f));
snprintf(desc, 256, "%d,%d: %d / %f", x, y, pix, pix * (1.0f / 255.0f));
break;
case GPU_DBG_FORMAT_24BIT_8X:
{
DepthScaleFactors depthScale = GetDepthScaleFactors();
// These are only ever going to be depth values, so let's also show scaled to 16 bit.
_snwprintf(desc, 256, L"%d,%d: %d / %f / %f", x, y, pix & 0x00FFFFFF, (pix & 0x00FFFFFF) * (1.0f / 16777215.0f), depthScale.Apply((pix & 0x00FFFFFF) * (1.0f / 16777215.0f)));
snprintf(desc, 256, "%d,%d: %d / %f / %f", x, y, pix & 0x00FFFFFF, (pix & 0x00FFFFFF) * (1.0f / 16777215.0f), depthScale.Apply((pix & 0x00FFFFFF) * (1.0f / 16777215.0f)));
break;
}
@@ -559,18 +569,18 @@ void CGEDebugger::DescribePixel(u32 pix, GPUDebugBufferFormat fmt, int x, int y,
// These are only ever going to be depth values, so let's also show scaled to 16 bit.
int z24 = pix & 0x00FFFFFF;
int z16 = z24 - 0x800000 + 0x8000;
_snwprintf(desc, 256, L"%d,%d: %d / %f", x, y, z16, z16 * (1.0f / 65535.0f));
snprintf(desc, 256, "%d,%d: %d / %f", x, y, z16, z16 * (1.0f / 65535.0f));
}
break;
case GPU_DBG_FORMAT_24X_8BIT:
_snwprintf(desc, 256, L"%d,%d: %d / %f", x, y, (pix >> 24) & 0xFF, ((pix >> 24) & 0xFF) * (1.0f / 255.0f));
snprintf(desc, 256, "%d,%d: %d / %f", x, y, (pix >> 24) & 0xFF, ((pix >> 24) & 0xFF) * (1.0f / 255.0f));
break;
case GPU_DBG_FORMAT_FLOAT: {
float pixf = *(float *)&pix;
DepthScaleFactors depthScale = GetDepthScaleFactors();
_snwprintf(desc, 256, L"%d,%d: %f / %f", x, y, pixf, depthScale.Apply(pixf));
snprintf(desc, 256, "%d,%d: %f / %f", x, y, pixf, depthScale.Apply(pixf));
break;
}
@@ -585,16 +595,16 @@ void CGEDebugger::DescribePixel(u32 pix, GPUDebugBufferFormat fmt, int x, int y,
int z16_2 = factors.Apply(z);
_snwprintf(desc, 256, L"%d,%d: %d / %f", x, y, z16, (z - 0.5 + (1.0 / 512.0)) * 256.0);
snprintf(desc, 256, "%d,%d: %d / %f", x, y, z16, (z - 0.5 + (1.0 / 512.0)) * 256.0);
}
break;
default:
_snwprintf(desc, 256, L"Unexpected format");
snprintf(desc, 256, "Unexpected format");
}
}
void CGEDebugger::DescribePixelRGBA(u32 pix, GPUDebugBufferFormat fmt, int x, int y, wchar_t desc[256]) {
void CGEDebugger::DescribePixelRGBA(u32 pix, GPUDebugBufferFormat fmt, int x, int y, char desc[256]) {
u32 r = -1, g = -1, b = -1, a = -1;
switch (fmt) {
@@ -658,11 +668,11 @@ void CGEDebugger::DescribePixelRGBA(u32 pix, GPUDebugBufferFormat fmt, int x, in
break;
default:
_snwprintf(desc, 256, L"Unexpected format");
snprintf(desc, 256, "Unexpected format");
return;
}
_snwprintf(desc, 256, L"%d,%d: r=%d, g=%d, b=%d, a=%d", x, y, r, g, b, a);
snprintf(desc, 256, "%d,%d: r=%d, g=%d, b=%d, a=%d", x, y, r, g, b, a);
}
void CGEDebugger::UpdateTextureLevel(int level) {
+4 -4
View File
@@ -76,13 +76,13 @@ private:
void UpdateSize(WORD width, WORD height);
void SavePosition();
void UpdateTextureLevel(int level);
void DescribePrimaryPreview(const GPUgstate &state, wchar_t desc[256]);
void DescribeSecondPreview(const GPUgstate &state, wchar_t desc[256]);
void DescribePrimaryPreview(const GPUgstate &state, char desc[256]);
void DescribeSecondPreview(const GPUgstate &state, char desc[256]);
void PrimaryPreviewHover(int x, int y);
void SecondPreviewHover(int x, int y);
void PreviewExport(const GPUDebugBuffer *buffer);
void DescribePixel(u32 pix, GPUDebugBufferFormat fmt, int x, int y, wchar_t desc[256]);
void DescribePixelRGBA(u32 pix, GPUDebugBufferFormat fmt, int x, int y, wchar_t desc[256]);
void DescribePixel(u32 pix, GPUDebugBufferFormat fmt, int x, int y, char desc[256]);
void DescribePixelRGBA(u32 pix, GPUDebugBufferFormat fmt, int x, int y, char desc[256]);
u32 TexturePreviewFlags(const GPUgstate &state);
+1
View File
@@ -318,6 +318,7 @@ EXEC_AND_LIB_FILES := \
$(SRC)/GPU/Common/TextureCacheCommon.cpp.arm \
$(SRC)/GPU/Common/TextureScalerCommon.cpp.arm \
$(SRC)/GPU/Common/ShaderCommon.cpp \
$(SRC)/GPU/Common/ShaderWriter.cpp \
$(SRC)/GPU/Common/ShaderTranslation.cpp \
$(SRC)/GPU/Common/StencilCommon.cpp \
$(SRC)/GPU/Common/SplineCommon.cpp.arm \
+1
View File
@@ -236,6 +236,7 @@ SOURCES_CXX += \
$(GPUCOMMONDIR)/ShaderCommon.cpp \
$(GPUCOMMONDIR)/ShaderUniforms.cpp \
$(GPUCOMMONDIR)/ShaderTranslation.cpp \
$(GPUCOMMONDIR)/ShaderWriter.cpp \
$(GPUCOMMONDIR)/GPUDebugInterface.cpp \
$(GPUCOMMONDIR)/DepalettizeShaderCommon.cpp \
$(GPUCOMMONDIR)/TransformCommon.cpp \