- clean up Apply function

This commit is contained in:
Magnus Norddahl 2019-03-02 23:39:44 +01:00
parent 0c9d27d078
commit 2a6d37dd73
2 changed files with 131 additions and 76 deletions

View file

@ -33,8 +33,8 @@ void VkRenderState::Draw(int dt, int index, int count, bool apply)
{ {
if (apply) if (apply)
Apply(dt); Apply(dt);
else if (mDescriptorsChanged) else if (mDynamicSetChanged)
BindDescriptorSets(); ApplyDynamicSet();
drawcalls.Clock(); drawcalls.Clock();
mCommandBuffer->draw(count, 1, index, 0); mCommandBuffer->draw(count, 1, index, 0);
@ -45,8 +45,8 @@ void VkRenderState::DrawIndexed(int dt, int index, int count, bool apply)
{ {
if (apply) if (apply)
Apply(dt); Apply(dt);
else if (mDescriptorsChanged) else if (mDynamicSetChanged)
BindDescriptorSets(); ApplyDynamicSet();
drawcalls.Clock(); drawcalls.Clock();
mCommandBuffer->drawIndexed(count, 1, index, 0, 0); mCommandBuffer->drawIndexed(count, 1, index, 0, 0);
@ -192,17 +192,20 @@ void VkRenderState::EnableLineSmooth(bool on)
{ {
} }
template<typename T> void VkRenderState::Apply(int dt)
static void CopyToBuffer(uint32_t &offset, const T &data, VKDataBuffer *buffer)
{ {
if (offset + (UniformBufferAlignment<T>() << 1) < buffer->Size()) ApplyRenderPass(dt);
{ ApplyScissor();
offset += UniformBufferAlignment<T>(); ApplyViewport();
memcpy(static_cast<uint8_t*>(buffer->Memory()) + offset, &data, sizeof(T)); ApplyStreamData();
} ApplyMatrices();
ApplyPushConstants();
ApplyVertexBuffers();
ApplyDynamicSet();
ApplyMaterial();
} }
void VkRenderState::Apply(int dt) void VkRenderState::ApplyRenderPass(int dt)
{ {
auto fb = GetVulkanFrameBuffer(); auto fb = GetVulkanFrameBuffer();
auto passManager = fb->GetRenderPassManager(); auto passManager = fb->GetRenderPassManager();
@ -254,7 +257,10 @@ void VkRenderState::Apply(int dt)
mCommandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->Pipeline.get()); mCommandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->Pipeline.get());
mRenderPassSetup = passSetup; mRenderPassSetup = passSetup;
} }
}
void VkRenderState::ApplyScissor()
{
if (mScissorChanged) if (mScissorChanged)
{ {
VkRect2D scissor; VkRect2D scissor;
@ -275,7 +281,10 @@ void VkRenderState::Apply(int dt)
mCommandBuffer->setScissor(0, 1, &scissor); mCommandBuffer->setScissor(0, 1, &scissor);
mScissorChanged = false; mScissorChanged = false;
} }
}
void VkRenderState::ApplyViewport()
{
if (mViewportChanged) if (mViewportChanged)
{ {
VkViewport viewport; VkViewport viewport;
@ -298,27 +307,15 @@ void VkRenderState::Apply(int dt)
mCommandBuffer->setViewport(0, 1, &viewport); mCommandBuffer->setViewport(0, 1, &viewport);
mViewportChanged = false; mViewportChanged = false;
} }
}
void VkRenderState::ApplyStreamData()
{
auto fb = GetVulkanFrameBuffer();
auto passManager = fb->GetRenderPassManager();
const float normScale = 1.0f / 255.0f; const float normScale = 1.0f / 255.0f;
int fogset = 0;
if (mFogEnabled)
{
if (mFogEnabled == 2)
{
fogset = -3; // 2D rendering with 'foggy' overlay.
}
else if ((mFogColor & 0xffffff) == 0)
{
fogset = gl_fogmode;
}
else
{
fogset = -gl_fogmode;
}
}
mStreamData.uDesaturationFactor = mDesaturation * normScale; mStreamData.uDesaturationFactor = mDesaturation * normScale;
mStreamData.uFogColor = { mFogColor.r * normScale, mFogColor.g * normScale, mFogColor.b * normScale, mFogColor.a * normScale }; mStreamData.uFogColor = { mFogColor.r * normScale, mFogColor.g * normScale, mFogColor.b * normScale, mFogColor.a * normScale };
mStreamData.uAddColor = { mAddColor.r * normScale, mAddColor.g * normScale, mAddColor.b * normScale, mAddColor.a * normScale }; mStreamData.uAddColor = { mAddColor.r * normScale, mAddColor.g * normScale, mAddColor.b * normScale, mAddColor.a * normScale };
@ -332,24 +329,6 @@ void VkRenderState::Apply(int dt)
mStreamData.timer = 0.0f; // static_cast<float>((double)(screen->FrameTime - firstFrame) * (double)mShaderTimer / 1000.); mStreamData.timer = 0.0f; // static_cast<float>((double)(screen->FrameTime - firstFrame) * (double)mShaderTimer / 1000.);
int tempTM = TM_NORMAL;
if (mMaterial.mMaterial && mMaterial.mMaterial->tex->isHardwareCanvas())
tempTM = TM_OPAQUE;
mPushConstants.uFogEnabled = fogset;
mPushConstants.uTextureMode = mTextureMode == TM_NORMAL && tempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode;
mPushConstants.uLightDist = mLightParms[0];
mPushConstants.uLightFactor = mLightParms[1];
mPushConstants.uFogDensity = mLightParms[2];
mPushConstants.uLightLevel = mLightParms[3];
mPushConstants.uAlphaThreshold = mAlphaThreshold;
mPushConstants.uClipSplit = { mClipSplit[0], mClipSplit[1] };
/*if (mMaterial.mMaterial)
{
mPushConstants.uSpecularMaterial = { mMaterial.mMaterial->tex->Glossiness, mMaterial.mMaterial->tex->SpecularLevel };
}*/
if (mGlowEnabled) if (mGlowEnabled)
{ {
mStreamData.uGlowTopPlane = mGlowTopPlane.vec; mStreamData.uGlowTopPlane = mGlowTopPlane.vec;
@ -385,6 +364,71 @@ void VkRenderState::Apply(int dt)
mStreamData.uSplitBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f }; mStreamData.uSplitBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
} }
mDataIndex++;
if (mDataIndex == MAX_STREAM_DATA)
{
mDataIndex = 0;
mStreamDataOffset += sizeof(StreamUBO);
}
uint8_t *ptr = (uint8_t*)fb->StreamUBO->Memory();
memcpy(ptr + mStreamDataOffset + sizeof(StreamData) * mDataIndex, &mStreamData, sizeof(StreamData));
}
void VkRenderState::ApplyPushConstants()
{
int fogset = 0;
if (mFogEnabled)
{
if (mFogEnabled == 2)
{
fogset = -3; // 2D rendering with 'foggy' overlay.
}
else if ((mFogColor & 0xffffff) == 0)
{
fogset = gl_fogmode;
}
else
{
fogset = -gl_fogmode;
}
}
int tempTM = TM_NORMAL;
if (mMaterial.mMaterial && mMaterial.mMaterial->tex->isHardwareCanvas())
tempTM = TM_OPAQUE;
mPushConstants.uFogEnabled = fogset;
mPushConstants.uTextureMode = mTextureMode == TM_NORMAL && tempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode;
mPushConstants.uLightDist = mLightParms[0];
mPushConstants.uLightFactor = mLightParms[1];
mPushConstants.uFogDensity = mLightParms[2];
mPushConstants.uLightLevel = mLightParms[3];
mPushConstants.uAlphaThreshold = mAlphaThreshold;
mPushConstants.uClipSplit = { mClipSplit[0], mClipSplit[1] };
//if (mMaterial.mMaterial)
// mPushConstants.uSpecularMaterial = { mMaterial.mMaterial->tex->Glossiness, mMaterial.mMaterial->tex->SpecularLevel };
mPushConstants.uLightIndex = screen->mLights->BindUBO(mLightIndex);
mPushConstants.uDataIndex = mDataIndex;
auto fb = GetVulkanFrameBuffer();
auto passManager = fb->GetRenderPassManager();
mCommandBuffer->pushConstants(passManager->PipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &mPushConstants);
}
template<typename T>
static void CopyToBuffer(uint32_t &offset, const T &data, VKDataBuffer *buffer)
{
if (offset + (UniformBufferAlignment<T>() << 1) < buffer->Size())
{
offset += UniformBufferAlignment<T>();
memcpy(static_cast<uint8_t*>(buffer->Memory()) + offset, &data, sizeof(T));
}
}
void VkRenderState::ApplyMatrices()
{
if (mTextureMatrixEnabled) if (mTextureMatrixEnabled)
{ {
mMatrices.TextureMatrix = mTextureMatrix; mMatrices.TextureMatrix = mTextureMatrix;
@ -405,38 +449,31 @@ void VkRenderState::Apply(int dt)
mMatrices.NormalModelMatrix.loadIdentity(); mMatrices.NormalModelMatrix.loadIdentity();
} }
mPushConstants.uLightIndex = screen->mLights->BindUBO(mLightIndex); auto fb = GetVulkanFrameBuffer();
CopyToBuffer(mMatricesOffset, mMatrices, fb->MatricesUBO); CopyToBuffer(mMatricesOffset, mMatrices, fb->MatricesUBO);
}
mDataIndex++; void VkRenderState::ApplyVertexBuffers()
if (mDataIndex == MAX_STREAM_DATA) {
{
mDataIndex = 0;
mStreamDataOffset += sizeof(StreamUBO);
}
uint8_t *ptr = (uint8_t*)fb->StreamUBO->Memory();
memcpy(ptr + mStreamDataOffset + sizeof(StreamData) * mDataIndex, &mStreamData, sizeof(StreamData));
mPushConstants.uDataIndex = mDataIndex;
mCommandBuffer->pushConstants(passManager->PipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &mPushConstants);
VkBuffer vertexBuffers[] = { static_cast<VKVertexBuffer*>(mVertexBuffer)->mBuffer->buffer }; VkBuffer vertexBuffers[] = { static_cast<VKVertexBuffer*>(mVertexBuffer)->mBuffer->buffer };
VkDeviceSize offsets[] = { 0 }; VkDeviceSize offsets[] = { 0 };
mCommandBuffer->bindVertexBuffers(0, 1, vertexBuffers, offsets); mCommandBuffer->bindVertexBuffers(0, 1, vertexBuffers, offsets);
if (mIndexBuffer) if (mIndexBuffer)
mCommandBuffer->bindIndexBuffer(static_cast<VKIndexBuffer*>(mIndexBuffer)->mBuffer->buffer, 0, VK_INDEX_TYPE_UINT32); mCommandBuffer->bindIndexBuffer(static_cast<VKIndexBuffer*>(mIndexBuffer)->mBuffer->buffer, 0, VK_INDEX_TYPE_UINT32);
}
BindDescriptorSets(); void VkRenderState::ApplyMaterial()
{
//if (mMaterial.mChanged) if (mMaterial.mChanged && mMaterial.mMaterial)
if (mMaterial.mMaterial)
{ {
auto base = static_cast<VkHardwareTexture*>(mMaterial.mMaterial->GetLayer(0, mMaterial.mTranslation)); auto base = static_cast<VkHardwareTexture*>(mMaterial.mMaterial->GetLayer(0, mMaterial.mTranslation));
if (base) if (base)
{
auto fb = GetVulkanFrameBuffer();
auto passManager = fb->GetRenderPassManager();
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->PipelineLayout.get(), 1, base->GetDescriptorSet(mMaterial)); mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->PipelineLayout.get(), 1, base->GetDescriptorSet(mMaterial));
}
mMaterial.mChanged = false; mMaterial.mChanged = false;
} }
@ -453,17 +490,23 @@ void VkRenderState::Bind(int bindingpoint, uint32_t offset)
mLightBufferOffset = offset; mLightBufferOffset = offset;
} }
mDescriptorsChanged = true; mDynamicSetChanged = true;
} }
void VkRenderState::BindDescriptorSets() void VkRenderState::ApplyDynamicSet()
{ {
auto fb = GetVulkanFrameBuffer(); if (mViewpointOffset != mLastViewpointOffset || mLightBufferOffset != mLastLightBufferOffset)
auto passManager = fb->GetRenderPassManager(); {
auto fb = GetVulkanFrameBuffer();
auto passManager = fb->GetRenderPassManager();
uint32_t offsets[4] = { mViewpointOffset, mLightBufferOffset, mMatricesOffset, mStreamDataOffset }; uint32_t offsets[4] = { mViewpointOffset, mLightBufferOffset, mMatricesOffset, mStreamDataOffset };
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->PipelineLayout.get(), 0, passManager->DynamicSet.get(), 4, offsets); mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->PipelineLayout.get(), 0, passManager->DynamicSet.get(), 4, offsets);
mDescriptorsChanged = false;
mLastViewpointOffset = mViewpointOffset;
mLastLightBufferOffset = mLightBufferOffset;
}
mDynamicSetChanged = false;
} }
void VkRenderState::EndRenderPass() void VkRenderState::EndRenderPass()
@ -478,5 +521,7 @@ void VkRenderState::EndRenderPass()
mMatricesOffset = 0; mMatricesOffset = 0;
mStreamDataOffset = 0; mStreamDataOffset = 0;
mDataIndex = -1; mDataIndex = -1;
mLastViewpointOffset = 0xffffffff;
mLastLightBufferOffset = 0xffffffff;
} }
} }

View file

@ -45,12 +45,20 @@ public:
private: private:
void Apply(int dt); void Apply(int dt);
void BindDescriptorSets(); void ApplyRenderPass(int dt);
void ApplyScissor();
void ApplyViewport();
void ApplyStreamData();
void ApplyMatrices();
void ApplyPushConstants();
void ApplyDynamicSet();
void ApplyVertexBuffers();
void ApplyMaterial();
bool mLastDepthClamp = true; bool mLastDepthClamp = true;
VulkanCommandBuffer *mCommandBuffer = nullptr; VulkanCommandBuffer *mCommandBuffer = nullptr;
VkRenderPassSetup *mRenderPassSetup = nullptr; VkRenderPassSetup *mRenderPassSetup = nullptr;
bool mDescriptorsChanged = true; bool mDynamicSetChanged = true;
int mScissorX = 0, mScissorY = 0, mScissorWidth = -1, mScissorHeight = -1; int mScissorX = 0, mScissorY = 0, mScissorWidth = -1, mScissorHeight = -1;
int mViewportX = 0, mViewportY = 0, mViewportWidth = -1, mViewportHeight = -1; int mViewportX = 0, mViewportY = 0, mViewportWidth = -1, mViewportHeight = -1;
@ -65,6 +73,8 @@ private:
StreamData mStreamData = {}; StreamData mStreamData = {};
PushConstants mPushConstants = {}; PushConstants mPushConstants = {};
uint32_t mLastViewpointOffset = 0xffffffff;
uint32_t mLastLightBufferOffset = 0xffffffff;
uint32_t mViewpointOffset = 0; uint32_t mViewpointOffset = 0;
uint32_t mLightBufferOffset = 0; uint32_t mLightBufferOffset = 0;
uint32_t mMatricesOffset = 0; uint32_t mMatricesOffset = 0;