Merge branch 'master' into TemporaryHackishBranch

This commit is contained in:
LunaMoo committed 2019-09-11 23:09:10 +02:00
commit 46fced0ccc
15 files changed
+125 -89

No files matched your search

+40
View File
@@ -1391,3 +1391,43 @@ void VulkanContext::GetImageMemoryRequirements(VkImage image, VkMemoryRequiremen
*dedicatedAllocation = false;
}
}
bool IsHashMaliDriverVersion(const VkPhysicalDeviceProperties &props) {
// ARM used to put a hash in place of the driver version.
// Now they only use major versions. We'll just make a bad heuristic.
uint32_t major = VK_VERSION_MAJOR(props.driverVersion);
uint32_t minor = VK_VERSION_MINOR(props.driverVersion);
uint32_t branch = VK_VERSION_PATCH(props.driverVersion);
if (branch > 0)
return true;
if (branch > 100 || major > 100)
return true;
return false;
}
// From Sascha's code
std::string FormatDriverVersion(const VkPhysicalDeviceProperties &props) {
if (props.vendorID == VULKAN_VENDOR_NVIDIA) {
// For whatever reason, NVIDIA has their own scheme.
// 10 bits = major version (up to r1023)
// 8 bits = minor version (up to 255)
// 8 bits = secondary branch version/build version (up to 255)
// 6 bits = tertiary branch/build version (up to 63)
uint32_t major = (props.driverVersion >> 22) & 0x3ff;
uint32_t minor = (props.driverVersion >> 14) & 0x0ff;
uint32_t secondaryBranch = (props.driverVersion >> 6) & 0x0ff;
uint32_t tertiaryBranch = (props.driverVersion) & 0x003f;
return StringFromFormat("%d.%d.%d.%d", major, minor, secondaryBranch, tertiaryBranch);
} else if (props.vendorID == VULKAN_VENDOR_ARM) {
// ARM used to just put a hash here. No point in splitting it up.
if (IsHashMaliDriverVersion(props)) {
return StringFromFormat("(hash) %08x", props.driverVersion);
}
}
// Qualcomm has an inscrutable versioning scheme. Let's just display it as normal.
// Standard scheme, use the standard macros.
uint32_t major = VK_VERSION_MAJOR(props.driverVersion);
uint32_t minor = VK_VERSION_MINOR(props.driverVersion);
uint32_t branch = VK_VERSION_PATCH(props.driverVersion);
return StringFromFormat("%d.%d.%d (%08x)", major, minor, branch, props.driverVersion);
}
+4
View File
@@ -359,3 +359,7 @@ void finalize_glslang();
bool GLSLtoSPV(const VkShaderStageFlagBits shader_type, const char *pshader, std::vector<uint32_t> &spirv, std::string *errorMessage = nullptr);
const char *VulkanResultToString(VkResult res);
std::string FormatDriverVersion(const VkPhysicalDeviceProperties &props);
// Simple heuristic.
bool IsHashMaliDriverVersion(const VkPhysicalDeviceProperties &props);
-1
View File
@@ -150,7 +150,6 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
if (g_Config.iRenderingMode == FB_NON_BUFFERED_MODE && g_display_rotation != DisplayRotation::ROTATE_0) {
flippedMatrix = flippedMatrix * g_display_rot_matrix;
}
CopyMatrix4x4(ub->proj, flippedMatrix.getReadPtr());
}
+1
View File
@@ -495,6 +495,7 @@ enum {
GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT = FLAG_BIT(26),
GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT = FLAG_BIT(27),
GPU_SUPPORTS_OES_TEXTURE_NPOT = FLAG_BIT(28),
GPU_NEEDS_Z_EQUAL_W_HACK = FLAG_BIT(29),
GPU_PREFER_CPU_DOWNLOAD = FLAG_BIT(30),
GPU_PREFER_REVERSE_COLOR_ORDER = FLAG_BIT(31),
};
+1 -1
View File
@@ -970,7 +970,7 @@ void DrawEngineVulkan::DoFlush() {
int scissorY2 = gstate.getScissorY2() + 1;
framebufferManager_->SetSafeSize(scissorX2, scissorY2);
if ((gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) {
if (gstate_c.Supports(GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) {
framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, result.color);
}
}
+13 -4
View File
@@ -17,6 +17,7 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <thread>
#include "base/logging.h"
#include "base/timeutil.h"
#include "profiler/profiler.h"
@@ -197,15 +198,23 @@ void GPU_Vulkan::CheckGPUFeatures() {
features |= GPU_SUPPORTS_ACCURATE_DEPTH;
break;
case VULKAN_VENDOR_ARM:
// Also required on older ARM Mali drivers, like the one on many Galaxy S7.
if (!PSP_CoreParameter().compat.flags().DisableAccurateDepth ||
vulkan_->GetPhysicalDeviceProperties().properties.driverVersion <= VK_MAKE_VERSION(428, 811, 2674)) {
{
// This check is probably not exactly accurate. But old drivers had problems with reverse-Z, just like AMD and Qualcomm.
bool driverTooOld = IsHashMaliDriverVersion(vulkan_->GetPhysicalDeviceProperties().properties)
|| VK_VERSION_MAJOR(vulkan_->GetPhysicalDeviceProperties().properties.driverVersion) < 14;
if (!PSP_CoreParameter().compat.flags().DisableAccurateDepth || driverTooOld) {
features |= GPU_SUPPORTS_ACCURATE_DEPTH;
}
// These GPUs (up to some certain hardware version?) has a bug where draws where gl_Position.w == .z
// corrupt the depth buffer. This is easily worked around by simply scaling Z down a tiny bit when this case
// is detected. See: https://github.com/hrydgard/ppsspp/issues/11937
features |= GPU_NEEDS_Z_EQUAL_W_HACK;
break;
}
default:
if (!PSP_CoreParameter().compat.flags().DisableAccurateDepth)
if (!PSP_CoreParameter().compat.flags().DisableAccurateDepth) {
features |= GPU_SUPPORTS_ACCURATE_DEPTH;
}
break;
}
+5 -2
View File
@@ -176,8 +176,7 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
if (!useHWTransform && doTextureTransform && !isModeThrough) {
WRITE(p, "layout (location = %d) in vec3 texcoord;\n", (int)PspAttributeLocation::TEXCOORD);
texcoordInVec3 = true;
}
else
} else
WRITE(p, "layout (location = %d) in vec2 texcoord;\n", (int)PspAttributeLocation::TEXCOORD);
}
if (hasColor) {
@@ -640,6 +639,10 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
}
WRITE(p, " gl_Position = outPos;\n");
if (gstate_c.Supports(GPU_NEEDS_Z_EQUAL_W_HACK)) {
// See comment in GPU_Vulkan.cpp.
WRITE(p, " if (gl_Position.z == gl_Position.w) gl_Position.z *= 0.999999;\n");
}
WRITE(p, "}\n");
return true;
}
+34
View File
@@ -1,3 +1,4 @@
#include <algorithm>
#include "base/display.h"
int dp_xres;
@@ -17,3 +18,36 @@ float display_hz = 60.0f;
DisplayRotation g_display_rotation;
Matrix4x4 g_display_rot_matrix;
void RotateRectToDisplay(FRect &rect, float curRTWidth, float curRTHeight) {
switch (g_display_rotation) {
case DisplayRotation::ROTATE_180:
rect.x = curRTWidth - rect.w - rect.x;
rect.y = curRTHeight - rect.h - rect.y;
break;
case DisplayRotation::ROTATE_90: {
// Note that curRTWidth_ and curRTHeight_ are "swapped"!
float origX = rect.x;
float origY = rect.y;
float rtw = curRTHeight;
float rth = curRTWidth;
rect.x = rth - rect.h - origY;
rect.y = origX;
std::swap(rect.w, rect.h);
break;
}
case DisplayRotation::ROTATE_270: {
float origX = rect.x;
float origY = rect.y;
float rtw = curRTHeight;
float rth = curRTWidth;
rect.x = origY;
rect.y = rtw - rect.w - origX;
std::swap(rect.w, rect.h);
break;
}
case DisplayRotation::ROTATE_0:
default:
break;
}
}
+5
View File
@@ -30,3 +30,8 @@ enum class DisplayRotation {
extern DisplayRotation g_display_rotation;
extern Matrix4x4 g_display_rot_matrix;
struct FRect {
float x, y, w, h;
};
void RotateRectToDisplay(FRect &rect, float curRTWidth, float curRTHeight);
-2
View File
@@ -220,5 +220,3 @@ void EnableFZ();
// very slow VFP units).
// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0274h/Babffifj.html
void FPU_SetFastMode();
+20 -5
View File
@@ -10,6 +10,7 @@
#include <mutex>
#include <thread>
#include "base/display.h"
#include "Common/Vulkan/VulkanContext.h"
#include "math/dataconv.h"
#include "math/math_util.h"
@@ -119,15 +120,21 @@ public:
void SetViewport(const VkViewport &vp) {
_dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER);
_dbg_assert_(G3D, (int)vp.width >= 0);
FRect rc{ vp.x, vp.y, vp.width, vp.height };
if (curRenderStep_->render.framebuffer == nullptr) { // Only the backbuffer is actually rotated wrong!
RotateRectToDisplay(rc, (float)vulkan_->GetBackbufferWidth(), (float)vulkan_->GetBackbufferHeight());
}
VkRenderData data{ VKRRenderCommand::VIEWPORT };
data.viewport.vp.x = vp.x;
data.viewport.vp.y = vp.y;
data.viewport.vp.width = vp.width;
data.viewport.vp.height = vp.height;
data.viewport.vp.x = rc.x;
data.viewport.vp.y = rc.y;
data.viewport.vp.width = rc.w;
data.viewport.vp.height = rc.h;
// We can't allow values outside this range unless we use VK_EXT_depth_range_unrestricted.
// Sometimes state mapping produces 65536/65535 which is slightly outside.
// TODO: This should be fixed at the source.
data.viewport.vp.maxDepth = clamp_value(vp.maxDepth, 0.0f, 1.0f);
data.viewport.vp.minDepth = clamp_value(vp.minDepth, 0.0f, 1.0f);
curRenderStep_->commands.push_back(data);
}
@@ -136,7 +143,15 @@ public:
_dbg_assert_(G3D, (int)rc.extent.width >= 0);
_dbg_assert_(G3D, (int)rc.extent.height >= 0);
VkRenderData data{ VKRRenderCommand::SCISSOR };
data.scissor.scissor = rc;
if (curRenderStep_->render.framebuffer == nullptr) {
FRect frc{ (float)rc.offset.x, (float)rc.offset.y, (float)rc.extent.width, (float)rc.extent.height };
if (curRenderStep_->render.framebuffer == nullptr) { // Only the backbuffer is actually rotated wrong!
RotateRectToDisplay(frc, (float)vulkan_->GetBackbufferWidth(), (float)vulkan_->GetBackbufferHeight());
}
data.scissor.scissor = VkRect2D{ { (int32_t)frc.x, (int32_t)frc.y }, { (uint32_t)frc.w, (uint32_t)frc.h} };
} else {
data.scissor.scissor = rc;
}
curRenderStep_->commands.push_back(data);
}
-32
View File
@@ -353,38 +353,6 @@ DrawContext::~DrawContext() {
DestroyPresets();
}
void DrawContext::RotateRectToDisplay(FRect &rect, float curRTWidth, float curRTHeight) {
if (g_display_rotation == DisplayRotation::ROTATE_0)
return;
switch (g_display_rotation) {
case DisplayRotation::ROTATE_180:
rect.x = curRTWidth - rect.w - rect.x;
rect.y = curRTHeight - rect.h - rect.y;
break;
case DisplayRotation::ROTATE_90: {
// Note that curRTWidth_ and curRTHeight_ are "swapped"!
float origX = rect.x;
float origY = rect.y;
float rtw = curRTHeight;
float rth = curRTWidth;
rect.x = rth - rect.h - origY;
rect.y = origX;
std::swap(rect.w, rect.h);
break;
}
case DisplayRotation::ROTATE_270: {
float origX = rect.x;
float origY = rect.y;
float rtw = curRTHeight;
float rth = curRTWidth;
rect.x = origY;
rect.y = rtw - rect.w - origX;
std::swap(rect.w, rect.h);
break;
}
}
}
// TODO: SSE/NEON
// Could also make C fake-simd for 64-bit, two 8888 pixels fit in a register :)
void ConvertFromRGBA8888(uint8_t *dst, const uint8_t *src, uint32_t dstStride, uint32_t srcStride, uint32_t width, uint32_t height, DataFormat format) {
-5
View File
@@ -661,11 +661,6 @@ public:
virtual void FlushState() {}
protected:
struct FRect {
float x, y, w, h;
};
void RotateRectToDisplay(FRect &rect, float curRTWidth, float curRTHeight);
ShaderModule *vsPresets_[VS_MAX_PRESET];
ShaderModule *fsPresets_[FS_MAX_PRESET];
+1 -36
View File
@@ -429,30 +429,6 @@ public:
void FlushState() override {}
// From Sascha's code
static std::string FormatDriverVersion(const VkPhysicalDeviceProperties &props) {
if (props.vendorID == VULKAN_VENDOR_NVIDIA) {
// 10 bits = major version (up to r1023)
// 8 bits = minor version (up to 255)
// 8 bits = secondary branch version/build version (up to 255)
// 6 bits = tertiary branch/build version (up to 63)
uint32_t major = (props.driverVersion >> 22) & 0x3ff;
uint32_t minor = (props.driverVersion >> 14) & 0x0ff;
uint32_t secondaryBranch = (props.driverVersion >> 6) & 0x0ff;
uint32_t tertiaryBranch = (props.driverVersion) & 0x003f;
return StringFromFormat("%d.%d.%d.%d (%08x)", major, minor, secondaryBranch, tertiaryBranch, props.driverVersion);
} else if (props.vendorID == VULKAN_VENDOR_ARM) {
// ARM just puts a hash here, let's just output it as is.
return StringFromFormat("%08x", props.driverVersion);
} else {
// Standard scheme, use the standard macros.
uint32_t major = VK_VERSION_MAJOR(props.driverVersion);
uint32_t minor = VK_VERSION_MINOR(props.driverVersion);
uint32_t branch = VK_VERSION_PATCH(props.driverVersion);
return StringFromFormat("%d.%d.%d (%08x)", major, minor, branch, props.driverVersion);
}
}
std::string GetInfoString(InfoField info) const override {
// TODO: Make these actually query the right information
switch (info) {
@@ -1059,13 +1035,7 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
}
void VKContext::SetScissorRect(int left, int top, int width, int height) {
FRect rc{ (float)left, (float)top, (float)width, (float)height };
if (curFramebuffer_ == nullptr) { // Only the backbuffer is actually rotated wrong!
int curRTWidth, curRTHeight;
GetFramebufferDimensions((Framebuffer *)curFramebuffer_, &curRTWidth, &curRTHeight);
RotateRectToDisplay(rc, (float)curRTWidth, (float)curRTHeight);
}
VkRect2D scissor{ {(int32_t)rc.x, (int32_t)rc.y}, {(uint32_t)rc.w, (uint32_t)rc.h} };
VkRect2D scissor{ {(int32_t)left, (int32_t)top}, {(uint32_t)width, (uint32_t)height} };
renderManager_.SetScissor(scissor);
}
@@ -1074,11 +1044,6 @@ void VKContext::SetViewports(int count, Viewport *viewports) {
// Ignore viewports more than the first.
VkViewport viewport;
FRect rc{ viewports[0].TopLeftX , viewports[0].TopLeftY, viewports[0].Width, viewports[0].Height };
if (curFramebuffer_ == nullptr) { // Only the backbuffer is actually rotated wrong!
int curRTWidth, curRTHeight;
GetFramebufferDimensions((Framebuffer *)curFramebuffer_, &curRTWidth, &curRTHeight);
RotateRectToDisplay(rc, (float)curRTWidth, (float)curRTHeight);
}
viewport.x = rc.x;
viewport.y = rc.y;
viewport.width = rc.w;