mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-15 02:29:51 +01:00
Merge branch 'postshader' into TemporaryHackishBranch
This commit is contained in:
commit
ec632dec68
18 files changed
+142
-84
No files matched your search
@@ -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() {
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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_;
|
||||
};
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -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 };
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user