mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 05:19:56 +00:00
Misc multiview hackery
This commit is contained in:
parent
7a620962aa
commit
d3804ec2e5
@ -326,9 +326,10 @@ static VkAttachmentStoreOp ConvertStoreAction(VKRRenderPassStoreAction action) {
|
||||
// Also see https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#synchronization-pipeline-barriers-subpass-self-dependencies
|
||||
|
||||
VkRenderPass CreateRenderPass(VulkanContext *vulkan, const RPKey &key, RenderPassType rpType) {
|
||||
bool selfDependency = rpType == RP_TYPE_COLOR_INPUT || rpType == RP_TYPE_COLOR_DEPTH_INPUT;
|
||||
bool selfDependency = RenderPassTypeHasInput(rpType);
|
||||
bool isBackbuffer = rpType == RP_TYPE_BACKBUFFER;
|
||||
bool hasDepth = rpType == RP_TYPE_BACKBUFFER || rpType == RP_TYPE_COLOR_DEPTH || rpType == RP_TYPE_COLOR_DEPTH_INPUT;
|
||||
bool hasDepth = RenderPassTypeHasDepth(rpType);
|
||||
bool multiview = RenderPassTypeHasMultiView(rpType);
|
||||
|
||||
VkAttachmentDescription attachments[2] = {};
|
||||
attachments[0].format = isBackbuffer ? vulkan->GetSwapchainFormat() : VK_FORMAT_R8G8B8A8_UNORM;
|
||||
@ -390,6 +391,19 @@ VkRenderPass CreateRenderPass(VulkanContext *vulkan, const RPKey &key, RenderPas
|
||||
rp.subpassCount = 1;
|
||||
rp.pSubpasses = &subpass;
|
||||
|
||||
VkRenderPassMultiviewCreateInfoKHR mv{ VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR };
|
||||
uint32_t viewMask = 0x3; // Must be outside the 'if (multiview)' scope!
|
||||
int viewOffset = 0;
|
||||
if (multiview) {
|
||||
rp.pNext = &mv;
|
||||
mv.subpassCount = 1;
|
||||
mv.pViewMasks = &viewMask;
|
||||
mv.dependencyCount = 0;
|
||||
mv.pCorrelationMasks = &viewMask; // same masks
|
||||
mv.correlationMaskCount = 1;
|
||||
mv.pViewOffsets = &viewOffset;
|
||||
}
|
||||
|
||||
if (isBackbuffer) {
|
||||
deps[numDeps].srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||
deps[numDeps].dstSubpass = 0;
|
||||
|
@ -48,18 +48,24 @@ enum class PipelineFlags {
|
||||
USES_DEPTH_STENCIL = (1 << 2), // Reads or writes the depth or stencil buffers.
|
||||
USES_INPUT_ATTACHMENT = (1 << 3),
|
||||
USES_GEOMETRY_SHADER = (1 << 4),
|
||||
USES_MULTIVIEW = (1 << 5), // Inherited from the render pass it was created with.
|
||||
};
|
||||
ENUM_CLASS_BITOPS(PipelineFlags);
|
||||
|
||||
// Pipelines need to be created for the right type of render pass.
|
||||
enum RenderPassType {
|
||||
// These four are organized so that bit 0 is DEPTH and bit 1 is INPUT, so
|
||||
// These eight are organized so that bit 0 is DEPTH and bit 1 is INPUT and bit 2 is MULTIVIEW, so
|
||||
// they can be OR-ed together in MergeRPTypes.
|
||||
RP_TYPE_COLOR,
|
||||
RP_TYPE_COLOR_DEPTH,
|
||||
RP_TYPE_COLOR_INPUT,
|
||||
RP_TYPE_COLOR_DEPTH_INPUT,
|
||||
|
||||
RP_TYPE_MULTIVIEW_COLOR,
|
||||
RP_TYPE_MULTIVIEW_COLOR_DEPTH,
|
||||
RP_TYPE_MULTIVIEW_COLOR_INPUT,
|
||||
RP_TYPE_MULTIVIEW_COLOR_DEPTH_INPUT,
|
||||
|
||||
// This is the odd one out, and gets special handling in MergeRPTypes.
|
||||
RP_TYPE_BACKBUFFER, // For the backbuffer we can always use CLEAR/DONT_CARE, so bandwidth cost for a depth channel is negligible.
|
||||
|
||||
@ -67,12 +73,18 @@ enum RenderPassType {
|
||||
RP_TYPE_COUNT,
|
||||
};
|
||||
|
||||
// Hm, soon time to exploit the bit properties in these..
|
||||
|
||||
inline bool RenderPassTypeHasDepth(RenderPassType type) {
|
||||
return type == RP_TYPE_BACKBUFFER || type == RP_TYPE_COLOR_DEPTH || type == RP_TYPE_COLOR_DEPTH_INPUT;
|
||||
return type == RP_TYPE_BACKBUFFER || type == RP_TYPE_COLOR_DEPTH || type == RP_TYPE_COLOR_DEPTH_INPUT || type == RP_TYPE_MULTIVIEW_COLOR_DEPTH || type == RP_TYPE_MULTIVIEW_COLOR_DEPTH_INPUT;
|
||||
}
|
||||
|
||||
inline bool RenderPassTypeHasInput(RenderPassType type) {
|
||||
return type == RP_TYPE_COLOR_INPUT || type == RP_TYPE_COLOR_DEPTH_INPUT;
|
||||
return type == RP_TYPE_COLOR_INPUT || type == RP_TYPE_COLOR_DEPTH_INPUT || type == RP_TYPE_MULTIVIEW_COLOR_INPUT || type == RP_TYPE_MULTIVIEW_COLOR_DEPTH_INPUT;
|
||||
}
|
||||
|
||||
inline bool RenderPassTypeHasMultiView(RenderPassType type) {
|
||||
return type == RP_TYPE_MULTIVIEW_COLOR || type == RP_TYPE_MULTIVIEW_COLOR_DEPTH || type == RP_TYPE_MULTIVIEW_COLOR_INPUT || type == RP_TYPE_MULTIVIEW_COLOR_DEPTH_INPUT;
|
||||
}
|
||||
|
||||
struct VkRenderData {
|
||||
|
@ -1295,7 +1295,7 @@ void TextureCacheCommon::LoadClut(u32 clutAddr, u32 loadBytes) {
|
||||
desc.height = 1;
|
||||
desc.depth = 1;
|
||||
desc.z_stencil = false;
|
||||
desc.numColorAttachments = 1;
|
||||
desc.numLayers = 1;
|
||||
desc.tag = "dynamic_clut";
|
||||
dynamicClutFbo_ = draw_->CreateFramebuffer(desc);
|
||||
desc.tag = "dynamic_clut_temp";
|
||||
|
@ -126,9 +126,12 @@ static const char * const boneWeightDecl[9] = {
|
||||
"layout(location = 3) in vec4 w1;\nlayout(location = 4) in vec4 w2;\n",
|
||||
};
|
||||
|
||||
bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguageDesc &compat, Draw::Bugs bugs, uint32_t *attrMask, uint64_t *uniformMask, std::string *errorString) {
|
||||
bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguageDesc &compat, Draw::Bugs bugs, uint32_t *attrMask, uint64_t *uniformMask, VertexShaderFlags *vertexShaderFlags, std::string *errorString) {
|
||||
*attrMask = 0;
|
||||
*uniformMask = 0;
|
||||
if (vertexShaderFlags) {
|
||||
*vertexShaderFlags = (VertexShaderFlags)0;
|
||||
}
|
||||
|
||||
bool highpFog = false;
|
||||
bool highpTexcoord = false;
|
||||
|
@ -25,7 +25,13 @@
|
||||
|
||||
struct VShaderID;
|
||||
|
||||
bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguageDesc &compat, const Draw::Bugs bugs, uint32_t *attrMask, uint64_t *uniformMask, std::string *errorString);
|
||||
// Can technically be deduced from the vertex shader ID, but this is safer.
|
||||
enum class VertexShaderFlags : u32 {
|
||||
MULTI_VIEW = 1,
|
||||
};
|
||||
ENUM_CLASS_BITOPS(VertexShaderFlags);
|
||||
|
||||
bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguageDesc &compat, const Draw::Bugs bugs, uint32_t *attrMask, uint64_t *uniformMask, VertexShaderFlags *vertexShaderFlags, std::string *errorString);
|
||||
|
||||
// D3D9 constants.
|
||||
enum {
|
||||
|
@ -212,7 +212,7 @@ void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **
|
||||
std::string genErrorString;
|
||||
uint32_t attrMask;
|
||||
uint64_t uniformMask;
|
||||
GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &attrMask, &uniformMask, &genErrorString);
|
||||
GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &attrMask, &uniformMask, nullptr, &genErrorString);
|
||||
_assert_msg_(strlen(codeBuffer_) < CODE_BUFFER_SIZE, "VS length error: %d", (int)strlen(codeBuffer_));
|
||||
vs = new D3D11VertexShader(device_, featureLevel_, VSID, codeBuffer_, vertType, useHWTransform);
|
||||
vsCache_[VSID] = vs;
|
||||
|
@ -581,7 +581,7 @@ VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellat
|
||||
std::string genErrorString;
|
||||
uint32_t attrMask;
|
||||
uint64_t uniformMask;
|
||||
if (GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &attrMask, &uniformMask, &genErrorString)) {
|
||||
if (GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &attrMask, &uniformMask, nullptr, &genErrorString)) {
|
||||
vs = new VSShader(device_, VSID, codeBuffer_, useHWTransform);
|
||||
}
|
||||
if (!vs || vs->Failed()) {
|
||||
@ -606,7 +606,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_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &attrMask, &uniformMask, &genErrorString);
|
||||
bool success = GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &attrMask, &uniformMask, nullptr, &genErrorString);
|
||||
_assert_(success);
|
||||
vs = new VSShader(device_, VSID, codeBuffer_, false);
|
||||
}
|
||||
|
@ -743,7 +743,7 @@ Shader *ShaderManagerGLES::CompileVertexShader(VShaderID VSID) {
|
||||
uint32_t attrMask;
|
||||
uint64_t uniformMask;
|
||||
std::string errorString;
|
||||
if (!GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &attrMask, &uniformMask, &errorString)) {
|
||||
if (!GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &attrMask, &uniformMask, nullptr, &errorString)) {
|
||||
ERROR_LOG(G3D, "Shader gen error: %s", errorString.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -336,6 +336,9 @@ VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VulkanRenderManager *
|
||||
if (fs->Flags() & FragmentShaderFlags::INPUT_ATTACHMENT) {
|
||||
pipelineFlags |= PipelineFlags::USES_INPUT_ATTACHMENT;
|
||||
}
|
||||
if (vs->Flags() & VertexShaderFlags::MULTI_VIEW) {
|
||||
pipelineFlags |= PipelineFlags::USES_MULTIVIEW;
|
||||
}
|
||||
|
||||
VulkanPipeline *pipeline = CreateVulkanPipeline(
|
||||
renderManager, pipelineCache_, layout, pipelineFlags,
|
||||
|
@ -135,8 +135,8 @@ std::string VulkanFragmentShader::GetShaderString(DebugShaderStringType type) co
|
||||
}
|
||||
}
|
||||
|
||||
VulkanVertexShader::VulkanVertexShader(VulkanContext *vulkan, VShaderID id, const char *code, bool useHWTransform)
|
||||
: vulkan_(vulkan), useHWTransform_(useHWTransform), id_(id) {
|
||||
VulkanVertexShader::VulkanVertexShader(VulkanContext *vulkan, VShaderID id, VertexShaderFlags flags, const char *code, bool useHWTransform)
|
||||
: vulkan_(vulkan), useHWTransform_(useHWTransform), flags_(flags), id_(id) {
|
||||
source_ = code;
|
||||
module_ = CompileShaderModuleAsync(vulkan, VK_SHADER_STAGE_VERTEX_BIT, source_.c_str(), new std::string(VertexShaderDesc(id)));
|
||||
if (!module_) {
|
||||
@ -331,10 +331,11 @@ void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader
|
||||
std::string genErrorString;
|
||||
uint64_t uniformMask = 0; // Not used
|
||||
uint32_t attributeMask = 0; // Not used
|
||||
bool success = GenerateVertexShader(VSID, codeBuffer_, compat_, draw_->GetBugs(), &attributeMask, &uniformMask, &genErrorString);
|
||||
VertexShaderFlags flags{};
|
||||
bool success = GenerateVertexShader(VSID, codeBuffer_, compat_, draw_->GetBugs(), &attributeMask, &uniformMask, &flags, &genErrorString);
|
||||
_assert_msg_(success, "VS gen error: %s", genErrorString.c_str());
|
||||
_assert_msg_(strlen(codeBuffer_) < CODE_BUFFER_SIZE, "VS length error: %d", (int)strlen(codeBuffer_));
|
||||
vs = new VulkanVertexShader(vulkan, VSID, codeBuffer_, useHWTransform);
|
||||
vs = new VulkanVertexShader(vulkan, VSID, flags, codeBuffer_, useHWTransform);
|
||||
vsCache_.Insert(VSID, vs);
|
||||
}
|
||||
|
||||
@ -343,7 +344,7 @@ void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader
|
||||
// Fragment shader not in cache. Let's compile it.
|
||||
std::string genErrorString;
|
||||
uint64_t uniformMask = 0; // Not used
|
||||
FragmentShaderFlags flags;
|
||||
FragmentShaderFlags flags{};
|
||||
bool success = GenerateFragmentShader(FSID, codeBuffer_, compat_, draw_->GetBugs(), &uniformMask, &flags, &genErrorString);
|
||||
_assert_msg_(success, "FS gen error: %s", genErrorString.c_str());
|
||||
_assert_msg_(strlen(codeBuffer_) < CODE_BUFFER_SIZE, "FS length error: %d", (int)strlen(codeBuffer_));
|
||||
@ -515,11 +516,12 @@ bool ShaderManagerVulkan::LoadCache(FILE *f) {
|
||||
std::string genErrorString;
|
||||
uint32_t attributeMask = 0;
|
||||
uint64_t uniformMask = 0;
|
||||
if (!GenerateVertexShader(id, codeBuffer_, compat_, draw_->GetBugs(), &attributeMask, &uniformMask, &genErrorString)) {
|
||||
VertexShaderFlags flags;
|
||||
if (!GenerateVertexShader(id, codeBuffer_, compat_, draw_->GetBugs(), &attributeMask, &uniformMask, &flags, &genErrorString)) {
|
||||
return false;
|
||||
}
|
||||
_assert_msg_(strlen(codeBuffer_) < CODE_BUFFER_SIZE, "VS length error: %d", (int)strlen(codeBuffer_));
|
||||
VulkanVertexShader *vs = new VulkanVertexShader(vulkan, id, codeBuffer_, useHWTransform);
|
||||
VulkanVertexShader *vs = new VulkanVertexShader(vulkan, id, flags, codeBuffer_, useHWTransform);
|
||||
vsCache_.Insert(id, vs);
|
||||
}
|
||||
uint32_t vendorID = vulkan->GetPhysicalDeviceProperties().properties.vendorID;
|
||||
|
@ -61,13 +61,14 @@ protected:
|
||||
|
||||
class VulkanVertexShader {
|
||||
public:
|
||||
VulkanVertexShader(VulkanContext *vulkan, VShaderID id, const char *code, bool useHWTransform);
|
||||
VulkanVertexShader(VulkanContext *vulkan, VShaderID id, VertexShaderFlags flags, const char *code, bool useHWTransform);
|
||||
~VulkanVertexShader();
|
||||
|
||||
const std::string &source() const { return source_; }
|
||||
|
||||
bool Failed() const { return failed_; }
|
||||
bool UseHWTransform() const { return useHWTransform_; }
|
||||
bool UseHWTransform() const { return useHWTransform_; } // TODO: Roll into flags
|
||||
VertexShaderFlags Flags() const { return flags_; }
|
||||
|
||||
std::string GetShaderString(DebugShaderStringType type) const;
|
||||
Promise<VkShaderModule> *GetModule() { return module_; }
|
||||
@ -81,6 +82,7 @@ protected:
|
||||
bool failed_ = false;
|
||||
bool useHWTransform_;
|
||||
VShaderID id_;
|
||||
VertexShaderFlags flags_;
|
||||
};
|
||||
|
||||
class VulkanGeometryShader {
|
||||
|
@ -67,27 +67,27 @@ bool GenerateVShader(VShaderID id, char *buffer, ShaderLanguage lang, Draw::Bugs
|
||||
case ShaderLanguage::GLSL_VULKAN:
|
||||
{
|
||||
ShaderLanguageDesc compat(ShaderLanguage::GLSL_VULKAN);
|
||||
return GenerateVertexShader(id, buffer, compat, bugs, &attrMask, &uniformMask, errorString);
|
||||
return GenerateVertexShader(id, buffer, compat, bugs, &attrMask, &uniformMask, nullptr, errorString);
|
||||
}
|
||||
case ShaderLanguage::GLSL_1xx:
|
||||
{
|
||||
ShaderLanguageDesc compat(ShaderLanguage::GLSL_1xx);
|
||||
return GenerateVertexShader(id, buffer, compat, bugs, &attrMask, &uniformMask, errorString);
|
||||
return GenerateVertexShader(id, buffer, compat, bugs, &attrMask, &uniformMask, nullptr, errorString);
|
||||
}
|
||||
case ShaderLanguage::GLSL_3xx:
|
||||
{
|
||||
ShaderLanguageDesc compat(ShaderLanguage::GLSL_3xx);
|
||||
return GenerateVertexShader(id, buffer, compat, bugs, &attrMask, &uniformMask, errorString);
|
||||
return GenerateVertexShader(id, buffer, compat, bugs, &attrMask, &uniformMask, nullptr, errorString);
|
||||
}
|
||||
case ShaderLanguage::HLSL_D3D9:
|
||||
{
|
||||
ShaderLanguageDesc compat(ShaderLanguage::HLSL_D3D9);
|
||||
return GenerateVertexShader(id, buffer, compat, bugs, &attrMask, &uniformMask, errorString);
|
||||
return GenerateVertexShader(id, buffer, compat, bugs, &attrMask, &uniformMask, nullptr, errorString);
|
||||
}
|
||||
case ShaderLanguage::HLSL_D3D11:
|
||||
{
|
||||
ShaderLanguageDesc compat(ShaderLanguage::HLSL_D3D11);
|
||||
return GenerateVertexShader(id, buffer, compat, bugs, &attrMask, &uniformMask, errorString);
|
||||
return GenerateVertexShader(id, buffer, compat, bugs, &attrMask, &uniformMask, nullptr, errorString);
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user