Merge branch 'postshader' into TemporaryHackishBranch

This commit is contained in:
LunaMoo committed 2020-05-18 02:59:19 +02:00
commit ec632dec68
18 files changed
+142 -84

No files matched your search

+2 -3
View File
@@ -45,7 +45,6 @@ FramebufferManagerCommon::FramebufferManagerCommon(Draw::DrawContext *draw)
: draw_(draw),
displayFormat_(GE_FORMAT_565) {
presentation_ = new PresentationCommon(draw);
UpdateSize();
}
FramebufferManagerCommon::~FramebufferManagerCommon() {
@@ -70,8 +69,8 @@ FramebufferManagerCommon::~FramebufferManagerCommon() {
}
void FramebufferManagerCommon::Init() {
BeginFrame();
presentation_->UpdatePostShader();
// We may need to override the render size if the shader is upscaling or SSAA.
Resized();
}
bool FramebufferManagerCommon::UpdateSize() {
+36 -9
View File
@@ -258,13 +258,10 @@ bool PresentationCommon::BuildPostShader(const ShaderInfo *shaderInfo, const Sha
nextHeight = (int)h;
}
// No depth/stencil for post processing
Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ nextWidth, nextHeight, 1, 1, false, Draw::FBO_8888 });
if (!fbo) {
if (!AllocateFramebuffer(nextWidth, nextHeight)) {
pipeline->Release();
return false;
}
postShaderFramebuffers_.push_back(fbo);
}
postShaderPipelines_.push_back(pipeline);
@@ -272,6 +269,31 @@ bool PresentationCommon::BuildPostShader(const ShaderInfo *shaderInfo, const Sha
return true;
}
bool PresentationCommon::AllocateFramebuffer(int w, int h) {
using namespace Draw;
// First, let's try to find a framebuffer of the right size that is NOT the most recent.
Framebuffer *last = postShaderFramebuffers_.empty() ? nullptr : postShaderFramebuffers_.back();
for (const auto &prev : postShaderFBOUsage_) {
if (prev.w == w && prev.h == h && prev.fbo != last) {
// Great, this one's perfect. Ref it for when we release.
prev.fbo->AddRef();
postShaderFramebuffers_.push_back(prev.fbo);
return true;
}
}
// No depth/stencil for post processing
Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, false, Draw::FBO_8888 });
if (!fbo) {
return false;
}
postShaderFBOUsage_.push_back({ fbo, w, h });
postShaderFramebuffers_.push_back(fbo);
return true;
}
void PresentationCommon::ShowPostShaderError(const std::string &errorString) {
// let's show the first line of the error string as an OSM.
std::set<std::string> blacklistedLines;
@@ -406,6 +428,7 @@ void PresentationCommon::DestroyPostShader() {
DoReleaseVector(postShaderPipelines_);
DoReleaseVector(postShaderFramebuffers_);
postShaderInfo_.clear();
postShaderFBOUsage_.clear();
}
Draw::ShaderModule *PresentationCommon::CompileShaderModule(Draw::ShaderStage stage, ShaderLanguage lang, const std::string &src, std::string *errorString) {
@@ -468,11 +491,11 @@ void PresentationCommon::SourceFramebuffer(Draw::Framebuffer *fb, int bufferWidt
srcHeight_ = bufferHeight;
}
void PresentationCommon::BindSource() {
void PresentationCommon::BindSource(int binding) {
if (srcTexture_) {
draw_->BindTexture(0, srcTexture_);
draw_->BindTexture(binding, srcTexture_);
} else if (srcFramebuffer_) {
draw_->BindFramebufferAsTexture(srcFramebuffer_, 0, Draw::FB_COLOR_BIT, 0);
draw_->BindFramebufferAsTexture(srcFramebuffer_, binding, Draw::FB_COLOR_BIT, 0);
} else {
assert(false);
}
@@ -588,8 +611,9 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u
if (usePostShaderOutput) {
draw_->BindFramebufferAsTexture(postShaderFramebuffers_[i - 1], 0, Draw::FB_COLOR_BIT, 0);
} else {
BindSource();
BindSource(0);
}
BindSource(1);
int nextWidth, nextHeight;
draw_->GetFramebufferDimensions(postShaderFramebuffer, &nextWidth, &nextHeight);
@@ -605,6 +629,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u
Draw::SamplerState *sampler = useNearest || shaderInfo->isUpscalingFilter ? samplerNearest_ : samplerLinear_;
draw_->BindSamplerStates(0, 1, &sampler);
draw_->BindSamplerStates(1, 1, &sampler);
draw_->BindVertexBuffers(0, 1, &vdata_, &postVertsOffset);
draw_->BindIndexBuffer(idata_, 0);
@@ -635,8 +660,9 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u
if (usePostShaderOutput) {
draw_->BindFramebufferAsTexture(postShaderFramebuffers_.back(), 0, Draw::FB_COLOR_BIT, 0);
} else {
BindSource();
BindSource(0);
}
BindSource(1);
if (isFinalAtOutputResolution) {
PostShaderUniforms uniforms;
@@ -653,6 +679,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u
Draw::SamplerState *sampler = useNearest ? samplerNearest_ : samplerLinear_;
draw_->BindSamplerStates(0, 1, &sampler);
draw_->BindSamplerStates(1, 1, &sampler);
auto setViewport = [&](float x, float y, float w, float h) {
Draw::Viewport viewport{ x, y, w, h, 0.0f, 1.0f };
+9 -1
View File
@@ -112,8 +112,9 @@ protected:
Draw::ShaderModule *CompileShaderModule(Draw::ShaderStage stage, ShaderLanguage lang, const std::string &src, std::string *errorString);
Draw::Pipeline *CreatePipeline(std::vector<Draw::ShaderModule *> shaders, bool postShader, const Draw::UniformBufferDesc *uniformDesc);
bool BuildPostShader(const ShaderInfo *shaderInfo, const ShaderInfo *next);
bool AllocateFramebuffer(int w, int h);
void BindSource();
void BindSource(int binding);
void GetCardboardSettings(CardboardSettings *cardboardSettings);
void CalculatePostShaderUniforms(int bufferWidth, int bufferHeight, int targetWidth, int targetHeight, const ShaderInfo *shaderInfo, PostShaderUniforms *uniforms);
@@ -145,4 +146,11 @@ protected:
bool usePostShader_ = false;
bool restorePostShader_ = false;
ShaderLanguage lang_;
struct PrevFBO {
Draw::Framebuffer *fbo;
int w;
int h;
};
std::vector<PrevFBO> postShaderFBOUsage_;
};
+8 -1
View File
@@ -140,6 +140,10 @@ std::string Postprocess(std::string code, ShaderLanguage lang, Draw::ShaderStage
out << "sampler2D sampler0 : register(s0);\n";
continue;
}
if (line == "uniform sampler2D sampler1;" && lang == HLSL_DX9) {
out << "sampler2D sampler1 : register(s1);\n";
continue;
}
if (line.find("uniform float") != std::string::npos) {
continue;
}
@@ -181,7 +185,10 @@ bool ConvertToVulkanGLSL(std::string *dest, TranslatedShaderMetadata *destMetada
if (line.find("uniform bool") != std::string::npos) {
continue;
} else if (line.find("uniform sampler2D") == 0) {
line = "layout(set = 0, binding = 1) " + line;
if (line.find("sampler0") != line.npos)
line = "layout(set = 0, binding = 1) " + line;
else
line = "layout(set = 0, 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)) {
+1 -1
View File
@@ -87,10 +87,10 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
drawEngine_.SetShaderManager(shaderManagerD3D11_);
drawEngine_.SetTextureCache(textureCacheD3D11_);
drawEngine_.SetFramebufferManager(framebufferManagerD3D11_);
framebufferManagerD3D11_->Init();
framebufferManagerD3D11_->SetTextureCache(textureCacheD3D11_);
framebufferManagerD3D11_->SetShaderManager(shaderManagerD3D11_);
framebufferManagerD3D11_->SetDrawEngine(&drawEngine_);
framebufferManagerD3D11_->Init();
textureCacheD3D11_->SetFramebufferManager(framebufferManagerD3D11_);
textureCacheD3D11_->SetDepalShaderCache(depalShaderCache_);
textureCacheD3D11_->SetShaderManager(shaderManagerD3D11_);
+1 -1
View File
@@ -70,10 +70,10 @@ GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
drawEngine_.SetShaderManager(shaderManagerDX9_);
drawEngine_.SetTextureCache(textureCacheDX9_);
drawEngine_.SetFramebufferManager(framebufferManagerDX9_);
framebufferManagerDX9_->Init();
framebufferManagerDX9_->SetTextureCache(textureCacheDX9_);
framebufferManagerDX9_->SetShaderManager(shaderManagerDX9_);
framebufferManagerDX9_->SetDrawEngine(&drawEngine_);
framebufferManagerDX9_->Init();
textureCacheDX9_->SetFramebufferManager(framebufferManagerDX9_);
textureCacheDX9_->SetDepalShaderCache(&depalShaderCache_);
textureCacheDX9_->SetShaderManager(shaderManagerDX9_);
+4 -3
View File
@@ -21,7 +21,8 @@
#include "Common/Log.h"
#include "Common/StringUtils.h"
#include "Core/Reporting.h"
#include "DepalettizeShaderGLES.h"
#include "GPU/GLES/DepalettizeShaderGLES.h"
#include "GPU/GLES/DrawEngineGLES.h"
#include "GPU/GLES/TextureCacheGLES.h"
#include "GPU/Common/DepalettizeShaderCommon.h"
@@ -178,8 +179,8 @@ DepalShader *DepalShaderCacheGLES::GetDepalettizeShader(uint32_t clutMode, GEBuf
queries.push_back({ &depal->u_pal, "pal" });
std::vector<GLRProgram::Initializer> initializer;
initializer.push_back({ &depal->u_tex, 0, 0 });
initializer.push_back({ &depal->u_pal, 0, 3 });
initializer.push_back({ &depal->u_tex, 0, TEX_SLOT_PSP_TEXTURE });
initializer.push_back({ &depal->u_pal, 0, TEX_SLOT_CLUT });
std::vector<GLRShader *> shaders{ vertexShader_, fragShader };
-2
View File
@@ -111,8 +111,6 @@ FramebufferManagerGLES::FramebufferManagerGLES(Draw::DrawContext *draw, GLRender
void FramebufferManagerGLES::Init() {
FramebufferManagerCommon::Init();
// Workaround for upscaling shaders where we force x1 resolution without saving it
Resized();
CompileDraw2DProgram();
}
+1 -1
View File
@@ -71,10 +71,10 @@ GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
drawEngine_.SetTextureCache(textureCacheGL_);
drawEngine_.SetFramebufferManager(framebufferManagerGL_);
drawEngine_.SetFragmentTestCache(&fragmentTestCache_);
framebufferManagerGL_->Init();
framebufferManagerGL_->SetTextureCache(textureCacheGL_);
framebufferManagerGL_->SetShaderManager(shaderManagerGL_);
framebufferManagerGL_->SetDrawEngine(&drawEngine_);
framebufferManagerGL_->Init();
depalShaderCache_.Init();
textureCacheGL_->SetFramebufferManager(framebufferManagerGL_);
textureCacheGL_->SetDepalShaderCache(&depalShaderCache_);
-6
View File
@@ -170,12 +170,6 @@ void FramebufferManagerVulkan::NotifyClear(bool clearColor, bool clearAlpha, boo
}
}
void FramebufferManagerVulkan::Init() {
FramebufferManagerCommon::Init();
// Workaround for upscaling shaders where we force x1 resolution without saving it
Resized();
}
void FramebufferManagerVulkan::DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, int flags) {
float texCoords[8] = {
u0,v0,
-2
View File
@@ -46,8 +46,6 @@ public:
// x,y,w,h are relative to destW, destH which fill out the target completely.
void DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, int flags) override;
virtual void Init() override;
void BeginFrameVulkan(); // there's a BeginFrame in the base class, which this calls
void EndFrame();
+1 -1
View File
@@ -72,10 +72,10 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
drawEngine_.SetShaderManager(shaderManagerVulkan_);
drawEngine_.SetPipelineManager(pipelineManager_);
framebufferManagerVulkan_->SetVulkan2D(&vulkan2D_);
framebufferManagerVulkan_->Init();
framebufferManagerVulkan_->SetTextureCache(textureCacheVulkan_);
framebufferManagerVulkan_->SetDrawEngine(&drawEngine_);
framebufferManagerVulkan_->SetShaderManager(shaderManagerVulkan_);
framebufferManagerVulkan_->Init();
textureCacheVulkan_->SetDepalShaderCache(&depalShaderCache_);
textureCacheVulkan_->SetFramebufferManager(framebufferManagerVulkan_);
textureCacheVulkan_->SetShaderManager(shaderManagerVulkan_);
+3 -3
View File
@@ -926,9 +926,9 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step) {
case GLRRenderCommand::UNIFORMMATRIX:
{
assert(curProgram);
int loc = c.uniform4.loc ? *c.uniform4.loc : -1;
if (c.uniform4.name) {
loc = curProgram->GetUniformLoc(c.uniform4.name);
int loc = c.uniformMatrix4.loc ? *c.uniformMatrix4.loc : -1;
if (c.uniformMatrix4.name) {
loc = curProgram->GetUniformLoc(c.uniformMatrix4.name);
}
if (loc >= 0) {
glUniformMatrix4fv(loc, 1, false, c.uniformMatrix4.m);
+2 -2
View File
@@ -117,13 +117,13 @@ struct GLRRenderData {
} drawIndexed;
struct {
const char *name; // if null, use loc
GLint *loc; // NOTE: This is a pointer so we can immediately use things that are "queried" during program creation.
const GLint *loc; // NOTE: This is a pointer so we can immediately use things that are "queried" during program creation.
GLint count;
float v[4];
} uniform4;
struct {
const char *name; // if null, use loc
GLint *loc;
const GLint *loc;
float m[16];
} uniformMatrix4;
struct {
+5 -5
View File
@@ -630,7 +630,7 @@ public:
curRenderStep_->commands.push_back(data);
}
void SetUniformI(GLint *loc, int count, const int *udata) {
void SetUniformI(const GLint *loc, int count, const int *udata) {
_dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER);
#ifdef _DEBUG
assert(curProgram_);
@@ -642,7 +642,7 @@ public:
curRenderStep_->commands.push_back(data);
}
void SetUniformI1(GLint *loc, int udata) {
void SetUniformI1(const GLint *loc, int udata) {
_dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER);
#ifdef _DEBUG
assert(curProgram_);
@@ -654,7 +654,7 @@ public:
curRenderStep_->commands.push_back(data);
}
void SetUniformF(GLint *loc, int count, const float *udata) {
void SetUniformF(const GLint *loc, int count, const float *udata) {
_dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER);
#ifdef _DEBUG
assert(curProgram_);
@@ -666,7 +666,7 @@ public:
curRenderStep_->commands.push_back(data);
}
void SetUniformF1(GLint *loc, const float udata) {
void SetUniformF1(const GLint *loc, const float udata) {
_dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER);
#ifdef _DEBUG
assert(curProgram_);
@@ -690,7 +690,7 @@ public:
curRenderStep_->commands.push_back(data);
}
void SetUniformM4x4(GLint *loc, const float *udata) {
void SetUniformM4x4(const GLint *loc, const float *udata) {
_dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER);
#ifdef _DEBUG
assert(curProgram_);
+1 -1
View File
@@ -540,7 +540,7 @@ public:
void BindTextures(int start, int count, Texture **textures) override;
void BindSamplerStates(int start, int count, SamplerState **states) override {
for (int i = 0; i < count; ++i) {
D3D9SamplerState *s = static_cast<D3D9SamplerState *>(states[start + i]);
D3D9SamplerState *s = static_cast<D3D9SamplerState *>(states[i]);
s->Apply(device_, start + i);
}
}
+21 -8
View File
@@ -323,6 +323,8 @@ public:
// TODO: Optimize by getting the locations first and putting in a custom struct
UniformBufferDesc dynamicUniforms;
GLint samplerLocs_[8];
std::vector<GLint> dynamicUniformLocs_;
GLRProgram *program_ = nullptr;
private:
@@ -387,7 +389,7 @@ public:
}
for (int i = 0; i < count; i++) {
int index = i + start;
boundSamplers_[index] = static_cast<OpenGLSamplerState *>(states[index]);
boundSamplers_[index] = static_cast<OpenGLSamplerState *>(states[i]);
}
}
@@ -960,6 +962,10 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
return nullptr;
}
}
if (desc.uniformDesc) {
pipeline->dynamicUniforms = *desc.uniformDesc;
pipeline->dynamicUniformLocs_.resize(desc.uniformDesc->uniforms.size());
}
ILOG("Linking shaders.");
if (pipeline->LinkShaders()) {
// Build the rest of the virtual pipeline object.
@@ -972,8 +978,6 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
pipeline->blend->AddRef();
pipeline->raster->AddRef();
pipeline->inputLayout->AddRef();
if (desc.uniformDesc)
pipeline->dynamicUniforms = *desc.uniformDesc;
return pipeline;
} else {
ELOG("Failed to create pipeline - shaders failed to link");
@@ -985,9 +989,9 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
void OpenGLContext::BindTextures(int start, int count, Texture **textures) {
maxTextures_ = std::max(maxTextures_, start + count);
for (int i = start; i < start + count; i++) {
OpenGLTexture *glTex = static_cast<OpenGLTexture *>(textures[i]);
OpenGLTexture *glTex = static_cast<OpenGLTexture *>(textures[i - start]);
if (!glTex) {
boundTextures_[i] = 0;
boundTextures_[i] = nullptr;
renderManager_.BindTexture(i, nullptr);
continue;
}
@@ -1046,7 +1050,14 @@ bool OpenGLPipeline::LinkShaders() {
semantics.push_back({ SEM_POSITION, "a_position" });
semantics.push_back({ SEM_TEXCOORD0, "a_texcoord0" });
std::vector<GLRProgram::UniformLocQuery> queries;
queries.push_back({ &samplerLocs_[0], "sampler0" });
queries.push_back({ &samplerLocs_[1], "sampler1" });
for (size_t i = 0; i < dynamicUniforms.uniforms.size(); ++i) {
queries.push_back({ &dynamicUniformLocs_[i], dynamicUniforms.uniforms[i].name });
}
std::vector<GLRProgram::Initializer> initialize;
initialize.push_back({ &samplerLocs_[0], 0, 0 });
initialize.push_back({ &samplerLocs_[1], 0, 1 });
program_ = render_->CreateProgram(linkShaders, semantics, queries, initialize, false);
return true;
}
@@ -1066,17 +1077,19 @@ void OpenGLContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) {
Crash();
}
for (auto &uniform : curPipeline_->dynamicUniforms.uniforms) {
for (size_t i = 0; i < curPipeline_->dynamicUniforms.uniforms.size(); ++i) {
const auto &uniform = curPipeline_->dynamicUniforms.uniforms[i];
const GLint &loc = curPipeline_->dynamicUniformLocs_[i];
const float *data = (const float *)((uint8_t *)ub + uniform.offset);
switch (uniform.type) {
case UniformType::FLOAT1:
case UniformType::FLOAT2:
case UniformType::FLOAT3:
case UniformType::FLOAT4:
renderManager_.SetUniformF(uniform.name, 1 + (int)uniform.type - (int)UniformType::FLOAT1, data);
renderManager_.SetUniformF(&loc, 1 + (int)uniform.type - (int)UniformType::FLOAT1, data);
break;
case UniformType::MATRIX4X4:
renderManager_.SetUniformM4x4(uniform.name, data);
renderManager_.SetUniformM4x4(&loc, data);
break;
}
}
+47 -34
View File
@@ -39,6 +39,7 @@
// 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)
@@ -290,14 +291,20 @@ class VKTexture;
class VKBuffer;
class VKSamplerState;
enum {
MAX_BOUND_TEXTURES = 2
};
struct DescriptorSetKey {
VkImageView imageView_;
VKSamplerState *sampler_;
VkImageView imageViews_[MAX_BOUND_TEXTURES];
VKSamplerState *samplers_[MAX_BOUND_TEXTURES];
VkBuffer buffer_;
bool operator < (const DescriptorSetKey &other) const {
if (imageView_ < other.imageView_) return true; else if (imageView_ > other.imageView_) return false;
if (sampler_ < other.sampler_) return true; else if (sampler_ > other.sampler_) return false;
for (int i = 0; i < MAX_BOUND_TEXTURES; ++i) {
if (imageViews_[i] < other.imageViews_[i]) return true; else if (imageViews_[i] > other.imageViews_[i]) return false;
if (samplers_[i] < other.samplers_[i]) return true; else if (samplers_[i] > other.samplers_[i]) return false;
}
if (buffer_ < other.buffer_) return true; else if (buffer_ > other.buffer_) return false;
return false;
}
@@ -505,7 +512,6 @@ private:
int queueFamilyIndex_;
enum {
MAX_BOUND_TEXTURES = 2,
MAX_FRAME_COMMAND_BUFFERS = 256,
};
VKTexture *boundTextures_[MAX_BOUND_TEXTURES]{};
@@ -669,7 +675,7 @@ RasterState *VKContext::CreateRasterState(const RasterStateDesc &desc) {
void VKContext::BindSamplerStates(int start, int count, SamplerState **state) {
for (int i = start; i < start + count; i++) {
boundSamplers_[i] = (VKSamplerState *)state[i];
boundSamplers_[i] = (VKSamplerState *)state[i - start];
}
}
@@ -790,7 +796,7 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit)
VkDescriptorPoolSize dpTypes[2];
dpTypes[0].descriptorCount = 200;
dpTypes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
dpTypes[1].descriptorCount = 200;
dpTypes[1].descriptorCount = 200 * MAX_BOUND_TEXTURES;
dpTypes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
VkDescriptorPoolCreateInfo dp{ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO };
@@ -811,21 +817,24 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit)
}
// binding 0 - uniform data
// binding 1 - combined sampler/image
VkDescriptorSetLayoutBinding bindings[2];
// binding 1 - combined sampler/image 0
// binding 2 - combined sampler/image 1
VkDescriptorSetLayoutBinding bindings[MAX_BOUND_TEXTURES + 1];
bindings[0].descriptorCount = 1;
bindings[0].pImmutableSamplers = nullptr;
bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
bindings[0].binding = 0;
bindings[1].descriptorCount = 1;
bindings[1].pImmutableSamplers = nullptr;
bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
bindings[1].binding = 1;
for (int i = 0; i < MAX_BOUND_TEXTURES; ++i) {
bindings[i + 1].descriptorCount = 1;
bindings[i + 1].pImmutableSamplers = nullptr;
bindings[i + 1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
bindings[i + 1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
bindings[i + 1].binding = i + 1;
}
VkDescriptorSetLayoutCreateInfo dsl = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO };
dsl.bindingCount = 2;
dsl.bindingCount = ARRAY_SIZE(bindings);
dsl.pBindings = bindings;
VkResult res = vkCreateDescriptorSetLayout(device_, &dsl, nullptr, &descriptorSetLayout_);
assert(VK_SUCCESS == res);
@@ -903,8 +912,10 @@ VkDescriptorSet VKContext::GetOrCreateDescriptorSet(VkBuffer buf) {
FrameData *frame = &frame_[vulkan_->GetCurFrame()];
key.imageView_ = boundTextures_[0] ? boundTextures_[0]->GetImageView() : boundImageView_[0];
key.sampler_ = boundSamplers_[0];
for (int i = 0; i < MAX_BOUND_TEXTURES; ++i) {
key.imageViews_[i] = boundTextures_[i] ? boundTextures_[i]->GetImageView() : boundImageView_[i];
key.samplers_[i] = boundSamplers_[i];
}
key.buffer_ = buf;
auto iter = frame->descSets_.find(key);
@@ -927,7 +938,7 @@ VkDescriptorSet VKContext::GetOrCreateDescriptorSet(VkBuffer buf) {
VkDescriptorImageInfo imageDesc;
VkWriteDescriptorSet writes[2] = {};
VkWriteDescriptorSet writes[1 + MAX_BOUND_TEXTURES] = {};
// If handles are NULL for whatever buggy reason, it's best to leave the descriptors
// unwritten instead of trying to write a zero, which is not legal.
@@ -946,24 +957,26 @@ VkDescriptorSet VKContext::GetOrCreateDescriptorSet(VkBuffer buf) {
numWrites++;
}
if (key.imageView_ && boundSamplers_[0] && boundSamplers_[0]->GetSampler()) {
imageDesc.imageView = key.imageView_ ? key.imageView_ : VK_NULL_HANDLE;
imageDesc.sampler = boundSamplers_[0] ? boundSamplers_[0]->GetSampler() : VK_NULL_HANDLE;
for (int i = 0; i < MAX_BOUND_TEXTURES; ++i) {
if (key.imageViews_[i] && key.samplers_[i] && key.samplers_[i]->GetSampler()) {
imageDesc.imageView = key.imageViews_[i];
imageDesc.sampler = key.samplers_[i]->GetSampler();
#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR
imageDesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
imageDesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
#else
imageDesc.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
imageDesc.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
#endif
writes[numWrites].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[numWrites].dstSet = descSet;
writes[numWrites].dstArrayElement = 0;
writes[numWrites].dstBinding = 1;
writes[numWrites].pBufferInfo = nullptr;
writes[numWrites].pImageInfo = &imageDesc;
writes[numWrites].pTexelBufferView = nullptr;
writes[numWrites].descriptorCount = 1;
writes[numWrites].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
numWrites++;
writes[numWrites].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[numWrites].dstSet = descSet;
writes[numWrites].dstArrayElement = 0;
writes[numWrites].dstBinding = i + 1;
writes[numWrites].pBufferInfo = nullptr;
writes[numWrites].pImageInfo = &imageDesc;
writes[numWrites].pTexelBufferView = nullptr;
writes[numWrites].descriptorCount = 1;
writes[numWrites].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
numWrites++;
}
}
vkUpdateDescriptorSets(device_, numWrites, writes, 0, nullptr);
@@ -1201,7 +1214,7 @@ void VKContext::UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset,
void VKContext::BindTextures(int start, int count, Texture **textures) {
for (int i = start; i < start + count; i++) {
boundTextures_[i] = static_cast<VKTexture *>(textures[i]);
boundTextures_[i] = static_cast<VKTexture *>(textures[i - start]);
boundImageView_[i] = boundTextures_[i] ? boundTextures_[i]->GetImageView() : GetNullTexture()->GetImageView();
}
}