Merge pull request #16291 from hrydgard/frame-desc-set

Vulkan: Reserve descriptor set 0 for frame-global data, move everything else to set 1
This commit is contained in:
Henrik Rydgård 2022-10-28 18:02:27 +02:00 committed by GitHub
commit ac818d9639
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 147 additions and 63 deletions

View File

@ -98,7 +98,7 @@ R"(#version 450
)";
static const char *vulkanUboDecl = R"(
layout (std140, set = 0, binding = 0) uniform Data {
layout (std140, set = 1, binding = 0) uniform Data {
vec2 u_texelDelta;
vec2 u_pixelDelta;
vec4 u_time;
@ -187,11 +187,11 @@ bool ConvertToVulkanGLSL(std::string *dest, TranslatedShaderMetadata *destMetada
continue;
} else if (line.find("uniform sampler2D") == 0) {
if (sscanf(line.c_str(), "uniform sampler2D sampler%d", &num) == 1)
line = StringFromFormat("layout(set = 0, binding = %d) ", num + 1) + line;
line = StringFromFormat("layout(set = 1, binding = %d) ", num + 1) + line;
else if (line.find("sampler0") != line.npos)
line = "layout(set = 0, binding = 1) " + line;
line = "layout(set = 1, binding = 1) " + line;
else
line = "layout(set = 0, binding = 2) " + line;
line = "layout(set = 1, binding = 2) " + line;
} else if (line.find("uniform ") != std::string::npos) {
continue;
} else if (2 == sscanf(line.c_str(), "varying vec%d v_texcoord%d;", &vecSize, &num)) {

View File

@ -326,7 +326,7 @@ void ShaderWriter::BeginFSMain(Slice<UniformDef> uniforms, Slice<VaryingDef> var
}
C("layout(location = 0, index = 0) out vec4 fragColor0;\n");
if (!uniforms.is_empty()) {
C("layout(std140, set = 0, binding = 0) uniform bufferVals {\n");
C("layout(std140, set = 1, binding = 0) uniform bufferVals {\n");
for (auto &uniform : uniforms) {
F("%s %s;\n", uniform.type, uniform.name);
}
@ -480,9 +480,9 @@ void ShaderWriter::DeclareTexture2D(const SamplerDef &def) {
case GLSL_VULKAN:
// texBindingBase_ is used for the thin3d descriptor set layout, where they start at 1.
if (def.flags & SamplerFlags::ARRAY_ON_VULKAN) {
F("layout(set = 0, binding = %d) uniform sampler2DArray %s;\n", def.binding + texBindingBase_, def.name);
F("layout(set = 1, binding = %d) uniform sampler2DArray %s;\n", def.binding + texBindingBase_, def.name);
} else {
F("layout(set = 0, binding = %d) uniform sampler2D %s;\n", def.binding + texBindingBase_, def.name);
F("layout(set = 1, binding = %d) uniform sampler2D %s;\n", def.binding + texBindingBase_, def.name);
}
break;
default:

View File

@ -1567,7 +1567,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
case VKRRenderCommand::DRAW_INDEXED:
{
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &c.drawIndexed.ds, c.drawIndexed.numUboOffsets, c.drawIndexed.uboOffsets);
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 1, 1, &c.drawIndexed.ds, c.drawIndexed.numUboOffsets, c.drawIndexed.uboOffsets);
vkCmdBindIndexBuffer(cmd, c.drawIndexed.ibuffer, c.drawIndexed.ioffset, (VkIndexType)c.drawIndexed.indexType);
VkDeviceSize voffset = c.drawIndexed.voffset;
vkCmdBindVertexBuffers(cmd, 0, 1, &c.drawIndexed.vbuffer, &voffset);
@ -1576,7 +1576,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
}
case VKRRenderCommand::DRAW:
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &c.draw.ds, c.draw.numUboOffsets, c.draw.uboOffsets);
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 1, 1, &c.draw.ds, c.draw.numUboOffsets, c.draw.uboOffsets);
if (c.draw.vbuffer) {
vkCmdBindVertexBuffers(cmd, 0, 1, &c.draw.vbuffer, &c.draw.voffset);
}
@ -1625,6 +1625,10 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
}
break;
case VKRRenderCommand::BIND_DESCRIPTOR_SET:
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, c.bindDescSet.pipelineLayout, c.bindDescSet.setNumber, 1, &c.bindDescSet.set, 0, nullptr);
break;
default:
ERROR_LOG(G3D, "Unimpl queue command");
break;

View File

@ -39,6 +39,7 @@ enum class VKRRenderCommand : uint8_t {
PUSH_CONSTANTS,
SELF_DEPENDENCY_BARRIER,
DEBUG_ANNOTATION,
BIND_DESCRIPTOR_SET,
NUM_RENDER_COMMANDS,
};
@ -152,6 +153,11 @@ struct VkRenderData {
struct {
const char *annotation;
} debugAnnotation;
struct {
int setNumber;
VkDescriptorSet set;
VkPipelineLayout pipelineLayout;
} bindDescSet;
};
};

View File

@ -270,6 +270,16 @@ public:
compileMutex_.unlock();
}
// Mainly used to bind the frame-global desc set.
// Can be done before binding a pipeline, so not asserting on that.
void BindDescriptorSet(int setNumber, VkDescriptorSet set, VkPipelineLayout pipelineLayout) {
VkRenderData data{ VKRRenderCommand::BIND_DESCRIPTOR_SET };
data.bindDescSet.setNumber = setNumber;
data.bindDescSet.set = set;
data.bindDescSet.pipelineLayout = pipelineLayout;
curRenderStep_->commands.push_back(data);
}
void BindPipeline(VKRGraphicsPipeline *pipeline, PipelineFlags flags, VkPipelineLayout pipelineLayout) {
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER);
_dbg_assert_(pipeline != nullptr);

View File

@ -35,15 +35,22 @@
#include "Core/Config.h"
// We use a simple descriptor set for all rendering: 1 sampler, 1 texture, 1 UBO binding point.
// binding 0 - uniform data
// binding 1 - sampler
// binding 2 - sampler
//
// Vertex data lives in a separate namespace (location = 0, 1, etc)
#include "Common/GPU/Vulkan/VulkanLoader.h"
// We support a frame-global descriptor set, which can be optionally used by other code,
// but is not directly used by thin3d. It has to be defined here though, be in set 0
// and specified in every pipeline layout, otherwise it can't sit undisturbed when other
// descriptor sets are bound on top.
// For descriptor set 1, we use a simple descriptor set for all thin3d rendering: 1 UBO binding point, 3 combined texture/samples.
//
// binding 0 - uniform buffer
// binding 1 - texture/sampler
// binding 2 - texture/sampler
// binding 3 - texture/sampler
//
// Vertex data lives in a separate namespace (location = 0, 1, etc).
using namespace PPSSPP_VK;
namespace Draw {
@ -514,6 +521,7 @@ private:
int curIBufferOffset_ = 0;
VkDescriptorSetLayout descriptorSetLayout_ = VK_NULL_HANDLE;
VkDescriptorSetLayout frameDescSetLayout_ = VK_NULL_HANDLE;
VkPipelineLayout pipelineLayout_ = VK_NULL_HANDLE;
VkPipelineCache pipelineCache_ = VK_NULL_HANDLE;
AutoRef<VKFramebuffer> curFramebuffer_;
@ -921,13 +929,25 @@ VKContext::VKContext(VulkanContext *vulkan)
VkResult res = vkCreateDescriptorSetLayout(device_, &dsl, nullptr, &descriptorSetLayout_);
_assert_(VK_SUCCESS == res);
VkDescriptorSetLayoutBinding frameBindings[1]{};
frameBindings[0].descriptorCount = 1;
frameBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
frameBindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
frameBindings[0].binding = 0;
dsl.bindingCount = ARRAY_SIZE(frameBindings);
dsl.pBindings = frameBindings;
res = vkCreateDescriptorSetLayout(device_, &dsl, nullptr, &frameDescSetLayout_);
_dbg_assert_(VK_SUCCESS == res);
vulkan_->SetDebugName(descriptorSetLayout_, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, "thin3d_d_layout");
VkPipelineLayoutCreateInfo pl = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
pl.pPushConstantRanges = nullptr;
pl.pushConstantRangeCount = 0;
pl.setLayoutCount = 1;
pl.pSetLayouts = &descriptorSetLayout_;
VkDescriptorSetLayout setLayouts[2] = { frameDescSetLayout_, descriptorSetLayout_ };
pl.setLayoutCount = ARRAY_SIZE(setLayouts);
pl.pSetLayouts = setLayouts;
res = vkCreatePipelineLayout(device_, &pl, nullptr, &pipelineLayout_);
_assert_(VK_SUCCESS == res);
@ -947,6 +967,7 @@ VKContext::~VKContext() {
delete frame_[i].pushBuffer;
}
vulkan_->Delete().QueueDeleteDescriptorSetLayout(descriptorSetLayout_);
vulkan_->Delete().QueueDeleteDescriptorSetLayout(frameDescSetLayout_);
vulkan_->Delete().QueueDeletePipelineLayout(pipelineLayout_);
vulkan_->Delete().QueueDeletePipelineCache(pipelineCache_);
}
@ -1681,6 +1702,11 @@ uint64_t VKContext::GetNativeObject(NativeObject obj, void *srcObject) {
_dbg_assert_(layer < curFramebuffer_->Layers());
return (uint64_t)curFramebuffer_->GetFB()->color.texLayerViews[layer];
}
case NativeObject::FRAME_DATA_DESC_SET_LAYOUT:
return (uint64_t)frameDescSetLayout_;
case NativeObject::THIN3D_PIPELINE_LAYOUT:
return (uint64_t)pipelineLayout_;
default:
Crash();
return 0;

View File

@ -137,7 +137,7 @@ static const std::vector<ShaderSource> fsTexCol = {
"layout(location = 0) in vec4 oColor0;\n"
"layout(location = 1) in vec2 oTexCoord0;\n"
"layout(location = 0) out vec4 fragColor0;\n"
"layout(set = 0, binding = 1) uniform sampler2D Sampler0;\n"
"layout(set = 1, binding = 1) uniform sampler2D Sampler0;\n"
"void main() { fragColor0 = texture(Sampler0, oTexCoord0) * oColor0; }\n"
}
};
@ -181,7 +181,7 @@ static const std::vector<ShaderSource> fsTexColRBSwizzle = {
"layout(location = 0) in vec4 oColor0;\n"
"layout(location = 1) in vec2 oTexCoord0;\n"
"layout(location = 0) out vec4 fragColor0\n;"
"layout(set = 0, binding = 1) uniform sampler2D Sampler0;\n"
"layout(set = 1, binding = 1) uniform sampler2D Sampler0;\n"
"void main() { fragColor0 = texture(Sampler0, oTexCoord0).bgra * oColor0; }\n"
}
};
@ -270,7 +270,7 @@ static const std::vector<ShaderSource> vsCol = {
R"(#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (std140, set = 0, binding = 0) uniform bufferVals {
layout (std140, set = 1, binding = 0) uniform bufferVals {
mat4 WorldViewProj;
vec2 TintSaturation;
} myBufferVals;
@ -416,7 +416,7 @@ VS_OUTPUT main(VS_INPUT input) {
R"(#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (std140, set = 0, binding = 0) uniform bufferVals {
layout (std140, set = 1, binding = 0) uniform bufferVals {
mat4 WorldViewProj;
vec2 TintSaturation;
} myBufferVals;

View File

@ -249,6 +249,8 @@ enum class NativeObject {
RENDER_MANAGER,
TEXTURE_VIEW,
NULL_IMAGEVIEW,
FRAME_DATA_DESC_SET_LAYOUT,
THIN3D_PIPELINE_LAYOUT,
};
enum FBChannel {

View File

@ -185,23 +185,23 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
WRITE(p, "layout (depth_unchanged) out float gl_FragDepth;\n");
}
WRITE(p, "layout (std140, set = 0, binding = 3) uniform baseUBO {\n%s};\n", ub_baseStr);
WRITE(p, "layout (std140, set = 1, binding = 3) uniform baseUBO {\n%s};\n", ub_baseStr);
if (doTexture) {
WRITE(p, "layout (binding = 0) uniform %s%s tex;\n", texture3D ? "sampler3D" : "sampler2D", arrayTexture ? "Array" : "");
WRITE(p, "layout (set = 1, binding = 0) uniform %s%s tex;\n", texture3D ? "sampler3D" : "sampler2D", arrayTexture ? "Array" : "");
}
if (readFramebufferTex) {
// The framebuffer texture is always bound as an array.
p.C("layout (binding = 1) uniform sampler2DArray fbotex;\n");
p.C("layout (set = 1, binding = 1) uniform sampler2DArray fbotex;\n");
} else if (fetchFramebuffer) {
p.C("layout (input_attachment_index = 0, binding = 9) uniform subpassInput inputColor;\n");
p.C("layout (input_attachment_index = 0, set = 1, binding = 9) uniform subpassInput inputColor;\n");
if (fragmentShaderFlags) {
*fragmentShaderFlags |= FragmentShaderFlags::INPUT_ATTACHMENT;
}
}
if (shaderDepalMode != ShaderDepalMode::OFF) {
WRITE(p, "layout (binding = 2) uniform sampler2D pal;\n");
WRITE(p, "layout (set = 1, binding = 2) uniform sampler2D pal;\n");
}
// Note: the precision qualifiers must match the vertex shader!

View File

@ -233,14 +233,13 @@ bool PresentationCommon::UpdatePostShader() {
if (gstate_c.Use(GPU_USE_SIMPLE_STEREO_PERSPECTIVE)) {
const ShaderInfo *stereoShaderInfo = GetPostShaderInfo(g_Config.sStereoToMonoShader);
bool result = CompilePostShader(stereoShaderInfo, &stereoPipeline_);
if (!result) {
// We won't have a stereo shader. We have to check for this later.
delete stereoShaderInfo_;
stereoShaderInfo_ = nullptr;
stereoPipeline_ = nullptr;
if (stereoShaderInfo) {
bool result = CompilePostShader(stereoShaderInfo, &stereoPipeline_);
if (result) {
stereoShaderInfo_ = new ShaderInfo(*stereoShaderInfo);
}
} else {
stereoShaderInfo_ = new ShaderInfo(*stereoShaderInfo);
WARN_LOG(G3D, "Failed to get info about stereo shader '%s'", g_Config.sStereoToMonoShader.c_str());
}
}
@ -296,6 +295,8 @@ bool PresentationCommon::UpdatePostShader() {
}
bool PresentationCommon::CompilePostShader(const ShaderInfo *shaderInfo, Draw::Pipeline **outPipeline) const {
_assert_(shaderInfo);
std::string vsSourceGLSL = ReadShaderSrc(shaderInfo->vertexShaderFile);
std::string fsSourceGLSL = ReadShaderSrc(shaderInfo->fragmentShaderFile);
if (vsSourceGLSL.empty() || fsSourceGLSL.empty()) {

View File

@ -133,12 +133,12 @@ R"( mat3x4 u_bone0; mat3x4 u_bone1; mat3x4 u_bone2; mat3x4 u_bone3; mat3x4 u_bon
static const char * const ub_frame_globalstr =
R"( vec4 unused;
R"( vec4 stereoParams;
)";
// VR stuff will go here.
// Frame-global uniforms.
struct UB_FrameGlobal {
float unused[4];
float stereoParams[4];
};
void CalcCullRange(float minValues[4], float maxValues[4], bool flipViewport, bool hasNegZ);

View File

@ -249,11 +249,11 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
if (compat.shaderLanguage == GLSL_VULKAN) {
WRITE(p, "\n");
WRITE(p, "layout (std140, set = 0, binding = 3) uniform baseVars {\n%s};\n", ub_baseStr);
WRITE(p, "layout (std140, set = 1, binding = 3) uniform baseVars {\n%s};\n", ub_baseStr);
if (enableLighting || doShadeMapping)
WRITE(p, "layout (std140, set = 0, binding = 4) uniform lightVars {\n%s};\n", ub_vs_lightsStr);
WRITE(p, "layout (std140, set = 1, binding = 4) uniform lightVars {\n%s};\n", ub_vs_lightsStr);
if (enableBones)
WRITE(p, "layout (std140, set = 0, binding = 5) uniform boneVars {\n%s};\n", ub_vs_bonesStr);
WRITE(p, "layout (std140, set = 1, binding = 5) uniform boneVars {\n%s};\n", ub_vs_bonesStr);
if (enableBones) {
WRITE(p, "%s", boneWeightDecl[numBoneWeights]);
@ -631,7 +631,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
WRITE(p, " vec4 tex;\n");
WRITE(p, " vec4 col;\n");
WRITE(p, "};\n");
WRITE(p, "layout (std430, set = 0, binding = 6) readonly buffer s_tess_data {\n");
WRITE(p, "layout (std430, set = 1, binding = 6) readonly buffer s_tess_data {\n");
WRITE(p, " TessData tess_data[];\n");
WRITE(p, "};\n");
@ -639,10 +639,10 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
WRITE(p, " vec4 basis;\n");
WRITE(p, " vec4 deriv;\n");
WRITE(p, "};\n");
WRITE(p, "layout (std430, set = 0, binding = 7) readonly buffer s_tess_weights_u {\n");
WRITE(p, "layout (std430, set = 1, binding = 7) readonly buffer s_tess_weights_u {\n");
WRITE(p, " TessWeight tess_weights_u[];\n");
WRITE(p, "};\n");
WRITE(p, "layout (std430, set = 0, binding = 8) readonly buffer s_tess_weights_v {\n");
WRITE(p, "layout (std430, set = 1, binding = 8) readonly buffer s_tess_weights_v {\n");
WRITE(p, " TessWeight tess_weights_v[];\n");
WRITE(p, "};\n");
} else if (ShaderLanguageIsOpenGL(compat.shaderLanguage)) {

View File

@ -154,7 +154,7 @@ void DrawEngineVulkan::InitDeviceObjects() {
static constexpr int DEFAULT_DESC_POOL_SIZE = 512;
std::vector<VkDescriptorPoolSize> dpTypes;
dpTypes.resize(4);
dpTypes.resize(5);
dpTypes[0].descriptorCount = DEFAULT_DESC_POOL_SIZE * 3;
dpTypes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
dpTypes[1].descriptorCount = DEFAULT_DESC_POOL_SIZE * 3; // Don't use these for tess anymore, need max three per set.
@ -163,6 +163,8 @@ void DrawEngineVulkan::InitDeviceObjects() {
dpTypes[2].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
dpTypes[3].descriptorCount = DEFAULT_DESC_POOL_SIZE; // TODO: Use a separate layout when no spline stuff is needed to reduce the need for these.
dpTypes[3].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
dpTypes[4].descriptorCount = 1; // For the frame global uniform buffer.
dpTypes[4].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
VkDescriptorPoolCreateInfo dp{ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO };
// Don't want to mess around with individually freeing these.
@ -185,10 +187,12 @@ void DrawEngineVulkan::InitDeviceObjects() {
VkPipelineLayoutCreateInfo pl{ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
pl.pPushConstantRanges = nullptr;
pl.pushConstantRangeCount = 0;
VkDescriptorSetLayout layouts[1] = { descriptorSetLayout_ };
VkDescriptorSetLayout frameDescSetLayout = (VkDescriptorSetLayout)draw_->GetNativeObject(Draw::NativeObject::FRAME_DATA_DESC_SET_LAYOUT);
VkDescriptorSetLayout layouts[2] = { frameDescSetLayout, descriptorSetLayout_};
pl.setLayoutCount = ARRAY_SIZE(layouts);
pl.pSetLayouts = layouts;
pl.flags = 0;
res = vkCreatePipelineLayout(device, &pl, nullptr, &pipelineLayout_);
_dbg_assert_(VK_SUCCESS == res);
@ -310,7 +314,8 @@ void DrawEngineVulkan::BeginFrame() {
frame->pushVertex->Begin(vulkan);
frame->pushIndex->Begin(vulkan);
// TODO: How can we make this nicer...
frame->frameDescSetUpdated = false;
tessDataTransferVulkan->SetPushBuffer(frame->pushUBO);
DirtyAllUBOs();
@ -1014,6 +1019,30 @@ void DrawEngineVulkan::DoFlush() {
}
void DrawEngineVulkan::UpdateUBOs(FrameData *frame) {
if (!frame->frameDescSetUpdated) {
// Push frame global constants.
UB_FrameGlobal frameConstants{};
VkDescriptorBufferInfo frameConstantsBufInfo;
frame->pushUBO->PushUBOData(frameConstants, &frameConstantsBufInfo);
VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT);
VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
VkDescriptorSetLayout frameDescSetLayout = (VkDescriptorSetLayout)draw_->GetNativeObject(Draw::NativeObject::FRAME_DATA_DESC_SET_LAYOUT);
VkDescriptorSet frameDescSet = frame->descPool.Allocate(1, &frameDescSetLayout, "frame_desc_set");
VkWriteDescriptorSet descWrite{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };
descWrite.descriptorCount = 1;
descWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descWrite.dstBinding = 0;
descWrite.dstSet = frameDescSet;
descWrite.pBufferInfo = &frameConstantsBufInfo;
vkUpdateDescriptorSets(vulkan->GetDevice(), 1, &descWrite, 0, nullptr);
renderManager->BindDescriptorSet(0, frameDescSet, pipelineLayout_);
frame->frameDescSetUpdated = true;
}
if ((dirtyUniforms_ & DIRTY_BASE_UNIFORMS) || baseBuf == VK_NULL_HANDLE) {
baseUBOOffset = shaderManager_->PushBaseBuffer(frame->pushUBO, &baseBuf);
dirtyUniforms_ &= ~DIRTY_BASE_UNIFORMS;

View File

@ -211,7 +211,8 @@ private:
Draw::DrawContext *draw_;
// We use a shared descriptor set layout for all PSP draws.
// We use a shared descriptor set layouts for all PSP draws.
// Descriptors created from descriptorSetLayout_ is rebound all the time at set 1.
VkDescriptorSetLayout descriptorSetLayout_;
VkPipelineLayout pipelineLayout_;
@ -254,6 +255,8 @@ private:
VulkanPushBuffer *pushVertex = nullptr;
VulkanPushBuffer *pushIndex = nullptr;
bool frameDescSetUpdated = false;
// We do rolling allocation and reset instead of caching across frames. That we might do later.
DenseHashMap<DescriptorSetKey, VkDescriptorSet, (VkDescriptorSet)VK_NULL_HANDLE> descSets;

View File

@ -65,9 +65,9 @@ const char *uploadShader = R"(
// hardware vendors.
layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
uniform layout(binding = 0, rgba8) writeonly image2D img;
uniform layout(set = 1, binding = 0, rgba8) writeonly image2D img;
layout(std430, binding = 1) buffer Buf {
layout(std430, set = 1, binding = 1) buffer Buf {
uint data[];
} buf;
@ -251,7 +251,7 @@ void TextureCacheVulkan::DeviceRestore(Draw::DrawContext *draw) {
CompileScalingShader();
computeShaderManager_.DeviceRestore(vulkan);
computeShaderManager_.DeviceRestore(draw);
}
void TextureCacheVulkan::NotifyConfigChanged() {
@ -626,7 +626,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
VK_PROFILE_BEGIN(vulkan, cmdInit, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
"Compute Upload: %dx%d->%dx%d", mipUnscaledWidth, mipUnscaledHeight, mipWidth, mipHeight);
vkCmdBindPipeline(cmdInit, VK_PIPELINE_BIND_POINT_COMPUTE, computeShaderManager_.GetPipeline(uploadCS_));
vkCmdBindDescriptorSets(cmdInit, VK_PIPELINE_BIND_POINT_COMPUTE, computeShaderManager_.GetPipelineLayout(), 0, 1, &descSet, 0, nullptr);
vkCmdBindDescriptorSets(cmdInit, VK_PIPELINE_BIND_POINT_COMPUTE, computeShaderManager_.GetPipelineLayout(), 1, 1, &descSet, 0, nullptr);
vkCmdPushConstants(cmdInit, computeShaderManager_.GetPipelineLayout(), VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(params), &params);
vkCmdDispatch(cmdInit, (mipUnscaledWidth + 7) / 8, (mipUnscaledHeight + 7) / 8, 1);
VK_PROFILE_END(vulkan, cmdInit, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);

View File

@ -56,7 +56,7 @@ VulkanComputeShaderManager::VulkanComputeShaderManager(VulkanContext *vulkan) :
}
VulkanComputeShaderManager::~VulkanComputeShaderManager() {}
void VulkanComputeShaderManager::InitDeviceObjects() {
void VulkanComputeShaderManager::InitDeviceObjects(Draw::DrawContext *draw) {
VkPipelineCacheCreateInfo pc{ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO };
VkResult res = vkCreatePipelineCache(vulkan_->GetDevice(), &pc, nullptr, &pipelineCache_);
_assert_(VK_SUCCESS == res);
@ -106,8 +106,10 @@ void VulkanComputeShaderManager::InitDeviceObjects() {
VkPipelineLayoutCreateInfo pl = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
pl.pPushConstantRanges = &push;
pl.pushConstantRangeCount = 1;
pl.setLayoutCount = 1;
pl.pSetLayouts = &descriptorSetLayout_;
VkDescriptorSetLayout frameDescSetLayout = (VkDescriptorSetLayout)draw->GetNativeObject(Draw::NativeObject::FRAME_DATA_DESC_SET_LAYOUT);
VkDescriptorSetLayout setLayouts[2] = { frameDescSetLayout, descriptorSetLayout_ };
pl.setLayoutCount = ARRAY_SIZE(setLayouts);
pl.pSetLayouts = setLayouts;
pl.flags = 0;
res = vkCreatePipelineLayout(device, &pl, nullptr, &pipelineLayout_);
_assert_(VK_SUCCESS == res);

View File

@ -25,6 +25,7 @@
#include "Common/GPU/Vulkan/VulkanImage.h"
#include "Common/GPU/Vulkan/VulkanLoader.h"
#include "Common/GPU/Vulkan/VulkanMemory.h"
#include "Common/GPU/thin3d.h"
extern const VkComponentMapping VULKAN_4444_SWIZZLE;
extern const VkComponentMapping VULKAN_1555_SWIZZLE;
@ -47,9 +48,9 @@ public:
void DeviceLost() {
DestroyDeviceObjects();
}
void DeviceRestore(VulkanContext *vulkan) {
vulkan_ = vulkan;
InitDeviceObjects();
void DeviceRestore(Draw::DrawContext *draw) {
vulkan_ = (VulkanContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT);
InitDeviceObjects(draw);
}
// Note: This doesn't cache. The descriptor is for immediate use only.
@ -63,7 +64,7 @@ public:
void EndFrame();
private:
void InitDeviceObjects();
void InitDeviceObjects(Draw::DrawContext *draw);
void DestroyDeviceObjects();
VulkanContext *vulkan_ = nullptr;

View File

@ -44,7 +44,7 @@ static const std::vector<Draw::ShaderSource> fsDiscard = {
layout(location = 0) in vec4 oColor0;
layout(location = 1) in vec2 oTexCoord0;
layout(location = 0) out vec4 fragColor0;
layout(set = 0, binding = 1) uniform sampler2D Sampler0;
layout(set = 1, binding = 1) uniform sampler2D Sampler0;
void main() {
vec4 color = texture(Sampler0, oTexCoord0) * oColor0;
if (color.a <= 0.0)
@ -86,7 +86,7 @@ static const std::vector<Draw::ShaderSource> fsAdrenoLogicTest = {
layout(location = 0) in vec4 oColor0;
layout(location = 1) in highp vec2 oTexCoord0;
layout(location = 0) out vec4 fragColor0;
layout(set = 0, binding = 1) uniform sampler2D Sampler0;
layout(set = 1, binding = 1) uniform sampler2D Sampler0;
void main() {
vec4 v = texture(Sampler0, oTexCoord0).aaaa * oColor0;
if (v.r < 0.2 && v.g < 0.2 && v.b < 0.2) discard;
@ -117,7 +117,7 @@ static const std::vector<Draw::ShaderSource> vsAdrenoLogicTest = {
"#version 450\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
"#extension GL_ARB_shading_language_420pack : enable\n"
"layout (std140, set = 0, binding = 0) uniform bufferVals {\n"
"layout (std140, set = 1, binding = 0) uniform bufferVals {\n"
" mat4 WorldViewProj;\n"
"} myBufferVals;\n"
"layout (location = 0) in vec4 pos;\n"
@ -173,7 +173,7 @@ static const std::vector<Draw::ShaderSource> fsFlat = {
"layout(location = 0) flat in lowp vec4 oColor0;\n"
"layout(location = 1) in highp vec2 oTexCoord0;\n"
"layout(location = 0) out vec4 fragColor0;\n"
"layout(set = 0, binding = 1) uniform sampler2D Sampler0;\n"
"layout(set = 1, binding = 1) uniform sampler2D Sampler0;\n"
"void main() { fragColor0 = texture(Sampler0, oTexCoord0) * oColor0; }\n"
}
};
@ -214,7 +214,7 @@ static const std::vector<Draw::ShaderSource> vsFlat = {
"#version 450\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
"#extension GL_ARB_shading_language_420pack : enable\n"
"layout (std140, set = 0, binding = 0) uniform bufferVals {\n"
"layout (std140, set = 1, binding = 0) uniform bufferVals {\n"
" mat4 WorldViewProj;\n"
"} myBufferVals;\n"
"layout (location = 0) in vec4 pos;\n"