Merge pull request #13629 from hrydgard/move-shader-lang-detect

Move the shader language feature detection to the draw context
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2020-11-06 11:09:14 +01:00
commit 9d7651e106
25 files changed
+322 -297

No files matched your search

+2 -2
View File
@@ -729,10 +729,10 @@
<ClCompile Include="Render\Text\draw_text_win.cpp">
<Filter>Render\Text</Filter>
</ClCompile>
<ClCompile Include="GPU\Shader.cpp">
<ClCompile Include="GPU\ShaderWriter.cpp">
<Filter>GPU</Filter>
</ClCompile>
<ClCompile Include="GPU\ShaderWriter.cpp">
<ClCompile Include="GPU\Shader.cpp">
<Filter>GPU</Filter>
</ClCompile>
</ItemGroup>
+20 -19
View File
@@ -294,6 +294,8 @@ D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *de
packDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
hr = device_->CreateTexture2D(&packDesc, nullptr, &packTexture_);
_assert_(SUCCEEDED(hr));
shaderLanguageDesc_.Init(HLSL_D3D11);
}
D3D11DrawContext::~D3D11DrawContext() {
@@ -1205,7 +1207,10 @@ uint32_t D3D11DrawContext::GetDataFormatSupport(DataFormat fmt) const {
// A D3D11Framebuffer is a D3D11Framebuffer plus all the textures it owns.
class D3D11Framebuffer : public Framebuffer {
public:
D3D11Framebuffer() {}
D3D11Framebuffer(int width, int height) {
width_ = width;
height_ = height;
}
~D3D11Framebuffer() {
if (colorTex)
colorTex->Release();
@@ -1220,8 +1225,6 @@ public:
if (depthStencilRTView)
depthStencilRTView->Release();
}
int width;
int height;
ID3D11Texture2D *colorTex = nullptr;
ID3D11RenderTargetView *colorRTView = nullptr;
@@ -1236,9 +1239,7 @@ public:
Framebuffer *D3D11DrawContext::CreateFramebuffer(const FramebufferDesc &desc) {
HRESULT hr;
D3D11Framebuffer *fb = new D3D11Framebuffer();
fb->width = desc.width;
fb->height = desc.height;
D3D11Framebuffer *fb = new D3D11Framebuffer(desc.width, desc.height);
if (desc.numColorAttachments) {
fb->colorFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
D3D11_TEXTURE2D_DESC descColor{};
@@ -1396,7 +1397,7 @@ void D3D11DrawContext::CopyFramebufferImage(Framebuffer *srcfb, int level, int x
}
// TODO: Check for level too!
if (width == src->width && width == dst->width && height == src->height && height == dst->height && x == 0 && y == 0 && z == 0 && dstX == 0 && dstY == 0 && dstZ == 0) {
if (width == src->Width() && width == dst->Width() && height == src->Height() && height == dst->Height() && x == 0 && y == 0 && z == 0 && dstX == 0 && dstY == 0 && dstZ == 0) {
// Don't need to specify region. This might be faster, too.
context_->CopyResource(dstTex, srcTex);
return;
@@ -1415,11 +1416,11 @@ void D3D11DrawContext::CopyFramebufferImage(Framebuffer *srcfb, int level, int x
dstY -= y;
y = 0;
}
if (x + width > src->width) {
width = src->width - x;
if (x + width > src->Width()) {
width = src->Width() - x;
}
if (y + height > src->height) {
height = src->height - y;
if (y + height > src->Height()) {
height = src->Height() - y;
}
D3D11_BOX srcBox{ (UINT)x, (UINT)y, (UINT)z, (UINT)(x + width), (UINT)(y + height), (UINT)(z + depth) };
context_->CopySubresourceRegion(dstTex, dstLevel, dstX, dstY, dstZ, srcTex, level, &srcBox);
@@ -1441,11 +1442,11 @@ bool D3D11DrawContext::CopyFramebufferToMemorySync(Framebuffer *src, int channel
_assert_(fb->colorFormat == DXGI_FORMAT_R8G8B8A8_UNORM);
// TODO: Figure out where the badness really comes from.
if (bx + bw > fb->width) {
bw -= (bx + bw) - fb->width;
if (bx + bw > fb->Width()) {
bw -= (bx + bw) - fb->Width();
}
if (by + bh > fb->height) {
bh -= (by + bh) - fb->height;
if (by + bh > fb->Height()) {
bh -= (by + bh) - fb->Height();
}
}
@@ -1565,8 +1566,8 @@ void D3D11DrawContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Ren
context_->OMSetRenderTargets(1, &fb->colorRTView, fb->depthStencilRTView);
curRenderTargetView_ = fb->colorRTView;
curDepthStencilView_ = fb->depthStencilRTView;
curRTWidth_ = fb->width;
curRTHeight_ = fb->height;
curRTWidth_ = fb->Width();
curRTHeight_ = fb->Height();
}
} else {
if (curRenderTargetView_ == bbRenderTargetView_ && curDepthStencilView_ == bbDepthStencilView_) {
@@ -1634,8 +1635,8 @@ uintptr_t D3D11DrawContext::GetFramebufferAPITexture(Framebuffer *fbo, int chann
void D3D11DrawContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) {
D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo;
if (fb) {
*w = fb->width;
*h = fb->height;
*w = fb->Width();
*h = fb->Height();
} else {
*w = bbWidth_;
*h = bbHeight_;
+17 -15
View File
@@ -670,6 +670,8 @@ D3D9Context::D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, ID
HRESULT fboINTZ = d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_INTZ);
supportsINTZ = SUCCEEDED(displayINTZ) && SUCCEEDED(fboINTZ);
}
shaderLanguageDesc_.Init(HLSL_D3D9);
}
D3D9Context::~D3D9Context() {
@@ -1072,26 +1074,26 @@ bool D3D9ShaderModule::Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, si
class D3D9Framebuffer : public Framebuffer {
public:
D3D9Framebuffer(int width, int height) {
width_ = width;
height_ = height;
}
~D3D9Framebuffer();
uint32_t id;
LPDIRECT3DSURFACE9 surf;
LPDIRECT3DSURFACE9 depthstencil;
LPDIRECT3DTEXTURE9 tex;
LPDIRECT3DTEXTURE9 depthstenciltex;
int width;
int height;
uint32_t id = 0;
LPDIRECT3DSURFACE9 surf = nullptr;
LPDIRECT3DSURFACE9 depthstencil = nullptr;
LPDIRECT3DTEXTURE9 tex = nullptr;
LPDIRECT3DTEXTURE9 depthstenciltex = nullptr;
};
Framebuffer *D3D9Context::CreateFramebuffer(const FramebufferDesc &desc) {
static uint32_t id = 0;
D3D9Framebuffer *fbo = new D3D9Framebuffer{};
fbo->width = desc.width;
fbo->height = desc.height;
D3D9Framebuffer *fbo = new D3D9Framebuffer(desc.width, desc.height);
fbo->depthstenciltex = nullptr;
HRESULT rtResult = device_->CreateTexture(fbo->width, fbo->height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &fbo->tex, NULL);
HRESULT rtResult = device_->CreateTexture(desc.width, desc.height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &fbo->tex, NULL);
if (FAILED(rtResult)) {
ERROR_LOG(G3D, "Failed to create render target");
delete fbo;
@@ -1101,12 +1103,12 @@ Framebuffer *D3D9Context::CreateFramebuffer(const FramebufferDesc &desc) {
HRESULT dsResult;
if (supportsINTZ) {
dsResult = device_->CreateTexture(fbo->width, fbo->height, 1, D3DUSAGE_DEPTHSTENCIL, FOURCC_INTZ, D3DPOOL_DEFAULT, &fbo->depthstenciltex, NULL);
dsResult = device_->CreateTexture(desc.width, desc.height, 1, D3DUSAGE_DEPTHSTENCIL, FOURCC_INTZ, D3DPOOL_DEFAULT, &fbo->depthstenciltex, NULL);
if (SUCCEEDED(dsResult)) {
dsResult = fbo->depthstenciltex->GetSurfaceLevel(0, &fbo->depthstencil);
}
} else {
dsResult = device_->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL);
dsResult = device_->CreateDepthStencilSurface(desc.width, desc.height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL);
}
if (FAILED(dsResult)) {
ERROR_LOG(G3D, "Failed to create depth buffer");
@@ -1208,8 +1210,8 @@ void D3D9Context::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChan
void D3D9Context::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) {
D3D9Framebuffer *fb = (D3D9Framebuffer *)fbo;
if (fb) {
*w = fb->width;
*h = fb->height;
*w = fb->Width();
*h = fb->Height();
} else {
*w = targetWidth_;
*h = targetHeight_;
+88 -12
View File
@@ -350,6 +350,7 @@ public:
return (uint32_t)ShaderLanguage::GLSL_1xx;
}
}
uint32_t GetDataFormatSupport(DataFormat fmt) const override;
void SetErrorCallback(ErrorCallbackFn callback, void *userdata) override {
@@ -601,6 +602,78 @@ OpenGLContext::OpenGLContext() {
// TODO: Should this workaround be removed for newer devices/drivers?
bugs_.Infest(Bugs::PVR_GENMIPMAP_HEIGHT_GREATER);
}
shaderLanguageDesc_.Init(GLSL_1xx);
// Detect shader language features.
if (gl_extensions.IsGLES) {
if (gl_extensions.GLES3) {
shaderLanguageDesc_.shaderLanguage = ShaderLanguage::GLSL_3xx;
shaderLanguageDesc_.glslVersionNumber = 300; // GLSL ES 3.0
shaderLanguageDesc_.fragColor0 = "fragColor0";
shaderLanguageDesc_.texture = "texture";
shaderLanguageDesc_.glslES30 = true;
shaderLanguageDesc_.bitwiseOps = true;
shaderLanguageDesc_.texelFetch = "texelFetch";
shaderLanguageDesc_.varying_vs = "out";
shaderLanguageDesc_.varying_fs = "in";
shaderLanguageDesc_.attribute = "in";
} else {
shaderLanguageDesc_.shaderLanguage = ShaderLanguage::GLSL_1xx;
shaderLanguageDesc_.glslVersionNumber = 100; // GLSL ES 1.0
if (gl_extensions.EXT_gpu_shader4) {
shaderLanguageDesc_.bitwiseOps = true;
shaderLanguageDesc_.texelFetch = "texelFetch2D";
}
if (gl_extensions.EXT_blend_func_extended) {
// Oldy moldy GLES, so use the fixed output name.
shaderLanguageDesc_.fragColor1 = "gl_SecondaryFragColorEXT";
}
}
} else {
if (!gl_extensions.ForceGL2 || gl_extensions.IsCoreContext) {
if (gl_extensions.VersionGEThan(3, 3, 0)) {
shaderLanguageDesc_.shaderLanguage = ShaderLanguage::GLSL_3xx;
shaderLanguageDesc_.glslVersionNumber = 330;
shaderLanguageDesc_.fragColor0 = "fragColor0";
shaderLanguageDesc_.texture = "texture";
shaderLanguageDesc_.glslES30 = true;
shaderLanguageDesc_.bitwiseOps = true;
shaderLanguageDesc_.texelFetch = "texelFetch";
shaderLanguageDesc_.varying_vs = "out";
shaderLanguageDesc_.varying_fs = "in";
shaderLanguageDesc_.attribute = "in";
} else if (gl_extensions.VersionGEThan(3, 0, 0)) {
shaderLanguageDesc_.shaderLanguage = ShaderLanguage::GLSL_1xx;
shaderLanguageDesc_.glslVersionNumber = 130;
shaderLanguageDesc_.fragColor0 = "fragColor0";
shaderLanguageDesc_.bitwiseOps = true;
shaderLanguageDesc_.texelFetch = "texelFetch";
} else {
shaderLanguageDesc_.shaderLanguage = ShaderLanguage::GLSL_1xx;
shaderLanguageDesc_.glslVersionNumber = 110;
if (gl_extensions.EXT_gpu_shader4) {
shaderLanguageDesc_.bitwiseOps = true;
shaderLanguageDesc_.texelFetch = "texelFetch2D";
}
}
}
}
if (gl_extensions.IsGLES && gl_extensions.GLES3) {
caps_.framebufferFetchSupported = (gl_extensions.EXT_shader_framebuffer_fetch || gl_extensions.NV_shader_framebuffer_fetch || gl_extensions.ARM_shader_framebuffer_fetch);
if (gl_extensions.EXT_shader_framebuffer_fetch) {
shaderLanguageDesc_.framebufferFetchExtension = "#extension GL_EXT_shader_framebuffer_fetch : require";
shaderLanguageDesc_.lastFragData = "gl_LastFragData[0]";
} else if (gl_extensions.NV_shader_framebuffer_fetch) {
// GL_NV_shader_framebuffer_fetch is available on mobile platform and ES 2.0 only but not on desktop.
shaderLanguageDesc_.framebufferFetchExtension = "#extension GL_NV_shader_framebuffer_fetch : require";
shaderLanguageDesc_.lastFragData = "gl_LastFragData[0]";
} else if (gl_extensions.ARM_shader_framebuffer_fetch) {
shaderLanguageDesc_.framebufferFetchExtension = "#extension GL_ARM_shader_framebuffer_fetch : require";
shaderLanguageDesc_.lastFragData = "gl_LastFragColorARM";
}
}
}
OpenGLContext::~OpenGLContext() {
@@ -735,13 +808,16 @@ OpenGLTexture::~OpenGLTexture() {
class OpenGLFramebuffer : public Framebuffer {
public:
OpenGLFramebuffer(GLRenderManager *render) : render_(render) {}
OpenGLFramebuffer(GLRenderManager *render, GLRFramebuffer *framebuffer) : render_(render), framebuffer_(framebuffer) {
width_ = framebuffer->width;
height_ = framebuffer->height;
}
~OpenGLFramebuffer() {
render_->DeleteFramebuffer(framebuffer);
render_->DeleteFramebuffer(framebuffer_);
}
GLRenderManager *render_;
GLRFramebuffer *framebuffer = nullptr;
GLRFramebuffer *framebuffer_ = nullptr;
};
// TODO: SSE/NEON optimize, and move to ColorConv.cpp.
@@ -843,7 +919,7 @@ bool OpenGLContext::CopyFramebufferToMemorySync(Framebuffer *src, int channelBit
aspect |= GL_DEPTH_BUFFER_BIT;
if (channelBits & FB_STENCIL_BIT)
aspect |= GL_STENCIL_BUFFER_BIT;
renderManager_.CopyFramebufferToMemorySync(fb ? fb->framebuffer : nullptr, aspect, x, y, w, h, dataFormat, (uint8_t *)pixels, pixelStride, tag);
renderManager_.CopyFramebufferToMemorySync(fb ? fb->framebuffer_ : nullptr, aspect, x, y, w, h, dataFormat, (uint8_t *)pixels, pixelStride, tag);
return true;
}
@@ -1239,8 +1315,8 @@ void OpenGLInputLayout::Compile(const InputLayoutDesc &desc) {
Framebuffer *OpenGLContext::CreateFramebuffer(const FramebufferDesc &desc) {
CheckGLExtensions();
OpenGLFramebuffer *fbo = new OpenGLFramebuffer(&renderManager_);
fbo->framebuffer = renderManager_.CreateFramebuffer(desc.width, desc.height, desc.z_stencil);
GLRFramebuffer *framebuffer = renderManager_.CreateFramebuffer(desc.width, desc.height, desc.z_stencil);
OpenGLFramebuffer *fbo = new OpenGLFramebuffer(&renderManager_, framebuffer);
return fbo;
}
@@ -1250,7 +1326,7 @@ void OpenGLContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Render
GLRRenderPassAction depth = (GLRRenderPassAction)rp.depth;
GLRRenderPassAction stencil = (GLRRenderPassAction)rp.stencil;
renderManager_.BindFramebufferAsRenderTarget(fb ? fb->framebuffer : nullptr, color, depth, stencil, rp.clearColor, rp.clearDepth, rp.clearStencil, tag);
renderManager_.BindFramebufferAsRenderTarget(fb ? fb->framebuffer_ : nullptr, color, depth, stencil, rp.clearColor, rp.clearDepth, rp.clearStencil, tag);
}
void OpenGLContext::CopyFramebufferImage(Framebuffer *fbsrc, int srcLevel, int srcX, int srcY, int srcZ, Framebuffer *fbdst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) {
@@ -1266,7 +1342,7 @@ void OpenGLContext::CopyFramebufferImage(Framebuffer *fbsrc, int srcLevel, int s
if (channelBits & FB_STENCIL_BIT)
aspect |= GL_STENCIL_BUFFER_BIT;
}
renderManager_.CopyFramebuffer(src->framebuffer, GLRect2D{ srcX, srcY, width, height }, dst->framebuffer, GLOffset2D{ dstX, dstY }, aspect, tag);
renderManager_.CopyFramebuffer(src->framebuffer_, GLRect2D{ srcX, srcY, width, height }, dst->framebuffer_, GLOffset2D{ dstX, dstY }, aspect, tag);
}
bool OpenGLContext::BlitFramebuffer(Framebuffer *fbsrc, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *fbdst, int dstX1, int dstY1, int dstX2, int dstY2, int channels, FBBlitFilter linearFilter, const char *tag) {
@@ -1280,7 +1356,7 @@ bool OpenGLContext::BlitFramebuffer(Framebuffer *fbsrc, int srcX1, int srcY1, in
if (channels & FB_STENCIL_BIT)
aspect |= GL_STENCIL_BUFFER_BIT;
renderManager_.BlitFramebuffer(src->framebuffer, GLRect2D{ srcX1, srcY1, srcX2 - srcX1, srcY2 - srcY1 }, dst->framebuffer, GLRect2D{ dstX1, dstY1, dstX2 - dstX1, dstY2 - dstY1 }, aspect, linearFilter == FB_BLIT_LINEAR, tag);
renderManager_.BlitFramebuffer(src->framebuffer_, GLRect2D{ srcX1, srcY1, srcX2 - srcX1, srcY2 - srcY1 }, dst->framebuffer_, GLRect2D{ dstX1, dstY1, dstX2 - dstX1, dstY2 - dstY1 }, aspect, linearFilter == FB_BLIT_LINEAR, tag);
return true;
}
@@ -1294,14 +1370,14 @@ void OpenGLContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBCh
aspect |= GL_DEPTH_BUFFER_BIT;
if (channelBit & FB_STENCIL_BIT)
aspect |= GL_STENCIL_BUFFER_BIT;
renderManager_.BindFramebufferAsTexture(fb->framebuffer, binding, aspect, color);
renderManager_.BindFramebufferAsTexture(fb->framebuffer_, binding, aspect, color);
}
void OpenGLContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) {
OpenGLFramebuffer *fb = (OpenGLFramebuffer *)fbo;
if (fb) {
*w = fb->framebuffer->width;
*h = fb->framebuffer->height;
*w = fb->Width();
*h = fb->Height();
} else {
*w = targetWidth_;
*h = targetHeight_;
+80
View File
@@ -1 +1,81 @@
#include "Common/GPU/Shader.h"
ShaderLanguageDesc::ShaderLanguageDesc(ShaderLanguage lang) {
Init(lang);
}
void ShaderLanguageDesc::Init(ShaderLanguage lang) {
shaderLanguage = lang;
switch (lang) {
case GLSL_1xx:
// Just used in the shader test, and as a basis for the others in DetectShaderLanguage.
glslVersionNumber = 110;
attribute = "attribute";
varying_vs = "varying";
varying_fs = "varying";
fragColor0 = "gl_FragColor";
fragColor1 = "fragColor1";
texture = "texture2D";
texelFetch = nullptr;
bitwiseOps = false;
lastFragData = nullptr;
gles = false;
forceMatrix4x4 = true;
break;
case GLSL_3xx:
// Just used in the shader test.
glslVersionNumber = 300; // GLSL ES 3.0
varying_vs = "out";
varying_fs = "in";
attribute = "in";
fragColor0 = "fragColor0";
fragColor1 = "fragColor1";
texture = "texture";
texelFetch = nullptr;
bitwiseOps = false;
lastFragData = nullptr;
gles = false;
forceMatrix4x4 = true;
glslES30 = true;
bitwiseOps = true;
texelFetch = "texelFetch";
break;
case GLSL_VULKAN:
fragColor0 = "fragColor0";
fragColor1 = "fragColor1";
varying_fs = "in";
varying_vs = "out";
attribute = "in";
bitwiseOps = true;
framebufferFetchExtension = nullptr;
gles = false;
glslES30 = true;
glslVersionNumber = 450;
lastFragData = nullptr;
texture = "texture";
texelFetch = "texelFetch";
forceMatrix4x4 = false;
coefsFromBuffers = true;
break;
case HLSL_D3D9:
case HLSL_D3D11:
fragColor0 = "outfragment.target";
fragColor1 = "outfragment.target1";
varying_fs = "in";
varying_vs = "out";
attribute = "in";
bitwiseOps = lang == HLSL_D3D11;
framebufferFetchExtension = nullptr;
gles = false;
glslES30 = true;
glslVersionNumber = 0;
lastFragData = nullptr;
texture = "texture";
texelFetch = "texelFetch";
forceMatrix4x4 = false;
coefsFromBuffers = true;
vsOutPrefix = "Out.";
break;
}
}
+3
View File
@@ -23,8 +23,11 @@ enum class ShaderStage {
};
struct ShaderLanguageDesc {
ShaderLanguageDesc() {}
explicit ShaderLanguageDesc(ShaderLanguage lang);
void Init(ShaderLanguage lang);
int glslVersionNumber = 0;
ShaderLanguage shaderLanguage;
bool gles = false;
+8 -4
View File
@@ -497,7 +497,6 @@ public:
void InvalidateCachedState() override;
private:
VulkanTexture *GetNullTexture();
VulkanContext *vulkan_ = nullptr;
@@ -760,6 +759,8 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const Textur
VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit)
: vulkan_(vulkan), caps_{}, renderManager_(vulkan) {
shaderLanguageDesc_.Init(GLSL_VULKAN);
caps_.anisoSupported = vulkan->GetDeviceFeatures().enabled.samplerAnisotropy != 0;
caps_.geometryShaderSupported = vulkan->GetDeviceFeatures().enabled.geometryShader != 0;
caps_.tesselationShaderSupported = vulkan->GetDeviceFeatures().enabled.tessellationShader != 0;
@@ -780,8 +781,7 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit)
case VULKAN_VENDOR_NVIDIA: caps_.vendor = GPUVendor::VENDOR_NVIDIA; break;
case VULKAN_VENDOR_QUALCOMM: caps_.vendor = GPUVendor::VENDOR_QUALCOMM; break;
case VULKAN_VENDOR_INTEL: caps_.vendor = GPUVendor::VENDOR_INTEL; break;
default:
caps_.vendor = GPUVendor::VENDOR_UNKNOWN;
default: caps_.vendor = GPUVendor::VENDOR_UNKNOWN; break;
}
if (caps_.vendor == GPUVendor::VENDOR_QUALCOMM) {
@@ -1448,7 +1448,11 @@ uint32_t VKContext::GetDataFormatSupport(DataFormat fmt) const {
// use this frame's init command buffer.
class VKFramebuffer : public Framebuffer {
public:
VKFramebuffer(VKRFramebuffer *fb) : buf_(fb) { _assert_msg_(fb, "Null fb in VKFramebuffer constructor"); }
VKFramebuffer(VKRFramebuffer *fb) : buf_(fb) {
_assert_msg_(fb, "Null fb in VKFramebuffer constructor");
width_ = fb->width;
height_ = fb->height;
}
~VKFramebuffer() {
_assert_msg_(buf_, "Null buf_ in VKFramebuffer - double delete?");
buf_->vulkan_->Delete().QueueCallback([](void *fb) {
+13 -1
View File
@@ -347,6 +347,10 @@ public:
class Framebuffer : public RefCountedObject {
public:
int Width() { return width_; }
int Height() { return height_; }
protected:
int width_ = -1, height_ = -1;
};
class Buffer : public RefCountedObject {
@@ -359,7 +363,7 @@ public:
int Height() { return height_; }
int Depth() { return depth_; }
protected:
int width_, height_, depth_;
int width_ = -1, height_ = -1, depth_ = -1;
};
struct BindingDesc {
@@ -496,6 +500,7 @@ struct DeviceCaps {
bool framebufferBlitSupported;
bool framebufferDepthCopySupported;
bool framebufferDepthBlitSupported;
bool framebufferFetchSupported;
std::string deviceName; // The device name to use when creating the thin3d context, to get the same one.
};
@@ -548,6 +553,11 @@ public:
virtual std::vector<std::string> GetExtensionList() const { return std::vector<std::string>(); }
virtual std::vector<std::string> GetDeviceList() const { return std::vector<std::string>(); }
// Describes the primary shader language that this implementation prefers.
const ShaderLanguageDesc &GetShaderLanguageDesc() {
return shaderLanguageDesc_;
}
virtual uint32_t GetSupportedShaderLanguages() const = 0;
virtual void SetErrorCallback(ErrorCallbackFn callback, void *userdata) {}
@@ -663,6 +673,8 @@ protected:
ShaderModule *vsPresets_[VS_MAX_PRESET];
ShaderModule *fsPresets_[FS_MAX_PRESET];
ShaderLanguageDesc shaderLanguageDesc_;
int targetWidth_;
int targetHeight_;
+3 -2
View File
@@ -66,11 +66,12 @@ struct CoreParameter {
std::string *collectEmuLog = nullptr;
bool headLess; // Try to avoid messageboxes etc
// Internal PSP resolution
// Internal PSP rendering resolution and scale factor.
int renderScaleFactor;
int renderWidth;
int renderHeight;
// Actual pixel output resolution (for use by glViewport and the like)
// Actual output resolution in pixels.
int pixelWidth;
int pixelHeight;
+41 -45
View File
@@ -77,6 +77,7 @@ bool FramebufferManagerCommon::UpdateSize() {
renderWidth_ = (float)PSP_CoreParameter().renderWidth;
renderHeight_ = (float)PSP_CoreParameter().renderHeight;
renderScaleFactor_ = (float)PSP_CoreParameter().renderScaleFactor;
pixelWidth_ = PSP_CoreParameter().pixelWidth;
pixelHeight_ = PSP_CoreParameter().pixelHeight;
bloomHack_ = g_Config.iBloomHack;
@@ -340,14 +341,6 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
}
}
float renderWidthFactor = renderWidth_ / 480.0f;
float renderHeightFactor = renderHeight_ / 272.0f;
if (PSP_CoreParameter().compat.flags().Force04154000Download && params.fb_address == 0x04154000) {
renderWidthFactor = 1.0;
renderHeightFactor = 1.0;
}
// None found? Create one.
if (!vfb) {
vfb = new VirtualFramebuffer{};
@@ -356,28 +349,28 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
vfb->fb_stride = params.fb_stride;
vfb->z_address = params.z_address;
vfb->z_stride = params.z_stride;
// The other width/height parameters are set in ResizeFramebufFBO below.
vfb->width = drawing_width;
vfb->height = drawing_height;
vfb->newWidth = drawing_width;
vfb->newHeight = drawing_height;
vfb->lastFrameNewSize = gpuStats.numFlips;
vfb->renderWidth = (u16)(drawing_width * renderWidthFactor);
vfb->renderHeight = (u16)(drawing_height * renderHeightFactor);
vfb->bufferWidth = drawing_width;
vfb->bufferHeight = drawing_height;
vfb->format = params.fmt;
vfb->drawnFormat = params.fmt;
vfb->usageFlags = FB_USAGE_RENDERTARGET;
SetColorUpdated(vfb, skipDrawReason);
u32 byteSize = ColorBufferByteSize(vfb);
if (Memory::IsVRAMAddress(params.fb_address) && params.fb_address + byteSize > framebufRangeEnd_) {
framebufRangeEnd_ = params.fb_address + byteSize;
}
// This is where we actually create the framebuffer. The true is "force".
ResizeFramebufFBO(vfb, drawing_width, drawing_height, true);
NotifyRenderFramebufferCreated(vfb);
SetColorUpdated(vfb, skipDrawReason);
INFO_LOG(FRAMEBUF, "Creating FBO for %08x (z: %08x) : %i x %i x %i", vfb->fb_address, vfb->z_address, vfb->width, vfb->height, vfb->format);
vfb->last_frame_render = gpuStats.numFlips;
@@ -1046,6 +1039,7 @@ void FramebufferManagerCommon::DecimateFBOs() {
}
}
// Requires width/height to be set already.
void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, int h, bool force, bool skipCopy) {
_dbg_assert_(w > 0);
_dbg_assert_(h > 0);
@@ -1067,7 +1061,32 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w,
vfb->bufferHeight = std::max((int)vfb->bufferHeight, h);
}
SetRenderSize(vfb);
bool force1x = false;
switch (bloomHack_) {
case 1:
force1x = vfb->bufferWidth <= 128 || vfb->bufferHeight <= 64;
break;
case 2:
force1x = vfb->bufferWidth <= 256 || vfb->bufferHeight <= 128;
break;
case 3:
force1x = vfb->bufferWidth < 480 || vfb->bufferWidth > 800 || vfb->bufferHeight < 272; // GOW uses 864x272
break;
}
if (PSP_CoreParameter().compat.flags().Force04154000Download && vfb->fb_address == 0x04154000) {
force1x = true;
}
if (force1x && g_Config.iInternalResolution != 1) {
vfb->renderScaleFactor = 1.0f;
vfb->renderWidth = vfb->bufferWidth;
vfb->renderHeight = vfb->bufferHeight;
} else {
vfb->renderScaleFactor = renderScaleFactor_;
vfb->renderWidth = (u16)(vfb->bufferWidth * renderScaleFactor_);
vfb->renderHeight = (u16)(vfb->bufferHeight * renderScaleFactor_);
}
// During hardware rendering, we always render at full color depth even if the game wouldn't on real hardware.
// It's not worth the trouble trying to support lower bit-depth rendering, just
@@ -1655,35 +1674,6 @@ void FramebufferManagerCommon::NotifyBlockTransferAfter(u32 dstBasePtr, int dstS
}
}
void FramebufferManagerCommon::SetRenderSize(VirtualFramebuffer *vfb) {
float renderWidthFactor = renderWidth_ / 480.0f;
float renderHeightFactor = renderHeight_ / 272.0f;
bool force1x = false;
switch (bloomHack_) {
case 1:
force1x = vfb->bufferWidth <= 128 || vfb->bufferHeight <= 64;
break;
case 2:
force1x = vfb->bufferWidth <= 256 || vfb->bufferHeight <= 128;
break;
case 3:
force1x = vfb->bufferWidth < 480 || vfb->bufferWidth > 800 || vfb->bufferHeight < 272; // GOW uses 864x272
break;
}
if (PSP_CoreParameter().compat.flags().Force04154000Download && vfb->fb_address == 0x04154000) {
force1x = true;
}
if (force1x && g_Config.iInternalResolution != 1) {
vfb->renderWidth = vfb->bufferWidth;
vfb->renderHeight = vfb->bufferHeight;
} else {
vfb->renderWidth = (u16)(vfb->bufferWidth * renderWidthFactor);
vfb->renderHeight = (u16)(vfb->bufferHeight * renderHeightFactor);
}
}
void FramebufferManagerCommon::SetSafeSize(u16 w, u16 h) {
VirtualFramebuffer *vfb = currentRenderVfb_;
if (vfb) {
@@ -1695,10 +1685,11 @@ void FramebufferManagerCommon::SetSafeSize(u16 w, u16 h) {
void FramebufferManagerCommon::Resized() {
gstate_c.skipDrawReason &= ~SKIPDRAW_NON_DISPLAYED_FB;
int w, h;
presentation_->CalculateRenderResolution(&w, &h, &postShaderIsUpscalingFilter_, &postShaderIsSupersampling_);
int w, h, scaleFactor;
presentation_->CalculateRenderResolution(&w, &h, &scaleFactor, &postShaderIsUpscalingFilter_, &postShaderIsSupersampling_);
PSP_CoreParameter().renderWidth = w;
PSP_CoreParameter().renderHeight = h;
PSP_CoreParameter().renderScaleFactor = scaleFactor;
if (UpdateSize()) {
DestroyAllFBOs();
@@ -1736,6 +1727,11 @@ void FramebufferManagerCommon::DestroyAllFBOs() {
tempFB.second.fbo->Release();
}
tempFBOs_.clear();
for (auto iter : fbosToDelete_) {
iter->Release();
}
fbosToDelete_.clear();
}
Draw::Framebuffer *FramebufferManagerCommon::GetTempFBO(TempFBO reason, u16 w, u16 h) {
+11 -7
View File
@@ -61,21 +61,24 @@ struct VirtualFramebuffer {
u16 width;
u16 height;
// renderWidth/renderHeight: The scaled size we render at. May be scaled to render at higher resolutions.
// The physical buffer may be larger than renderWidth/renderHeight.
u16 renderWidth;
u16 renderHeight;
// bufferWidth/bufferHeight: The pre-scaling size of the buffer itself. May only be bigger than width/height.
// bufferWidth/bufferHeight: The pre-scaling size of the buffer itself. May only be bigger than or equal to width/height.
// Actual physical buffer is this size times the render resolution multiplier.
// The buffer may be used to render a width or height from 0 to these values without being recreated.
u16 bufferWidth;
u16 bufferHeight;
// renderWidth/renderHeight: The scaled size we render at. May be scaled to render at higher resolutions.
// The physical buffer may be larger than renderWidth/renderHeight.
u16 renderWidth;
u16 renderHeight;
float renderScaleFactor;
u16 usageFlags;
u16 newWidth;
u16 newHeight;
int lastFrameNewSize;
Draw::Framebuffer *fbo;
@@ -396,9 +399,10 @@ protected:
bool gameUsesSequentialCopies_ = false;
// Sampled in BeginFrame for safety.
// Sampled in BeginFrame/UpdateSize for safety.
float renderWidth_ = 0.0f;
float renderHeight_ = 0.0f;
float renderScaleFactor_ = 1.0f;
int pixelWidth_;
int pixelHeight_;
int bloomHack_ = 0;
+3 -1
View File
@@ -729,7 +729,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u
draw_->BindPipeline(nullptr);
}
void PresentationCommon::CalculateRenderResolution(int *width, int *height, bool *upscaling, bool *ssaa) {
void PresentationCommon::CalculateRenderResolution(int *width, int *height, int *scaleFactor, bool *upscaling, bool *ssaa) {
// Check if postprocessing shader is doing upscaling as it requires native resolution
std::vector<const ShaderInfo *> shaderInfo;
if (!g_Config.vPostShaderNames.empty() && g_Config.vPostShaderNames[0] != "Off") {
@@ -776,4 +776,6 @@ void PresentationCommon::CalculateRenderResolution(int *width, int *height, bool
*width = 480 * zoom;
*height = 272 * zoom;
}
*scaleFactor = zoom;
}
+1 -1
View File
@@ -100,7 +100,7 @@ public:
void SourceFramebuffer(Draw::Framebuffer *fb, int bufferWidth, int bufferHeight);
void CopyToOutput(OutputFlags flags, int uvRotation, float u0, float v0, float u1, float v1);
void CalculateRenderResolution(int *width, int *height, bool *upscaling, bool *ssaa);
void CalculateRenderResolution(int *width, int *height, int *scaleFactor, bool *upscaling, bool *ssaa);
protected:
void CreateDeviceObjects();
-76
View File
@@ -101,79 +101,3 @@ void init_resources(TBuiltInResource &Resources) {
Resources.limits.generalVariableIndexing = 1;
Resources.limits.generalConstantMatrixVectorIndexing = 1;
}
ShaderLanguageDesc::ShaderLanguageDesc(ShaderLanguage lang) {
shaderLanguage = lang;
switch (lang) {
case GLSL_1xx:
// Just used in the shader test, and as a basis for the others in DetectShaderLanguage.
glslVersionNumber = 110;
attribute = "attribute";
varying_vs = "varying";
varying_fs = "varying";
fragColor0 = "gl_FragColor";
fragColor1 = "fragColor1";
texture = "texture2D";
texelFetch = nullptr;
bitwiseOps = false;
lastFragData = nullptr;
gles = false;
forceMatrix4x4 = true;
break;
case GLSL_3xx:
// Just used in the shader test.
glslVersionNumber = 300; // GLSL ES 3.0
varying_vs = "out";
varying_fs = "in";
attribute = "in";
fragColor0 = "fragColor0";
fragColor1 = "fragColor1";
texture = "texture";
texelFetch = nullptr;
bitwiseOps = false;
lastFragData = nullptr;
gles = false;
forceMatrix4x4 = true;
glslES30 = true;
bitwiseOps = true;
texelFetch = "texelFetch";
break;
case GLSL_VULKAN:
fragColor0 = "fragColor0";
fragColor1 = "fragColor1";
varying_fs = "in";
varying_vs = "out";
attribute = "in";
bitwiseOps = true;
framebufferFetchExtension = nullptr;
gles = false;
glslES30 = true;
glslVersionNumber = 450;
lastFragData = nullptr;
texture = "texture";
texelFetch = "texelFetch";
forceMatrix4x4 = false;
coefsFromBuffers = true;
break;
case HLSL_D3D9:
case HLSL_D3D11:
fragColor0 = "outfragment.target";
fragColor1 = "outfragment.target1";
varying_fs = "in";
varying_vs = "out";
attribute = "in";
bitwiseOps = lang == HLSL_D3D11;
framebufferFetchExtension = nullptr;
gles = false;
glslES30 = true;
glslVersionNumber = 0;
lastFragData = nullptr;
texture = "texture";
texelFetch = "texelFetch";
forceMatrix4x4 = false;
coefsFromBuffers = true;
vsOutPrefix = "Out.";
break;
}
}
+4 -4
View File
@@ -420,8 +420,8 @@ void FramebufferManagerD3D11::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
return;
}
float srcXFactor = (float)src->renderWidth / (float)src->bufferWidth;
float srcYFactor = (float)src->renderHeight / (float)src->bufferHeight;
float srcXFactor = src->renderScaleFactor;
float srcYFactor = src->renderScaleFactor;
const int srcBpp = src->format == GE_FORMAT_8888 ? 4 : 2;
if (srcBpp != bpp && bpp != 0) {
srcXFactor = (srcXFactor * bpp) / srcBpp;
@@ -431,8 +431,8 @@ void FramebufferManagerD3D11::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
int srcY1 = srcY * srcYFactor;
int srcY2 = (srcY + h) * srcYFactor;
float dstXFactor = (float)dst->renderWidth / (float)dst->bufferWidth;
float dstYFactor = (float)dst->renderHeight / (float)dst->bufferHeight;
float dstXFactor = dst->renderScaleFactor;
float dstYFactor = dst->renderScaleFactor;
const int dstBpp = dst->format == GE_FORMAT_8888 ? 4 : 2;
if (dstBpp != bpp && bpp != 0) {
dstXFactor = (dstXFactor * bpp) / dstBpp;
+3 -3
View File
@@ -89,7 +89,7 @@ std::string D3D11VertexShader::GetShaderString(DebugShaderStringType type) const
}
ShaderManagerD3D11::ShaderManagerD3D11(Draw::DrawContext *draw, ID3D11Device *device, ID3D11DeviceContext *context, D3D_FEATURE_LEVEL featureLevel)
: ShaderManagerCommon(draw), device_(device), context_(context), featureLevel_(featureLevel), compat_(ShaderLanguage::HLSL_D3D11) {
: ShaderManagerCommon(draw), device_(device), context_(context), featureLevel_(featureLevel) {
codeBuffer_ = new char[16384];
memset(&ub_base, 0, sizeof(ub_base));
memset(&ub_lights, 0, sizeof(ub_lights));
@@ -210,7 +210,7 @@ void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **
std::string genErrorString;
uint32_t attrMask;
uint64_t uniformMask;
GenerateVertexShader(VSID, codeBuffer_, compat_, &attrMask, &uniformMask, &genErrorString);
GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), &attrMask, &uniformMask, &genErrorString);
vs = new D3D11VertexShader(device_, featureLevel_, VSID, codeBuffer_, vertType, useHWTransform);
vsCache_[VSID] = vs;
} else {
@@ -224,7 +224,7 @@ void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **
// Fragment shader not in cache. Let's compile it.
std::string genErrorString;
uint64_t uniformMask;
GenerateFragmentShader(FSID, codeBuffer_, compat_, &uniformMask, &genErrorString);
GenerateFragmentShader(FSID, codeBuffer_, draw_->GetShaderLanguageDesc(), &uniformMask, &genErrorString);
fs = new D3D11FragmentShader(device_, featureLevel_, FSID, codeBuffer_, useHWTransform);
fsCache_[FSID] = fs;
} else {
-1
View File
@@ -110,7 +110,6 @@ private:
ID3D11Device *device_;
ID3D11DeviceContext *context_;
D3D_FEATURE_LEVEL featureLevel_;
ShaderLanguageDesc compat_;
typedef std::map<FShaderID, D3D11FragmentShader *> FSCache;
FSCache fsCache_;
+4 -4
View File
@@ -383,8 +383,8 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
return;
}
float srcXFactor = (float)src->renderWidth / (float)src->bufferWidth;
float srcYFactor = (float)src->renderHeight / (float)src->bufferHeight;
float srcXFactor = (float)src->renderScaleFactor;
float srcYFactor = (float)src->renderScaleFactor;
const int srcBpp = src->format == GE_FORMAT_8888 ? 4 : 2;
if (srcBpp != bpp && bpp != 0) {
srcXFactor = (srcXFactor * bpp) / srcBpp;
@@ -394,8 +394,8 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
int srcY1 = srcY * srcYFactor;
int srcY2 = (srcY + h) * srcYFactor;
float dstXFactor = (float)dst->renderWidth / (float)dst->bufferWidth;
float dstYFactor = (float)dst->renderHeight / (float)dst->bufferHeight;
float dstXFactor = (float)dst->renderScaleFactor;
float dstYFactor = (float)dst->renderScaleFactor;
const int dstBpp = dst->format == GE_FORMAT_8888 ? 4 : 2;
if (dstBpp != bpp && bpp != 0) {
dstXFactor = (dstXFactor * bpp) / dstBpp;
+4 -4
View File
@@ -502,7 +502,7 @@ void ShaderManagerDX9::VSUpdateUniforms(u64 dirtyUniforms) {
}
ShaderManagerDX9::ShaderManagerDX9(Draw::DrawContext *draw, LPDIRECT3DDEVICE9 device)
: ShaderManagerCommon(draw), device_(device), compat_(HLSL_D3D9) {
: ShaderManagerCommon(draw), device_(device) {
codeBuffer_ = new char[32768];
}
@@ -582,7 +582,7 @@ VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellat
std::string genErrorString;
uint32_t attrMask;
uint64_t uniformMask;
if (GenerateVertexShader(VSID, codeBuffer_, compat_, &attrMask, &uniformMask, &genErrorString)) {
if (GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), &attrMask, &uniformMask, &genErrorString)) {
vs = new VSShader(device_, VSID, codeBuffer_, useHWTransform);
}
if (!vs || vs->Failed()) {
@@ -607,7 +607,7 @@ VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellat
// Can still work with software transform.
uint32_t attrMask;
uint64_t uniformMask;
bool success = GenerateVertexShader(VSID, codeBuffer_, compat_, &attrMask, &uniformMask, &genErrorString);
bool success = GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), &attrMask, &uniformMask, &genErrorString);
_assert_(success);
vs = new VSShader(device_, VSID, codeBuffer_, false);
}
@@ -624,7 +624,7 @@ VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellat
// Fragment shader not in cache. Let's compile it.
std::string errorString;
uint64_t uniformMask;
bool success = GenerateFragmentShader(FSID, codeBuffer_, compat_, &uniformMask, &errorString);
bool success = GenerateFragmentShader(FSID, codeBuffer_, draw_->GetShaderLanguageDesc(), &uniformMask, &errorString);
// We're supposed to handle all possible cases.
_assert_(success);
fs = new PSShader(device_, FSID, codeBuffer_);
-1
View File
@@ -111,7 +111,6 @@ private:
void Clear();
LPDIRECT3DDEVICE9 device_;
ShaderLanguageDesc compat_;
FShaderID lastFSID_;
VShaderID lastVSID_;
+7 -5
View File
@@ -315,8 +315,8 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
bool useBlit = gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT);
float srcXFactor = useBlit ? (float)src->renderWidth / (float)src->bufferWidth : 1.0f;
float srcYFactor = useBlit ? (float)src->renderHeight / (float)src->bufferHeight : 1.0f;
float srcXFactor = useBlit ? src->renderScaleFactor : 1.0f;
float srcYFactor = useBlit ? src->renderScaleFactor : 1.0f;
const int srcBpp = src->format == GE_FORMAT_8888 ? 4 : 2;
if (srcBpp != bpp && bpp != 0) {
srcXFactor = (srcXFactor * bpp) / srcBpp;
@@ -326,8 +326,8 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
int srcY1 = srcY * srcYFactor;
int srcY2 = (srcY + h) * srcYFactor;
float dstXFactor = useBlit ? (float)dst->renderWidth / (float)dst->bufferWidth : 1.0f;
float dstYFactor = useBlit ? (float)dst->renderHeight / (float)dst->bufferHeight : 1.0f;
float dstXFactor = useBlit ? dst->renderScaleFactor : 1.0f;
float dstYFactor = useBlit ? dst->renderScaleFactor : 1.0f;
const int dstBpp = dst->format == GE_FORMAT_8888 ? 4 : 2;
if (dstBpp != bpp && bpp != 0) {
dstXFactor = (dstXFactor * bpp) / dstBpp;
@@ -360,6 +360,8 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
if (useBlit) {
draw_->BlitFramebuffer(src->fbo, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, Draw::FB_COLOR_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebuffer");
} else {
// TODO: Move this workaround out into thin3d, instead of dirtying up the code here.
draw_->BindFramebufferAsRenderTarget(dst->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "BlitFramebuffer");
draw_->BindFramebufferAsTexture(src->fbo, 0, Draw::FB_COLOR_BIT, 0);
@@ -376,7 +378,7 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
float srcW = src->bufferWidth;
float srcH = src->bufferHeight;
render_->BindProgram(draw2dprogram_);
DrawActiveTexture(dstX1, dstY1, w * dstXFactor, h, dst->bufferWidth, dst->bufferHeight, srcX1 / srcW, srcY1 / srcH, srcX2 / srcW, srcY2 / srcH, ROTATION_LOCKED_HORIZONTAL, DRAWTEX_NEAREST);
DrawActiveTexture(dstX1, dstY1, w * dstXFactor, h * dstYFactor, dst->bufferWidth, dst->bufferHeight, srcX1 / srcW, srcY1 / srcH, srcX2 / srcW, srcY2 / srcH, ROTATION_LOCKED_HORIZONTAL, DRAWTEX_NEAREST);
textureCacheGL_->ForgetLastTexture();
}
+3 -81
View File
@@ -572,95 +572,17 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu
}
ShaderManagerGLES::ShaderManagerGLES(Draw::DrawContext *draw)
: ShaderManagerCommon(draw), compat_(GLSL_1xx), fsCache_(16), vsCache_(16) {
: ShaderManagerCommon(draw), fsCache_(16), vsCache_(16) {
render_ = (GLRenderManager *)draw->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
codeBuffer_ = new char[16384];
lastFSID_.set_invalid();
lastVSID_.set_invalid();
DetectShaderLanguage();
}
ShaderManagerGLES::~ShaderManagerGLES() {
delete [] codeBuffer_;
}
void ShaderManagerGLES::DetectShaderLanguage() {
ShaderLanguageDesc &compat = compat_;
compat.gles = gl_extensions.IsGLES;
if (compat.gles) {
if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300)) {
compat.shaderLanguage = ShaderLanguage::GLSL_3xx;
compat.glslVersionNumber = 300; // GLSL ES 3.0
compat.fragColor0 = "fragColor0";
compat.texture = "texture";
compat.glslES30 = true;
compat.bitwiseOps = true;
compat.texelFetch = "texelFetch";
compat.varying_vs = "out";
compat.varying_fs = "in";
compat.attribute = "in";
} else {
compat.shaderLanguage = ShaderLanguage::GLSL_1xx;
compat.glslVersionNumber = 100; // GLSL ES 1.0
if (gl_extensions.EXT_gpu_shader4) {
compat.bitwiseOps = true;
compat.texelFetch = "texelFetch2D";
}
if (gl_extensions.EXT_blend_func_extended) {
// Oldy moldy GLES, so use the fixed output name.
compat.fragColor1 = "gl_SecondaryFragColorEXT";
}
}
} else {
if (!gl_extensions.ForceGL2 || gl_extensions.IsCoreContext) {
if (gl_extensions.VersionGEThan(3, 3, 0)) {
compat.shaderLanguage = ShaderLanguage::GLSL_3xx;
compat.glslVersionNumber = 330;
compat.fragColor0 = "fragColor0";
compat.texture = "texture";
compat.glslES30 = true;
compat.bitwiseOps = true;
compat.texelFetch = "texelFetch";
compat.varying_vs = "out";
compat.varying_fs = "in";
compat.attribute = "in";
} else if (gl_extensions.VersionGEThan(3, 0, 0)) {
compat.shaderLanguage = ShaderLanguage::GLSL_1xx;
compat.glslVersionNumber = 130;
compat.fragColor0 = "fragColor0";
compat.bitwiseOps = true;
compat.texelFetch = "texelFetch";
} else {
compat.shaderLanguage = ShaderLanguage::GLSL_1xx;
compat.glslVersionNumber = 110;
if (gl_extensions.EXT_gpu_shader4) {
compat.bitwiseOps = true;
compat.texelFetch = "texelFetch2D";
}
}
}
}
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)) {
if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300) && gl_extensions.EXT_shader_framebuffer_fetch) {
compat.framebufferFetchExtension = "#extension GL_EXT_shader_framebuffer_fetch : require";
compat.lastFragData = "fragColor0";
} else if (gl_extensions.EXT_shader_framebuffer_fetch) {
compat.framebufferFetchExtension = "#extension GL_EXT_shader_framebuffer_fetch : require";
compat.lastFragData = "gl_LastFragData[0]";
} else if (gl_extensions.NV_shader_framebuffer_fetch) {
// GL_NV_shader_framebuffer_fetch is available on mobile platform and ES 2.0 only but not on desktop.
compat.framebufferFetchExtension = "#extension GL_NV_shader_framebuffer_fetch : require";
compat.lastFragData = "gl_LastFragData[0]";
} else if (gl_extensions.ARM_shader_framebuffer_fetch) {
compat.framebufferFetchExtension = "#extension GL_ARM_shader_framebuffer_fetch : require";
compat.lastFragData = "gl_LastFragColorARM";
}
}
}
void ShaderManagerGLES::Clear() {
DirtyLastShader();
for (auto iter = linkedShaderCache_.begin(); iter != linkedShaderCache_.end(); ++iter) {
@@ -709,7 +631,7 @@ void ShaderManagerGLES::DirtyLastShader() {
Shader *ShaderManagerGLES::CompileFragmentShader(FShaderID FSID) {
uint64_t uniformMask;
std::string errorString;
if (!GenerateFragmentShader(FSID, codeBuffer_, compat_, &uniformMask, &errorString)) {
if (!GenerateFragmentShader(FSID, codeBuffer_, draw_->GetShaderLanguageDesc(), &uniformMask, &errorString)) {
ERROR_LOG(G3D, "Shader gen error: %s", errorString.c_str());
return nullptr;
}
@@ -722,7 +644,7 @@ Shader *ShaderManagerGLES::CompileVertexShader(VShaderID VSID) {
uint32_t attrMask;
uint64_t uniformMask;
std::string errorString;
if (!GenerateVertexShader(VSID, codeBuffer_, compat_, &attrMask, &uniformMask, &errorString)) {
if (!GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), &attrMask, &uniformMask, &errorString)) {
ERROR_LOG(G3D, "Shader gen error: %s", errorString.c_str());
return nullptr;
}
-2
View File
@@ -170,7 +170,6 @@ private:
void Clear();
Shader *CompileFragmentShader(FShaderID id);
Shader *CompileVertexShader(VShaderID id);
void DetectShaderLanguage();
struct LinkedShaderCacheEntry {
LinkedShaderCacheEntry(Shader *vs_, Shader *fs_, LinkedShader *ls_)
@@ -183,7 +182,6 @@ private:
typedef std::vector<LinkedShaderCacheEntry> LinkedShaderCache;
GLRenderManager *render_;
ShaderLanguageDesc compat_;
LinkedShaderCache linkedShaderCache_;
bool lastVShaderSame_;
+6 -7
View File
@@ -261,7 +261,6 @@ void FramebufferManagerVulkan::ReformatFramebufferFrom(VirtualFramebuffer *vfb,
// We have to bind here instead of clear, since it can be that no framebuffer is bound.
// The backend can sometimes directly optimize it to a clear.
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }, "ReformatFramebuffer");
// draw_->Clear(Draw::FBChannel::FB_COLOR_BIT | Draw::FBChannel::FB_STENCIL_BIT, 0, 0.0f, 0);
// Need to dirty anything that has command buffer dynamic state, in case we started a new pass above.
// Should find a way to feed that information back, maybe... Or simply correct the issue in the rendermanager.
@@ -339,8 +338,10 @@ void FramebufferManagerVulkan::BlitFramebuffer(VirtualFramebuffer *dst, int dstX
return;
}
float srcXFactor = (float)src->renderWidth / (float)src->bufferWidth;
float srcYFactor = (float)src->renderHeight / (float)src->bufferHeight;
float srcXFactor = (float)src->renderScaleFactor;
float srcYFactor = (float)src->renderScaleFactor;
// Some games use wrong-format block transfers. Simulate that.
const int srcBpp = src->format == GE_FORMAT_8888 ? 4 : 2;
if (srcBpp != bpp && bpp != 0) {
srcXFactor = (srcXFactor * bpp) / srcBpp;
@@ -350,8 +351,8 @@ void FramebufferManagerVulkan::BlitFramebuffer(VirtualFramebuffer *dst, int dstX
int srcY1 = srcY * srcYFactor;
int srcY2 = (srcY + h) * srcYFactor;
float dstXFactor = (float)dst->renderWidth / (float)dst->bufferWidth;
float dstYFactor = (float)dst->renderHeight / (float)dst->bufferHeight;
float dstXFactor = (float)dst->renderScaleFactor;
float dstYFactor = (float)dst->renderScaleFactor;
const int dstBpp = dst->format == GE_FORMAT_8888 ? 4 : 2;
if (dstBpp != bpp && bpp != 0) {
dstXFactor = (dstXFactor * bpp) / dstBpp;
@@ -367,8 +368,6 @@ void FramebufferManagerVulkan::BlitFramebuffer(VirtualFramebuffer *dst, int dstX
return;
}
// BlitFramebuffer can clip, but CopyFramebufferImage is more restricted.
// In case the src goes outside, we just skip the optimization in that case.
const bool sameSize = dstX2 - dstX1 == srcX2 - srcX1 && dstY2 - dstY1 == srcY2 - srcY1;
const bool srcInsideBounds = srcX2 <= src->renderWidth && srcY2 <= src->renderHeight;
const bool dstInsideBounds = dstX2 <= dst->renderWidth && dstY2 <= dst->renderHeight;
+1
View File
@@ -358,6 +358,7 @@ int main(int argc, const char* argv[])
coreParameter.startBreak = false;
coreParameter.printfEmuLog = !autoCompare;
coreParameter.headLess = true;
coreParameter.renderScaleFactor = 1;
coreParameter.renderWidth = 480;
coreParameter.renderHeight = 272;
coreParameter.pixelWidth = 480;