mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-26 13:51:09 +00:00
- implement ssao
This commit is contained in:
parent
990d61f41a
commit
c00a46043d
14 changed files with 152 additions and 107 deletions
|
@ -77,7 +77,6 @@ void FGLRenderState::Reset()
|
||||||
|
|
||||||
mEffectState = 0;
|
mEffectState = 0;
|
||||||
activeShader = nullptr;
|
activeShader = nullptr;
|
||||||
mPassType = NORMAL_PASS;
|
|
||||||
|
|
||||||
mCurrentVertexBuffer = nullptr;
|
mCurrentVertexBuffer = nullptr;
|
||||||
mCurrentVertexOffsets[0] = mVertexOffsets[0] = 0;
|
mCurrentVertexOffsets[0] = mVertexOffsets[0] = 0;
|
||||||
|
@ -435,11 +434,6 @@ void FGLRenderState::SetColorMask(bool r, bool g, bool b, bool a)
|
||||||
glColorMask(r, g, b, a);
|
glColorMask(r, g, b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGLRenderState::EnableDrawBufferAttachments(bool on)
|
|
||||||
{
|
|
||||||
EnableDrawBuffers(on ? GetPassDrawBufferCount() : 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGLRenderState::SetStencil(int offs, int op, int flags = -1)
|
void FGLRenderState::SetStencil(int offs, int op, int flags = -1)
|
||||||
{
|
{
|
||||||
static int op2gl[] = { GL_KEEP, GL_INCR, GL_DECR };
|
static int op2gl[] = { GL_KEEP, GL_INCR, GL_DECR };
|
||||||
|
|
|
@ -40,14 +40,6 @@ namespace OpenGLRenderer
|
||||||
class FShader;
|
class FShader;
|
||||||
struct GLSectorPlane;
|
struct GLSectorPlane;
|
||||||
|
|
||||||
enum EPassType
|
|
||||||
{
|
|
||||||
NORMAL_PASS,
|
|
||||||
GBUFFER_PASS,
|
|
||||||
MAX_PASS_TYPES
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class FGLRenderState : public FRenderState
|
class FGLRenderState : public FRenderState
|
||||||
{
|
{
|
||||||
uint64_t firstFrame = 0;
|
uint64_t firstFrame = 0;
|
||||||
|
@ -68,7 +60,6 @@ class FGLRenderState : public FRenderState
|
||||||
|
|
||||||
FShader *activeShader;
|
FShader *activeShader;
|
||||||
|
|
||||||
EPassType mPassType = NORMAL_PASS;
|
|
||||||
int mNumDrawBuffers = 1;
|
int mNumDrawBuffers = 1;
|
||||||
|
|
||||||
bool ApplyShader();
|
bool ApplyShader();
|
||||||
|
@ -119,17 +110,7 @@ public:
|
||||||
mSpecularLevel = specularLevel;
|
mSpecularLevel = specularLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPassType(EPassType passType)
|
void EnableDrawBuffers(int count) override
|
||||||
{
|
|
||||||
mPassType = passType;
|
|
||||||
}
|
|
||||||
|
|
||||||
EPassType GetPassType()
|
|
||||||
{
|
|
||||||
return mPassType;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnableDrawBuffers(int count)
|
|
||||||
{
|
{
|
||||||
count = MIN(count, 3);
|
count = MIN(count, 3);
|
||||||
if (mNumDrawBuffers != count)
|
if (mNumDrawBuffers != count)
|
||||||
|
@ -140,11 +121,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetPassDrawBufferCount()
|
|
||||||
{
|
|
||||||
return mPassType == GBUFFER_PASS ? 3 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ToggleState(int state, bool on);
|
void ToggleState(int state, bool on);
|
||||||
|
|
||||||
void ClearScreen() override;
|
void ClearScreen() override;
|
||||||
|
@ -156,7 +132,6 @@ public:
|
||||||
void SetDepthFunc(int func) override;
|
void SetDepthFunc(int func) override;
|
||||||
void SetDepthRange(float min, float max) override;
|
void SetDepthRange(float min, float max) override;
|
||||||
void SetColorMask(bool r, bool g, bool b, bool a) override;
|
void SetColorMask(bool r, bool g, bool b, bool a) override;
|
||||||
void EnableDrawBufferAttachments(bool on) override;
|
|
||||||
void SetStencil(int offs, int op, int flags) override;
|
void SetStencil(int offs, int op, int flags) override;
|
||||||
void SetCulling(int mode) override;
|
void SetCulling(int mode) override;
|
||||||
void EnableClipDistance(int num, bool state) override;
|
void EnableClipDistance(int num, bool state) override;
|
||||||
|
|
|
@ -120,6 +120,13 @@ struct FDepthBiasState
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum EPassType
|
||||||
|
{
|
||||||
|
NORMAL_PASS,
|
||||||
|
GBUFFER_PASS,
|
||||||
|
MAX_PASS_TYPES
|
||||||
|
};
|
||||||
|
|
||||||
class FRenderState
|
class FRenderState
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -163,6 +170,7 @@ protected:
|
||||||
int mVertexOffsets[2]; // one per binding point
|
int mVertexOffsets[2]; // one per binding point
|
||||||
IIndexBuffer *mIndexBuffer;
|
IIndexBuffer *mIndexBuffer;
|
||||||
|
|
||||||
|
EPassType mPassType = NORMAL_PASS;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VSMatrix mModelMatrix;
|
VSMatrix mModelMatrix;
|
||||||
|
@ -193,6 +201,7 @@ public:
|
||||||
mRenderStyle = DefaultRenderStyle();
|
mRenderStyle = DefaultRenderStyle();
|
||||||
mMaterial.Reset();
|
mMaterial.Reset();
|
||||||
mBias.Reset();
|
mBias.Reset();
|
||||||
|
mPassType = NORMAL_PASS;
|
||||||
|
|
||||||
mVertexBuffer = nullptr;
|
mVertexBuffer = nullptr;
|
||||||
mVertexOffsets[0] = mVertexOffsets[1] = 0;
|
mVertexOffsets[0] = mVertexOffsets[1] = 0;
|
||||||
|
@ -502,6 +511,26 @@ public:
|
||||||
return mInterpolationFactor;
|
return mInterpolationFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EnableDrawBufferAttachments(bool on) // Used by fog boundary drawer
|
||||||
|
{
|
||||||
|
EnableDrawBuffers(on ? GetPassDrawBufferCount() : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetPassDrawBufferCount()
|
||||||
|
{
|
||||||
|
return mPassType == GBUFFER_PASS ? 3 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPassType(EPassType passType)
|
||||||
|
{
|
||||||
|
mPassType = passType;
|
||||||
|
}
|
||||||
|
|
||||||
|
EPassType GetPassType()
|
||||||
|
{
|
||||||
|
return mPassType;
|
||||||
|
}
|
||||||
|
|
||||||
// API-dependent render interface
|
// API-dependent render interface
|
||||||
|
|
||||||
// Draw commands
|
// Draw commands
|
||||||
|
@ -515,7 +544,6 @@ public:
|
||||||
virtual void SetDepthFunc(int func) = 0; // Used by models, portals and mirror surfaces.
|
virtual void SetDepthFunc(int func) = 0; // Used by models, portals and mirror surfaces.
|
||||||
virtual void SetDepthRange(float min, float max) = 0; // Used by portal setup.
|
virtual void SetDepthRange(float min, float max) = 0; // Used by portal setup.
|
||||||
virtual void SetColorMask(bool r, bool g, bool b, bool a) = 0; // Used by portals.
|
virtual void SetColorMask(bool r, bool g, bool b, bool a) = 0; // Used by portals.
|
||||||
virtual void EnableDrawBufferAttachments(bool on) = 0; // Used by fog boundary drawer.
|
|
||||||
virtual void SetStencil(int offs, int op, int flags=-1) = 0; // Used by portal setup and render hacks.
|
virtual void SetStencil(int offs, int op, int flags=-1) = 0; // Used by portal setup and render hacks.
|
||||||
virtual void SetCulling(int mode) = 0; // Used by model drawer only.
|
virtual void SetCulling(int mode) = 0; // Used by model drawer only.
|
||||||
virtual void EnableClipDistance(int num, bool state) = 0; // Use by sprite sorter for vertical splits.
|
virtual void EnableClipDistance(int num, bool state) = 0; // Use by sprite sorter for vertical splits.
|
||||||
|
@ -526,6 +554,7 @@ public:
|
||||||
virtual void EnableDepthTest(bool on) = 0; // used by 2D, portals and render hacks.
|
virtual void EnableDepthTest(bool on) = 0; // used by 2D, portals and render hacks.
|
||||||
virtual void EnableMultisampling(bool on) = 0; // only active for 2D
|
virtual void EnableMultisampling(bool on) = 0; // only active for 2D
|
||||||
virtual void EnableLineSmooth(bool on) = 0; // constant setting for each 2D drawer operation
|
virtual void EnableLineSmooth(bool on) = 0; // constant setting for each 2D drawer operation
|
||||||
|
virtual void EnableDrawBuffers(int count) = 0; // Used by SSAO and EnableDrawBufferAttachments
|
||||||
|
|
||||||
void SetColorMask(bool on)
|
void SetColorMask(bool on)
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,7 +59,7 @@ void VkPostprocess::PostProcessScene(int fixedcm, const std::function<void()> &a
|
||||||
//mCustomPostProcessShaders->Run("scene");
|
//mCustomPostProcessShaders->Run("scene");
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkPostprocess::BlitSceneToTexture()
|
void VkPostprocess::BlitSceneToPostprocess()
|
||||||
{
|
{
|
||||||
auto fb = GetVulkanFrameBuffer();
|
auto fb = GetVulkanFrameBuffer();
|
||||||
|
|
||||||
|
@ -116,11 +116,19 @@ void VkPostprocess::BlitSceneToTexture()
|
||||||
buffers->PipelineImage[mCurrentPipelineImage]->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
buffers->PipelineImage[mCurrentPipelineImage]->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
1, &blit, VK_FILTER_NEAREST);
|
1, &blit, VK_FILTER_NEAREST);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Note: this destroys the SceneColor contents
|
void VkPostprocess::ImageTransitionScene(bool undefinedSrcLayout)
|
||||||
VkPPImageTransition imageTransition1;
|
{
|
||||||
imageTransition1.addImage(buffers->SceneColor.get(), &buffers->SceneColorLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
|
auto fb = GetVulkanFrameBuffer();
|
||||||
imageTransition1.execute(fb->GetDrawCommands());
|
auto buffers = fb->GetBuffers();
|
||||||
|
|
||||||
|
VkPPImageTransition imageTransition;
|
||||||
|
imageTransition.addImage(buffers->SceneColor.get(), &buffers->SceneColorLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
|
||||||
|
imageTransition.addImage(buffers->SceneFog.get(), &buffers->SceneFogLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
|
||||||
|
imageTransition.addImage(buffers->SceneNormal.get(), &buffers->SceneNormalLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
|
||||||
|
imageTransition.addImage(buffers->SceneDepthStencil.get(), &buffers->SceneDepthStencilLayout, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
|
||||||
|
imageTransition.execute(fb->GetDrawCommands());
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkPostprocess::BlitCurrentToImage(VulkanImage *dstimage, VkImageLayout *dstlayout, VkImageLayout finallayout)
|
void VkPostprocess::BlitCurrentToImage(VulkanImage *dstimage, VkImageLayout *dstlayout, VkImageLayout finallayout)
|
||||||
|
@ -207,6 +215,8 @@ void VkPostprocess::AmbientOccludeScene(float m5)
|
||||||
|
|
||||||
VkPPRenderState renderstate;
|
VkPPRenderState renderstate;
|
||||||
hw_postprocess.ssao.Render(&renderstate, m5, sceneWidth, sceneHeight);
|
hw_postprocess.ssao.Render(&renderstate, m5, sceneWidth, sceneHeight);
|
||||||
|
|
||||||
|
ImageTransitionScene(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkPostprocess::BlurScene(float gameinfobluramount)
|
void VkPostprocess::BlurScene(float gameinfobluramount)
|
||||||
|
@ -242,7 +252,7 @@ void VkPostprocess::UpdateShadowMap()
|
||||||
auto buffers = fb->GetBuffers();
|
auto buffers = fb->GetBuffers();
|
||||||
|
|
||||||
VkPPImageTransition imageTransition;
|
VkPPImageTransition imageTransition;
|
||||||
imageTransition.addImage(buffers->Shadowmap.get(), &buffers->ShadowmapLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false);
|
imageTransition.addImage(buffers->Shadowmap.get(), &buffers->ShadowmapLayout, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
|
||||||
imageTransition.execute(fb->GetDrawCommands());
|
imageTransition.execute(fb->GetDrawCommands());
|
||||||
|
|
||||||
screen->mShadowMap.FinishUpdate();
|
screen->mShadowMap.FinishUpdate();
|
||||||
|
@ -426,6 +436,11 @@ void VkPPRenderState::Draw()
|
||||||
else
|
else
|
||||||
key.OutputFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
|
key.OutputFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||||
|
|
||||||
|
if (Output.Type == PPTextureType::SceneColor)
|
||||||
|
key.Samples = fb->GetBuffers()->GetSceneSamples();
|
||||||
|
else
|
||||||
|
key.Samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
|
||||||
auto &passSetup = pp->mRenderPassSetup[key];
|
auto &passSetup = pp->mRenderPassSetup[key];
|
||||||
if (!passSetup)
|
if (!passSetup)
|
||||||
passSetup.reset(new VkPPRenderPassSetup(key));
|
passSetup.reset(new VkPPRenderPassSetup(key));
|
||||||
|
@ -692,10 +707,12 @@ void VkPPRenderPassSetup::CreatePipeline(const VkPPRenderPassKey &key)
|
||||||
builder.addVertexAttribute(1, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(FFlatVertex, u));
|
builder.addVertexAttribute(1, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(FFlatVertex, u));
|
||||||
builder.addDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
|
builder.addDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
|
||||||
builder.addDynamicState(VK_DYNAMIC_STATE_SCISSOR);
|
builder.addDynamicState(VK_DYNAMIC_STATE_SCISSOR);
|
||||||
builder.setViewport(0.0f, 0.0f, (float)SCREENWIDTH, (float)SCREENHEIGHT);
|
// Note: the actual values are ignored since we use dynamic viewport+scissor states
|
||||||
builder.setScissor(0.0f, 0.0f, (float)SCREENWIDTH, (float)SCREENHEIGHT);
|
builder.setViewport(0.0f, 0.0f, 320.0f, 200.0f);
|
||||||
|
builder.setScissor(0.0f, 0.0f, 320.0f, 200.0f);
|
||||||
builder.setTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
|
builder.setTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
|
||||||
builder.setBlendMode(key.BlendMode);
|
builder.setBlendMode(key.BlendMode);
|
||||||
|
builder.setRasterizationSamples(key.Samples);
|
||||||
builder.setLayout(PipelineLayout.get());
|
builder.setLayout(PipelineLayout.get());
|
||||||
builder.setRenderPass(RenderPass.get());
|
builder.setRenderPass(RenderPass.get());
|
||||||
Pipeline = builder.create(GetVulkanFrameBuffer()->device);
|
Pipeline = builder.create(GetVulkanFrameBuffer()->device);
|
||||||
|
@ -706,9 +723,9 @@ void VkPPRenderPassSetup::CreateRenderPass(const VkPPRenderPassKey &key)
|
||||||
{
|
{
|
||||||
RenderPassBuilder builder;
|
RenderPassBuilder builder;
|
||||||
if (key.SwapChain)
|
if (key.SwapChain)
|
||||||
builder.addAttachment(key.OutputFormat, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
builder.addAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||||
else
|
else
|
||||||
builder.addAttachment(key.OutputFormat, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
builder.addAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
builder.addSubpass();
|
builder.addSubpass();
|
||||||
builder.addSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
builder.addSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
builder.addExternalSubpassDependency(
|
builder.addExternalSubpassDependency(
|
||||||
|
@ -729,6 +746,7 @@ void VkPPImageTransition::addImage(VulkanImage *image, VkImageLayout *layout, Vk
|
||||||
|
|
||||||
VkAccessFlags srcAccess = 0;
|
VkAccessFlags srcAccess = 0;
|
||||||
VkAccessFlags dstAccess = 0;
|
VkAccessFlags dstAccess = 0;
|
||||||
|
VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
|
||||||
switch (*layout)
|
switch (*layout)
|
||||||
{
|
{
|
||||||
|
@ -748,6 +766,11 @@ void VkPPImageTransition::addImage(VulkanImage *image, VkImageLayout *layout, Vk
|
||||||
srcAccess = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
srcAccess = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
srcStageMask |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
srcStageMask |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
break;
|
break;
|
||||||
|
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
|
||||||
|
srcAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||||
|
srcStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||||
|
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
I_FatalError("Unimplemented src image layout transition\n");
|
I_FatalError("Unimplemented src image layout transition\n");
|
||||||
}
|
}
|
||||||
|
@ -770,11 +793,16 @@ void VkPPImageTransition::addImage(VulkanImage *image, VkImageLayout *layout, Vk
|
||||||
dstAccess = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
dstAccess = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
dstStageMask |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
dstStageMask |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
break;
|
break;
|
||||||
|
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
|
||||||
|
srcAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||||
|
srcStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||||
|
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
I_FatalError("Unimplemented dst image layout transition\n");
|
I_FatalError("Unimplemented dst image layout transition\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
barrier.addImage(image, undefinedSrcLayout ? VK_IMAGE_LAYOUT_UNDEFINED : *layout, targetLayout, srcAccess, dstAccess);
|
barrier.addImage(image, undefinedSrcLayout ? VK_IMAGE_LAYOUT_UNDEFINED : *layout, targetLayout, srcAccess, dstAccess, aspectMask);
|
||||||
needbarrier = true;
|
needbarrier = true;
|
||||||
*layout = targetLayout;
|
*layout = targetLayout;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ public:
|
||||||
VkFormat OutputFormat;
|
VkFormat OutputFormat;
|
||||||
int SwapChain;
|
int SwapChain;
|
||||||
int ShadowMapBuffers;
|
int ShadowMapBuffers;
|
||||||
|
VkSampleCountFlagBits Samples;
|
||||||
|
|
||||||
bool operator<(const VkPPRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) < 0; }
|
bool operator<(const VkPPRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) < 0; }
|
||||||
bool operator==(const VkPPRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) == 0; }
|
bool operator==(const VkPPRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) == 0; }
|
||||||
|
@ -63,7 +64,9 @@ public:
|
||||||
|
|
||||||
void UpdateShadowMap();
|
void UpdateShadowMap();
|
||||||
|
|
||||||
void BlitSceneToTexture();
|
void ImageTransitionScene(bool undefinedSrcLayout);
|
||||||
|
|
||||||
|
void BlitSceneToPostprocess();
|
||||||
void BlitCurrentToImage(VulkanImage *image, VkImageLayout *layout, VkImageLayout finallayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
void BlitCurrentToImage(VulkanImage *image, VkImageLayout *layout, VkImageLayout finallayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
void DrawPresentTexture(const IntRect &box, bool applyGamma, bool clearBorders);
|
void DrawPresentTexture(const IntRect &box, bool applyGamma, bool clearBorders);
|
||||||
|
|
||||||
|
|
|
@ -232,8 +232,8 @@ void VkRenderBuffers::CreateShadowmap()
|
||||||
ShadowmapView->SetDebugName("VkRenderBuffers.ShadowmapView");
|
ShadowmapView->SetDebugName("VkRenderBuffers.ShadowmapView");
|
||||||
|
|
||||||
PipelineBarrier barrier;
|
PipelineBarrier barrier;
|
||||||
barrier.addImage(Shadowmap.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
|
barrier.addImage(Shadowmap.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0, VK_ACCESS_SHADER_READ_BIT);
|
||||||
barrier.execute(fb->GetDrawCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
barrier.execute(fb->GetDrawCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
|
|
||||||
if (!ShadowmapSampler)
|
if (!ShadowmapSampler)
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
std::unique_ptr<VulkanImage> Shadowmap;
|
std::unique_ptr<VulkanImage> Shadowmap;
|
||||||
std::unique_ptr<VulkanImageView> ShadowmapView;
|
std::unique_ptr<VulkanImageView> ShadowmapView;
|
||||||
std::unique_ptr<VulkanSampler> ShadowmapSampler;
|
std::unique_ptr<VulkanSampler> ShadowmapSampler;
|
||||||
VkImageLayout ShadowmapLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
VkImageLayout ShadowmapLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreatePipeline(int width, int height);
|
void CreatePipeline(int width, int height);
|
||||||
|
|
|
@ -146,11 +146,16 @@ void VkRenderPassSetup::CreateRenderPass(const VkRenderPassKey &key)
|
||||||
{
|
{
|
||||||
auto buffers = GetVulkanFrameBuffer()->GetBuffers();
|
auto buffers = GetVulkanFrameBuffer()->GetBuffers();
|
||||||
|
|
||||||
|
VkFormat drawBufferFormats[] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_A2R10G10B10_UNORM_PACK32 };
|
||||||
|
|
||||||
RenderPassBuilder builder;
|
RenderPassBuilder builder;
|
||||||
|
for (int i = 0; i < key.DrawBuffers; i++)
|
||||||
|
{
|
||||||
builder.addAttachment(
|
builder.addAttachment(
|
||||||
VK_FORMAT_R16G16B16A16_SFLOAT, (VkSampleCountFlagBits)key.Samples,
|
drawBufferFormats[i], i == 0 ? (VkSampleCountFlagBits)key.Samples : buffers->GetSceneSamples(),
|
||||||
(key.ClearTargets & CT_Color) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
(key.ClearTargets & CT_Color) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
|
}
|
||||||
if (key.UsesDepthStencil())
|
if (key.UsesDepthStencil())
|
||||||
{
|
{
|
||||||
builder.addDepthStencilAttachment(
|
builder.addDepthStencilAttachment(
|
||||||
|
@ -160,10 +165,11 @@ void VkRenderPassSetup::CreateRenderPass(const VkRenderPassKey &key)
|
||||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
}
|
}
|
||||||
builder.addSubpass();
|
builder.addSubpass();
|
||||||
builder.addSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
for (int i = 0; i < key.DrawBuffers; i++)
|
||||||
|
builder.addSubpassColorAttachmentRef(i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
if (key.UsesDepthStencil())
|
if (key.UsesDepthStencil())
|
||||||
{
|
{
|
||||||
builder.addSubpassDepthStencilAttachmentRef(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
builder.addSubpassDepthStencilAttachmentRef(key.DrawBuffers, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
builder.addExternalSubpassDependency(
|
builder.addExternalSubpassDependency(
|
||||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
|
@ -194,7 +200,7 @@ void VkRenderPassSetup::CreatePipeline(const VkRenderPassKey &key)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
program = fb->GetShaderManager()->Get(key.EffectState, key.AlphaTest);
|
program = fb->GetShaderManager()->Get(key.EffectState, key.AlphaTest, key.DrawBuffers > 1 ? GBUFFER_PASS : NORMAL_PASS);
|
||||||
}
|
}
|
||||||
builder.addVertexShader(program->vert.get());
|
builder.addVertexShader(program->vert.get());
|
||||||
builder.addFragmentShader(program->frag.get());
|
builder.addFragmentShader(program->frag.get());
|
||||||
|
@ -263,6 +269,7 @@ void VkRenderPassSetup::CreatePipeline(const VkRenderPassKey &key)
|
||||||
builder.setColorWriteMask((VkColorComponentFlags)key.ColorMask);
|
builder.setColorWriteMask((VkColorComponentFlags)key.ColorMask);
|
||||||
builder.setStencil(VK_STENCIL_OP_KEEP, op2vk[key.StencilPassOp], VK_STENCIL_OP_KEEP, VK_COMPARE_OP_EQUAL, 0xffffffff, 0xffffffff, 0);
|
builder.setStencil(VK_STENCIL_OP_KEEP, op2vk[key.StencilPassOp], VK_STENCIL_OP_KEEP, VK_COMPARE_OP_EQUAL, 0xffffffff, 0xffffffff, 0);
|
||||||
builder.setBlendMode(key.RenderStyle);
|
builder.setBlendMode(key.RenderStyle);
|
||||||
|
builder.setSubpassColorAttachmentCount(key.DrawBuffers);
|
||||||
builder.setRasterizationSamples((VkSampleCountFlagBits)key.Samples);
|
builder.setRasterizationSamples((VkSampleCountFlagBits)key.Samples);
|
||||||
|
|
||||||
builder.setLayout(fb->GetRenderPassManager()->PipelineLayout.get());
|
builder.setLayout(fb->GetRenderPassManager()->PipelineLayout.get());
|
||||||
|
|
|
@ -30,6 +30,7 @@ public:
|
||||||
int DrawType;
|
int DrawType;
|
||||||
int Samples;
|
int Samples;
|
||||||
int ClearTargets;
|
int ClearTargets;
|
||||||
|
int DrawBuffers;
|
||||||
|
|
||||||
bool UsesDepthStencil() const { return DepthTest || DepthWrite || StencilTest || (ClearTargets & (CT_Depth | CT_Stencil)); }
|
bool UsesDepthStencil() const { return DepthTest || DepthWrite || StencilTest || (ClearTargets & (CT_Depth | CT_Stencil)); }
|
||||||
|
|
||||||
|
|
|
@ -86,10 +86,6 @@ void VkRenderState::SetColorMask(bool r, bool g, bool b, bool a)
|
||||||
mNeedApply = true;
|
mNeedApply = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkRenderState::EnableDrawBufferAttachments(bool on)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void VkRenderState::SetStencil(int offs, int op, int flags)
|
void VkRenderState::SetStencil(int offs, int op, int flags)
|
||||||
{
|
{
|
||||||
mStencilRef = screen->stencilValue + offs;
|
mStencilRef = screen->stencilValue + offs;
|
||||||
|
@ -205,6 +201,7 @@ void VkRenderState::ApplyRenderPass(int dt)
|
||||||
passKey.ColorMask = mColorMask;
|
passKey.ColorMask = mColorMask;
|
||||||
passKey.CullMode = mCullMode;
|
passKey.CullMode = mCullMode;
|
||||||
passKey.Samples = mRenderTarget.Samples;
|
passKey.Samples = mRenderTarget.Samples;
|
||||||
|
passKey.DrawBuffers = mRenderTarget.DrawBuffers;
|
||||||
if (mSpecialEffect > EFF_NONE)
|
if (mSpecialEffect > EFF_NONE)
|
||||||
{
|
{
|
||||||
passKey.SpecialEffect = mSpecialEffect;
|
passKey.SpecialEffect = mSpecialEffect;
|
||||||
|
@ -567,6 +564,15 @@ void VkRenderState::EndFrame()
|
||||||
mDataIndex = -1;
|
mDataIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VkRenderState::EnableDrawBuffers(int count)
|
||||||
|
{
|
||||||
|
if (mRenderTarget.DrawBuffers != count)
|
||||||
|
{
|
||||||
|
EndRenderPass();
|
||||||
|
mRenderTarget.DrawBuffers = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VkRenderState::SetRenderTarget(VulkanImageView *view, int width, int height, VkSampleCountFlagBits samples)
|
void VkRenderState::SetRenderTarget(VulkanImageView *view, int width, int height, VkSampleCountFlagBits samples)
|
||||||
{
|
{
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
|
@ -586,12 +592,17 @@ void VkRenderState::BeginRenderPass(const VkRenderPassKey &key, VulkanCommandBuf
|
||||||
auto &framebuffer = passSetup->Framebuffer[mRenderTarget.View->view];
|
auto &framebuffer = passSetup->Framebuffer[mRenderTarget.View->view];
|
||||||
if (!framebuffer)
|
if (!framebuffer)
|
||||||
{
|
{
|
||||||
|
auto buffers = fb->GetBuffers();
|
||||||
FramebufferBuilder builder;
|
FramebufferBuilder builder;
|
||||||
builder.setRenderPass(passSetup->RenderPass.get());
|
builder.setRenderPass(passSetup->RenderPass.get());
|
||||||
builder.setSize(mRenderTarget.Width, mRenderTarget.Height);
|
builder.setSize(mRenderTarget.Width, mRenderTarget.Height);
|
||||||
builder.addAttachment(mRenderTarget.View->view);
|
builder.addAttachment(mRenderTarget.View);
|
||||||
|
if (key.DrawBuffers > 1)
|
||||||
|
builder.addAttachment(buffers->SceneFogView.get());
|
||||||
|
if (key.DrawBuffers > 2)
|
||||||
|
builder.addAttachment(buffers->SceneNormalView.get());
|
||||||
if (key.UsesDepthStencil())
|
if (key.UsesDepthStencil())
|
||||||
builder.addAttachment(fb->GetBuffers()->SceneDepthStencilView.get());
|
builder.addAttachment(buffers->SceneDepthStencilView.get());
|
||||||
framebuffer = builder.create(GetVulkanFrameBuffer()->device);
|
framebuffer = builder.create(GetVulkanFrameBuffer()->device);
|
||||||
framebuffer->SetDebugName("VkRenderPassSetup.Framebuffer");
|
framebuffer->SetDebugName("VkRenderPassSetup.Framebuffer");
|
||||||
}
|
}
|
||||||
|
@ -601,6 +612,10 @@ void VkRenderState::BeginRenderPass(const VkRenderPassKey &key, VulkanCommandBuf
|
||||||
beginInfo.setRenderArea(0, 0, mRenderTarget.Width, mRenderTarget.Height);
|
beginInfo.setRenderArea(0, 0, mRenderTarget.Width, mRenderTarget.Height);
|
||||||
beginInfo.setFramebuffer(framebuffer.get());
|
beginInfo.setFramebuffer(framebuffer.get());
|
||||||
beginInfo.addClearColor(screen->mSceneClearColor[0], screen->mSceneClearColor[1], screen->mSceneClearColor[2], screen->mSceneClearColor[3]);
|
beginInfo.addClearColor(screen->mSceneClearColor[0], screen->mSceneClearColor[1], screen->mSceneClearColor[2], screen->mSceneClearColor[3]);
|
||||||
|
if (key.DrawBuffers > 1)
|
||||||
|
beginInfo.addClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
if (key.DrawBuffers > 2)
|
||||||
|
beginInfo.addClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
beginInfo.addClearDepthStencil(1.0f, 0);
|
beginInfo.addClearDepthStencil(1.0f, 0);
|
||||||
cmdbuffer->beginRenderPass(beginInfo);
|
cmdbuffer->beginRenderPass(beginInfo);
|
||||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->Pipeline.get());
|
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->Pipeline.get());
|
||||||
|
|
|
@ -30,7 +30,6 @@ public:
|
||||||
void SetDepthFunc(int func) override;
|
void SetDepthFunc(int func) override;
|
||||||
void SetDepthRange(float min, float max) override;
|
void SetDepthRange(float min, float max) override;
|
||||||
void SetColorMask(bool r, bool g, bool b, bool a) override;
|
void SetColorMask(bool r, bool g, bool b, bool a) override;
|
||||||
void EnableDrawBufferAttachments(bool on) override;
|
|
||||||
void SetStencil(int offs, int op, int flags = -1) override;
|
void SetStencil(int offs, int op, int flags = -1) override;
|
||||||
void SetCulling(int mode) override;
|
void SetCulling(int mode) override;
|
||||||
void EnableClipDistance(int num, bool state) override;
|
void EnableClipDistance(int num, bool state) override;
|
||||||
|
@ -41,6 +40,7 @@ public:
|
||||||
void EnableDepthTest(bool on) override;
|
void EnableDepthTest(bool on) override;
|
||||||
void EnableMultisampling(bool on) override;
|
void EnableMultisampling(bool on) override;
|
||||||
void EnableLineSmooth(bool on) override;
|
void EnableLineSmooth(bool on) override;
|
||||||
|
void EnableDrawBuffers(int count) override;
|
||||||
|
|
||||||
void SetRenderTarget(VulkanImageView *view, int width, int height, VkSampleCountFlagBits samples);
|
void SetRenderTarget(VulkanImageView *view, int width, int height, VkSampleCountFlagBits samples);
|
||||||
void Bind(int bindingpoint, uint32_t offset);
|
void Bind(int bindingpoint, uint32_t offset);
|
||||||
|
@ -117,6 +117,7 @@ protected:
|
||||||
int Width = 0;
|
int Width = 0;
|
||||||
int Height = 0;
|
int Height = 0;
|
||||||
VkSampleCountFlagBits Samples = VK_SAMPLE_COUNT_1_BIT;
|
VkSampleCountFlagBits Samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
int DrawBuffers = 1;
|
||||||
} mRenderTarget;
|
} mRenderTarget;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,21 +12,23 @@ VkShaderManager::VkShaderManager(VulkanDevice *device) : device(device)
|
||||||
|
|
||||||
const char *mainvp = "shaders/glsl/main.vp";
|
const char *mainvp = "shaders/glsl/main.vp";
|
||||||
const char *mainfp = "shaders/glsl/main.fp";
|
const char *mainfp = "shaders/glsl/main.fp";
|
||||||
bool gbufferpass = false;
|
|
||||||
|
|
||||||
for (int i = 0; defaultshaders[i].ShaderName != NULL; i++)
|
for (int j = 0; j < MAX_PASS_TYPES; j++)
|
||||||
|
{
|
||||||
|
bool gbufferpass = j;
|
||||||
|
for (int i = 0; defaultshaders[i].ShaderName != nullptr; i++)
|
||||||
{
|
{
|
||||||
VkShaderProgram prog;
|
VkShaderProgram prog;
|
||||||
prog.vert = LoadVertShader(defaultshaders[i].ShaderName, mainvp, defaultshaders[i].Defines);
|
prog.vert = LoadVertShader(defaultshaders[i].ShaderName, mainvp, defaultshaders[i].Defines);
|
||||||
prog.frag = LoadFragShader(defaultshaders[i].ShaderName, mainfp, defaultshaders[i].gettexelfunc, defaultshaders[i].lightfunc, defaultshaders[i].Defines, true, gbufferpass);
|
prog.frag = LoadFragShader(defaultshaders[i].ShaderName, mainfp, defaultshaders[i].gettexelfunc, defaultshaders[i].lightfunc, defaultshaders[i].Defines, true, gbufferpass);
|
||||||
mMaterialShaders.push_back(std::move(prog));
|
mMaterialShaders[j].push_back(std::move(prog));
|
||||||
|
|
||||||
if (i < SHADER_NoTexture)
|
if (i < SHADER_NoTexture)
|
||||||
{
|
{
|
||||||
VkShaderProgram natprog;
|
VkShaderProgram natprog;
|
||||||
natprog.vert = LoadVertShader(defaultshaders[i].ShaderName, mainvp, defaultshaders[i].Defines);
|
natprog.vert = LoadVertShader(defaultshaders[i].ShaderName, mainvp, defaultshaders[i].Defines);
|
||||||
natprog.frag = LoadFragShader(defaultshaders[i].ShaderName, mainfp, defaultshaders[i].gettexelfunc, defaultshaders[i].lightfunc, defaultshaders[i].Defines, false, gbufferpass);
|
natprog.frag = LoadFragShader(defaultshaders[i].ShaderName, mainfp, defaultshaders[i].gettexelfunc, defaultshaders[i].lightfunc, defaultshaders[i].Defines, false, gbufferpass);
|
||||||
mMaterialShadersNAT.push_back(std::move(natprog));
|
mMaterialShadersNAT[j].push_back(std::move(natprog));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +40,8 @@ VkShaderManager::VkShaderManager(VulkanDevice *device) : device(device)
|
||||||
VkShaderProgram prog;
|
VkShaderProgram prog;
|
||||||
prog.vert = LoadVertShader(name, mainvp, defaultshaders[i].Defines);
|
prog.vert = LoadVertShader(name, mainvp, defaultshaders[i].Defines);
|
||||||
prog.frag = LoadFragShader(name, mainfp, usershaders[i].shader, defaultshaders[usershaders[i].shaderType].lightfunc, defines, true, gbufferpass);
|
prog.frag = LoadFragShader(name, mainfp, usershaders[i].shader, defaultshaders[usershaders[i].shaderType].lightfunc, defines, true, gbufferpass);
|
||||||
mMaterialShaders.push_back(std::move(prog));
|
mMaterialShaders[j].push_back(std::move(prog));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < MAX_EFFECTS; i++)
|
for (int i = 0; i < MAX_EFFECTS; i++)
|
||||||
|
@ -64,16 +67,16 @@ VkShaderProgram *VkShaderManager::GetEffect(int effect)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkShaderProgram *VkShaderManager::Get(unsigned int eff, bool alphateston)
|
VkShaderProgram *VkShaderManager::Get(unsigned int eff, bool alphateston, EPassType passType)
|
||||||
{
|
{
|
||||||
// indices 0-2 match the warping modes, 3 is brightmap, 4 no texture, the following are custom
|
// indices 0-2 match the warping modes, 3 is brightmap, 4 no texture, the following are custom
|
||||||
if (!alphateston && eff <= 3)
|
if (!alphateston && eff <= 3)
|
||||||
{
|
{
|
||||||
return &mMaterialShadersNAT[eff]; // Non-alphatest shaders are only created for default, warp1+2 and brightmap. The rest won't get used anyway
|
return &mMaterialShadersNAT[passType][eff]; // Non-alphatest shaders are only created for default, warp1+2 and brightmap. The rest won't get used anyway
|
||||||
}
|
}
|
||||||
else if (eff < (unsigned int)mMaterialShaders.size())
|
else if (eff < (unsigned int)mMaterialShaders[passType].size())
|
||||||
{
|
{
|
||||||
return &mMaterialShaders[eff];
|
return &mMaterialShaders[passType][eff];
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ public:
|
||||||
~VkShaderManager();
|
~VkShaderManager();
|
||||||
|
|
||||||
VkShaderProgram *GetEffect(int effect);
|
VkShaderProgram *GetEffect(int effect);
|
||||||
VkShaderProgram *Get(unsigned int eff, bool alphateston);
|
VkShaderProgram *Get(unsigned int eff, bool alphateston, EPassType passType);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<VulkanShader> LoadVertShader(FString shadername, const char *vert_lump, const char *defines);
|
std::unique_ptr<VulkanShader> LoadVertShader(FString shadername, const char *vert_lump, const char *defines);
|
||||||
|
@ -100,7 +100,7 @@ private:
|
||||||
|
|
||||||
VulkanDevice *device;
|
VulkanDevice *device;
|
||||||
|
|
||||||
std::vector<VkShaderProgram> mMaterialShaders;
|
std::vector<VkShaderProgram> mMaterialShaders[MAX_PASS_TYPES];
|
||||||
std::vector<VkShaderProgram> mMaterialShadersNAT;
|
std::vector<VkShaderProgram> mMaterialShadersNAT[MAX_PASS_TYPES];
|
||||||
VkShaderProgram mEffectShaders[MAX_EFFECTS];
|
VkShaderProgram mEffectShaders[MAX_EFFECTS];
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include "hwrenderer/utility/hw_clock.h"
|
#include "hwrenderer/utility/hw_clock.h"
|
||||||
#include "hwrenderer/utility/hw_vrmodes.h"
|
#include "hwrenderer/utility/hw_vrmodes.h"
|
||||||
|
#include "hwrenderer/utility/hw_cvars.h"
|
||||||
#include "hwrenderer/models/hw_models.h"
|
#include "hwrenderer/models/hw_models.h"
|
||||||
#include "hwrenderer/scene/hw_skydome.h"
|
#include "hwrenderer/scene/hw_skydome.h"
|
||||||
#include "hwrenderer/scene/hw_fakeflat.h"
|
#include "hwrenderer/scene/hw_fakeflat.h"
|
||||||
|
@ -381,6 +382,8 @@ sector_t *VulkanFrameBuffer::RenderView(player_t *player)
|
||||||
fovratio = ratio;
|
fovratio = ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mPostprocess->ImageTransitionScene(true); // This is the only line that differs compared to FGLRenderer::RenderView
|
||||||
|
|
||||||
retsec = RenderViewpoint(r_viewpoint, player->camera, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true);
|
retsec = RenderViewpoint(r_viewpoint, player->camera, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true);
|
||||||
}
|
}
|
||||||
All.Unclock();
|
All.Unclock();
|
||||||
|
@ -411,12 +414,9 @@ sector_t *VulkanFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor *
|
||||||
if (mainview) // Bind the scene frame buffer and turn on draw buffers used by ssao
|
if (mainview) // Bind the scene frame buffer and turn on draw buffers used by ssao
|
||||||
{
|
{
|
||||||
mRenderState->SetRenderTarget(GetBuffers()->SceneColorView.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), GetBuffers()->GetSceneSamples());
|
mRenderState->SetRenderTarget(GetBuffers()->SceneColorView.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), GetBuffers()->GetSceneSamples());
|
||||||
#if 0
|
|
||||||
bool useSSAO = (gl_ssao != 0);
|
bool useSSAO = (gl_ssao != 0);
|
||||||
GetRenderState()->SetPassType(useSSAO ? GBUFFER_PASS : NORMAL_PASS);
|
GetRenderState()->SetPassType(useSSAO ? GBUFFER_PASS : NORMAL_PASS);
|
||||||
GetRenderState()->EnableDrawBuffers(gl_RenderState.GetPassDrawBufferCount());
|
GetRenderState()->EnableDrawBuffers(GetRenderState()->GetPassDrawBufferCount());
|
||||||
GetRenderState()->Apply();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto di = HWDrawInfo::StartDrawInfo(mainvp.ViewLevel, nullptr, mainvp, nullptr);
|
auto di = HWDrawInfo::StartDrawInfo(mainvp.ViewLevel, nullptr, mainvp, nullptr);
|
||||||
|
@ -443,15 +443,13 @@ sector_t *VulkanFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor *
|
||||||
PostProcess.Clock();
|
PostProcess.Clock();
|
||||||
if (toscreen) di->EndDrawScene(mainvp.sector, *GetRenderState()); // do not call this for camera textures.
|
if (toscreen) di->EndDrawScene(mainvp.sector, *GetRenderState()); // do not call this for camera textures.
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (GetRenderState()->GetPassType() == GBUFFER_PASS) // Turn off ssao draw buffers
|
if (GetRenderState()->GetPassType() == GBUFFER_PASS) // Turn off ssao draw buffers
|
||||||
{
|
{
|
||||||
GetRenderState()->SetPassType(NORMAL_PASS);
|
GetRenderState()->SetPassType(NORMAL_PASS);
|
||||||
GetRenderState()->EnableDrawBuffers(1);
|
GetRenderState()->EnableDrawBuffers(1);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
mPostprocess->BlitSceneToTexture(); // Copy the resulting scene to the current post process texture
|
mPostprocess->BlitSceneToPostprocess(); // Copy the resulting scene to the current post process texture
|
||||||
|
|
||||||
PostProcessScene(cm, [&]() { di->DrawEndScene2D(mainvp.sector, *GetRenderState()); });
|
PostProcessScene(cm, [&]() { di->DrawEndScene2D(mainvp.sector, *GetRenderState()); });
|
||||||
|
|
||||||
|
@ -515,7 +513,6 @@ void VulkanFrameBuffer::DrawScene(HWDrawInfo *di, int drawmode)
|
||||||
static int ssao_portals_available = 0;
|
static int ssao_portals_available = 0;
|
||||||
const auto &vp = di->Viewpoint;
|
const auto &vp = di->Viewpoint;
|
||||||
|
|
||||||
#if 0
|
|
||||||
bool applySSAO = false;
|
bool applySSAO = false;
|
||||||
if (drawmode == DM_MAINVIEW)
|
if (drawmode == DM_MAINVIEW)
|
||||||
{
|
{
|
||||||
|
@ -531,7 +528,6 @@ void VulkanFrameBuffer::DrawScene(HWDrawInfo *di, int drawmode)
|
||||||
applySSAO = true;
|
applySSAO = true;
|
||||||
ssao_portals_available--;
|
ssao_portals_available--;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (vp.camera != nullptr)
|
if (vp.camera != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -549,18 +545,11 @@ void VulkanFrameBuffer::DrawScene(HWDrawInfo *di, int drawmode)
|
||||||
|
|
||||||
di->RenderScene(*GetRenderState());
|
di->RenderScene(*GetRenderState());
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (applySSAO && GetRenderState()->GetPassType() == GBUFFER_PASS)
|
if (applySSAO && GetRenderState()->GetPassType() == GBUFFER_PASS)
|
||||||
{
|
{
|
||||||
GetRenderState()->EnableDrawBuffers(1);
|
mPostprocess->AmbientOccludeScene(di->VPUniforms.mProjectionMatrix.get()[5]);
|
||||||
GLRenderer->AmbientOccludeScene(di->VPUniforms.mProjectionMatrix.get()[5]);
|
|
||||||
glViewport(screen->mSceneViewport.left, screen->mSceneViewport.top, screen->mSceneViewport.width, screen->mSceneViewport.height);
|
|
||||||
GLRenderer->mBuffers->BindSceneFB(true);
|
|
||||||
GetRenderState()->EnableDrawBuffers(GetRenderState()->GetPassDrawBufferCount());
|
|
||||||
GetRenderState()->Apply();
|
|
||||||
screen->mViewpoints->Bind(*GetRenderState(), di->vpIndex);
|
screen->mViewpoints->Bind(*GetRenderState(), di->vpIndex);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Handle all portals after rendering the opaque objects but before
|
// Handle all portals after rendering the opaque objects but before
|
||||||
// doing all translucent stuff
|
// doing all translucent stuff
|
||||||
|
|
Loading…
Reference in a new issue