From 73153a42aea94007c236d6aecf1c61185628e2e3 Mon Sep 17 00:00:00 2001 From: turanszkij Date: Wed, 25 Oct 2017 17:18:09 +0100 Subject: [PATCH] entity array writes to gpu-ringbuffer + general updates --- Editor/Editor.cpp | 11 +- Editor/Editor.h | 1 + WickedEngine/ShaderInterop.h | 2 +- WickedEngine/WickedEngine.h | 1 - WickedEngine/WickedEngine_SHARED.vcxitems | 2 - .../WickedEngine_SHARED.vcxitems.filters | 6 - WickedEngine/globals.hlsli | 3 +- WickedEngine/lightCullingCS.hlsl | 2 +- WickedEngine/objectHF.hlsli | 4 +- WickedEngine/wiEmittedParticle.cpp | 7 +- WickedEngine/wiEmittedParticle.h | 9 +- WickedEngine/wiHairParticle.h | 12 +- WickedEngine/wiLoader.cpp | 3 +- WickedEngine/wiLoader.h | 5 +- WickedEngine/wiParticle.cpp | 5 - WickedEngine/wiParticle.h | 22 -- WickedEngine/wiRenderer.cpp | 275 +++++++++--------- WickedEngine/wiRenderer.h | 5 +- WickedEngine/wiVersion.cpp | 2 +- 19 files changed, 182 insertions(+), 195 deletions(-) delete mode 100644 WickedEngine/wiParticle.cpp delete mode 100644 WickedEngine/wiParticle.h diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index ae6dd84fa..d24862e50 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -84,12 +84,16 @@ void Editor::Initialize() void EditorLoadingScreen::Load() { + font = wiFont("Loading...", wiFontProps((int)(wiRenderer::GetDevice()->GetScreenWidth()*0.5f), (int)(wiRenderer::GetDevice()->GetScreenHeight()*0.5f), 36, + WIFALIGN_MID, WIFALIGN_MID)); + addFont(&font); + sprite = wiSprite("../logo/logo_small.png"); sprite.anim.opa = 0.02f; sprite.anim.repeatable = true; - sprite.effects.pos = XMFLOAT3(wiRenderer::GetDevice()->GetScreenWidth()*0.5f, wiRenderer::GetDevice()->GetScreenHeight()*0.5f, 0); + sprite.effects.pos = XMFLOAT3(wiRenderer::GetDevice()->GetScreenWidth()*0.5f, wiRenderer::GetDevice()->GetScreenHeight()*0.5f - font.textHeight(), 0); sprite.effects.siz = XMFLOAT2(128, 128); - sprite.effects.pivot = XMFLOAT2(0.5f, 0.5f); + sprite.effects.pivot = XMFLOAT2(0.5f, 1.0f); sprite.effects.quality = QUALITY_BILINEAR; sprite.effects.blendFlag = BLENDMODE_ALPHA; addSprite(&sprite); @@ -99,9 +103,6 @@ void EditorLoadingScreen::Load() void EditorLoadingScreen::Compose() { __super::Compose(); - - wiFont("Loading...", wiFontProps((int)(wiRenderer::GetDevice()->GetScreenWidth()*0.5f), (int)(wiRenderer::GetDevice()->GetScreenHeight()*0.6f), 36, - WIFALIGN_MID, WIFALIGN_MID)).Draw(GRAPHICSTHREAD_IMMEDIATE); } void EditorLoadingScreen::Unload() { diff --git a/Editor/Editor.h b/Editor/Editor.h index 678118b27..2b38317aa 100644 --- a/Editor/Editor.h +++ b/Editor/Editor.h @@ -17,6 +17,7 @@ class EditorLoadingScreen : public LoadingScreenComponent { private: wiSprite sprite; + wiFont font; public: void Load() override; void Compose() override; diff --git a/WickedEngine/ShaderInterop.h b/WickedEngine/ShaderInterop.h index e68b5ad61..7703755df 100644 --- a/WickedEngine/ShaderInterop.h +++ b/WickedEngine/ShaderInterop.h @@ -120,7 +120,7 @@ struct ShaderEntityType // Tiled rendering params: #define TILED_CULLING_BLOCKSIZE 16 -#define MAX_SHADER_ENTITY_COUNT 1024 +#define MAX_SHADER_ENTITY_COUNT 4096 #define MAX_SHADER_ENTITY_COUNT_PER_TILE 256 diff --git a/WickedEngine/WickedEngine.h b/WickedEngine/WickedEngine.h index 288d1d10a..d815a984d 100644 --- a/WickedEngine/WickedEngine.h +++ b/WickedEngine/WickedEngine.h @@ -20,7 +20,6 @@ #include "wiFrameRate.h" #include "wiCpuInfo.h" #include "wiLoader.h" -#include "wiParticle.h" #include "wiEmittedParticle.h" #include "wiHairParticle.h" #include "wiRenderer.h" diff --git a/WickedEngine/WickedEngine_SHARED.vcxitems b/WickedEngine/WickedEngine_SHARED.vcxitems index 6f3a7e2d7..e4d5c7dcb 100644 --- a/WickedEngine/WickedEngine_SHARED.vcxitems +++ b/WickedEngine/WickedEngine_SHARED.vcxitems @@ -332,7 +332,6 @@ - @@ -671,7 +670,6 @@ - diff --git a/WickedEngine/WickedEngine_SHARED.vcxitems.filters b/WickedEngine/WickedEngine_SHARED.vcxitems.filters index 0863f1f01..ceb2856ef 100644 --- a/WickedEngine/WickedEngine_SHARED.vcxitems.filters +++ b/WickedEngine/WickedEngine_SHARED.vcxitems.filters @@ -921,9 +921,6 @@ ENGINE\Graphics - - ENGINE\Graphics - ENGINE\Graphics @@ -1751,9 +1748,6 @@ ENGINE\Graphics - - ENGINE\Graphics - ENGINE\Graphics diff --git a/WickedEngine/globals.hlsli b/WickedEngine/globals.hlsli index 0a625632e..26d32064f 100644 --- a/WickedEngine/globals.hlsli +++ b/WickedEngine/globals.hlsli @@ -67,9 +67,10 @@ CBUFFER(WorldCB, CBSLOT_RENDERER_WORLD) }; CBUFFER(FrameCB, CBSLOT_RENDERER_FRAME) { + uint g_xFrame_EntityArrayOffset; float g_xFrame_Time; float g_xFrame_TimePrev; - float g_xFrame_DeltaTime; float xPadding0_FrameCB; + float g_xFrame_DeltaTime; float3 g_xFrame_WindDirection; float xPadding1_FrameCB; float g_xFrame_WindWaveSize; float g_xFrame_WindRandomness; diff --git a/WickedEngine/lightCullingCS.hlsl b/WickedEngine/lightCullingCS.hlsl index 069341142..b8b309237 100644 --- a/WickedEngine/lightCullingCS.hlsl +++ b/WickedEngine/lightCullingCS.hlsl @@ -441,7 +441,7 @@ void main(ComputeShaderInput IN) for (uint li = 0; li < o_ArrayLength; ++li) { uint entityIndex = o_Array[li]; - ShaderEntityType light = EntityArray[entityIndex]; + ShaderEntityType light = EntityArray[entityIndex + g_xFrame_EntityArrayOffset]; LightingResult result = (LightingResult)0; diff --git a/WickedEngine/objectHF.hlsli b/WickedEngine/objectHF.hlsli index 8122a4a66..1f6dde669 100644 --- a/WickedEngine/objectHF.hlsli +++ b/WickedEngine/objectHF.hlsli @@ -188,7 +188,7 @@ inline void TiledLighting(in float2 pixel, in float3 N, in float3 V, in float3 P [loop] for (; iterator < decalCount; ++iterator) { - ShaderEntityType decal = EntityArray[EntityIndexList[startOffset + iterator]]; + ShaderEntityType decal = EntityArray[EntityIndexList[startOffset + iterator] + g_xFrame_EntityArrayOffset]; float4x4 decalProjection = decal.GetProjection(); float3 clipSpace = mul(float4(P, 1), decalProjection).xyz; @@ -221,7 +221,7 @@ inline void TiledLighting(in float2 pixel, in float3 N, in float3 V, in float3 P [loop] for (; iterator < arrayLength; iterator++) { - ShaderEntityType light = EntityArray[EntityIndexList[startOffset + iterator]]; + ShaderEntityType light = EntityArray[EntityIndexList[startOffset + iterator] + g_xFrame_EntityArrayOffset]; LightingResult result = (LightingResult)0; diff --git a/WickedEngine/wiEmittedParticle.cpp b/WickedEngine/wiEmittedParticle.cpp index 692bbb834..97b917126 100644 --- a/WickedEngine/wiEmittedParticle.cpp +++ b/WickedEngine/wiEmittedParticle.cpp @@ -19,6 +19,7 @@ BlendState *wiEmittedParticle::blendStateAlpha = nullptr,*wiEmittedParticle::bl RasterizerState *wiEmittedParticle::rasterizerState = nullptr,*wiEmittedParticle::wireFrameRS = nullptr; DepthStencilState *wiEmittedParticle::depthStencilState = nullptr; +#define MAX_PARTICLES 10000 static const int NUM_POS_SAMPLES = 30; static const float INV_NUM_POS_SAMPLES = 1.0f / NUM_POS_SAMPLES; @@ -297,7 +298,7 @@ void wiEmittedParticle::Draw(GRAPHICSTHREAD threadID) device->BindPrimitiveTopology(PRIMITIVETOPOLOGY::TRIANGLELIST,threadID); device->BindVertexLayout(nullptr, threadID); - device->BindPS(wireRender?simplestPS:pixelShader,threadID); + device->BindPS(wiRenderer::IsWireRender() ? simplestPS : pixelShader, threadID); device->BindVS(vertexShader,threadID); ConstantBuffer cb; @@ -310,14 +311,14 @@ void wiEmittedParticle::Draw(GRAPHICSTHREAD threadID) device->UpdateBuffer(constantBuffer,&cb,threadID); device->BindConstantBufferVS(constantBuffer, CB_GETBINDSLOT(ConstantBuffer),threadID); - device->BindRasterizerState(wireRender ? wireFrameRS : rasterizerState, threadID); + device->BindRasterizerState(wiRenderer::IsWireRender() ? wireFrameRS : rasterizerState, threadID); device->BindDepthStencilState(depthStencilState, 1, threadID); device->BindBlendState((additive ? blendStateAdd : blendStateAlpha), threadID); device->BindResourceVS(dynamicPool, 0, threadID); - if (!wireRender && material->texture) + if (!wiRenderer::IsWireRender() && material->texture) { device->BindResourcePS(material->texture, TEXSLOT_ONDEMAND0, threadID); } diff --git a/WickedEngine/wiEmittedParticle.h b/WickedEngine/wiEmittedParticle.h index 013efd12e..637f25f02 100644 --- a/WickedEngine/wiEmittedParticle.h +++ b/WickedEngine/wiEmittedParticle.h @@ -1,19 +1,22 @@ #pragma once -#include "wiParticle.h" +#include "CommonInclude.h" +#include "wiGraphicsAPI.h" #include "ShaderInterop.h" #include "wiIntersectables.h" #include #include +struct SkinnedVertex; +struct Mesh; +struct Object; struct Material; struct Light; struct Camera; class wiArchive; -class wiEmittedParticle : - public wiParticle +class wiEmittedParticle { private: struct Point diff --git a/WickedEngine/wiHairParticle.h b/WickedEngine/wiHairParticle.h index e57e08898..dcba1af2b 100644 --- a/WickedEngine/wiHairParticle.h +++ b/WickedEngine/wiHairParticle.h @@ -1,15 +1,19 @@ #pragma once -#include "wiParticle.h" -#include "ConstantBufferMapping.h" +#include "CommonInclude.h" +#include "wiGraphicsAPI.h" +#include "ShaderInterop.h" #include "wiSPTree.h" + +struct SkinnedVertex; +struct Mesh; +struct Object; struct Material; struct Camera; class wiArchive; -class wiHairParticle : - public wiParticle +class wiHairParticle { public: struct Point diff --git a/WickedEngine/wiLoader.cpp b/WickedEngine/wiLoader.cpp index 0f826fb05..de9517ca4 100644 --- a/WickedEngine/wiLoader.cpp +++ b/WickedEngine/wiLoader.cpp @@ -1997,7 +1997,7 @@ void Mesh::CreateBuffers(Object* object) GPUBufferDesc bd; SubresourceData InitData; - if (!softBody) // softbodies will write the global dynamic vertex buffer pool (except for texcoords)! + if (!hasDynamicVB()) // dynamic vertex buffers will be written to the global pool by the renderer instead! { ZeroMemory(&bd, sizeof(bd)); bd.Usage = USAGE_IMMUTABLE; @@ -2040,6 +2040,7 @@ void Mesh::CreateBuffers(Object* object) } } + // texture coordinate buffers are always static: ZeroMemory(&bd, sizeof(bd)); bd.Usage = USAGE_IMMUTABLE; bd.CPUAccessFlags = 0; diff --git a/WickedEngine/wiLoader.h b/WickedEngine/wiLoader.h index 79a112977..df0319c4d 100644 --- a/WickedEngine/wiLoader.h +++ b/WickedEngine/wiLoader.h @@ -497,8 +497,9 @@ public: bufferOffset_PRE = 0; } - bool hasArmature()const { return armature != nullptr; } - bool hasImpostor()const { return impostorTarget.IsInitialized(); } + bool hasArmature() const { return armature != nullptr; } + bool hasImpostor() const { return impostorTarget.IsInitialized(); } + bool hasDynamicVB() const { return softBody; } float getTessellationFactor() { return tessellationFactor; } void Serialize(wiArchive& archive); }; diff --git a/WickedEngine/wiParticle.cpp b/WickedEngine/wiParticle.cpp deleted file mode 100644 index 1d136885e..000000000 --- a/WickedEngine/wiParticle.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "wiParticle.h" - - - -bool wiParticle::wireRender=false; diff --git a/WickedEngine/wiParticle.h b/WickedEngine/wiParticle.h deleted file mode 100644 index 28f7db9c8..000000000 --- a/WickedEngine/wiParticle.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -#include "CommonInclude.h" -#include "wiGraphicsAPI.h" -#define MAX_PARTICLES 10000 - - -struct SkinnedVertex; -struct Mesh; -struct Object; - -class wiParticle -{ -protected: - wiParticle(){}; - -public: - - static bool wireRender; - static void ChangeRasterizer(){wireRender=!wireRender;} -}; - - diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 9c3487d07..5fa2a7a88 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -63,6 +63,7 @@ float wiRenderer::renderTime = 0, wiRenderer::renderTime_Prev = 0, wiRenderer::d XMFLOAT2 wiRenderer::temporalAAJitter = XMFLOAT2(0, 0), wiRenderer::temporalAAJitterPrev = XMFLOAT2(0, 0); float wiRenderer::RESOLUTIONSCALE = 1.0f; GPUQuery wiRenderer::occlusionQueries[]; +UINT wiRenderer::entityArrayOffset = 0; Texture2D* wiRenderer::enviroMap,*wiRenderer::colorGrading; float wiRenderer::GameSpeed=1,wiRenderer::overrideGameSpeed=1; @@ -632,6 +633,8 @@ void wiRenderer::LoadBuffers() bd.BindFlags = BIND_SHADER_RESOURCE; bd.MiscFlags = RESOURCE_MISC_BUFFER_STRUCTURED; bd.StructureByteStride = sizeof(ShaderEntityType); + SAFE_DELETE(resourceBuffers[RBTYPE_ENTITYARRAY]); + resourceBuffers[RBTYPE_ENTITYARRAY] = new GPURingBuffer; GetDevice()->CreateBuffer(&bd, nullptr, resourceBuffers[RBTYPE_ENTITYARRAY]); SAFE_DELETE(resourceBuffers[RBTYPE_VOXELSCENE]); // lazy init on request @@ -1851,132 +1854,15 @@ void wiRenderer::UpdatePerFrameData(float dt) } void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID) { - UpdateWorldCB(threadID); // only commits when parameters are changed - UpdateFrameCB(threadID); - BindPersistentState(threadID); - - wiProfiler::GetInstance().BeginRange("Skinning", wiProfiler::DOMAIN_GPU, threadID); - GetDevice()->EventBegin("Skinning", threadID); - { - bool streamOutSetUp = false; - - for (Model* model : GetScene().models) - { - // Update material constant buffers: - MaterialCB materialGPUData; - for (auto& it : model->materials) - { - Material* material = it.second; - materialGPUData.Create(*material); - // These will probably not change every time so only issue a GPU memory update if it is necessary: - if (memcmp(&material->gpuData, &materialGPUData, sizeof(MaterialCB)) != 0) - { - material->gpuData = materialGPUData; - GetDevice()->UpdateBuffer(&material->constantBuffer, &materialGPUData, threadID); - } - } - - // Skinning: - for (MeshCollection::iterator iter = model->meshes.begin(); iter != model->meshes.end(); ++iter) - { - Mesh* mesh = iter->second; - - if (mesh->hasArmature() && !mesh->softBody && mesh->renderable && !mesh->vertices_POS.empty() - && mesh->streamoutBuffer_POS.IsValid() && mesh->vertexBuffer_POS.IsValid()) - { - Armature* armature = mesh->armature; - - if (!streamOutSetUp) - { - // Set up skinning shader - streamOutSetUp = true; - GetDevice()->BindVertexLayout(nullptr, threadID); - GPUBuffer* vbs[] = { - nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr - }; - const UINT strides[] = { - 0,0,0,0,0,0,0,0 - }; - GetDevice()->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, nullptr, threadID); - GetDevice()->BindCS(computeShaders[CSTYPE_SKINNING], threadID); - } - - // Upload bones for skinning to shader - for (unsigned int k = 0; k < armature->boneCollection.size(); k++) - { - armature->boneData[k].Create(armature->boneCollection[k]->boneRelativity); - } - GetDevice()->UpdateBuffer(&armature->boneBuffer, armature->boneData.data(), threadID, (int)(sizeof(Armature::ShaderBoneType) * armature->boneCollection.size())); - GetDevice()->BindResourceCS(&armature->boneBuffer, SKINNINGSLOT_IN_BONEBUFFER, threadID); - - // Do the skinning - const GPUResource* vbs[] = { - static_cast(&mesh->vertexBuffer_POS), - static_cast(&mesh->vertexBuffer_NOR), - static_cast(&mesh->vertexBuffer_BON), - }; - const GPUUnorderedResource* sos[] = { - static_cast(&mesh->streamoutBuffer_POS), - static_cast(&mesh->streamoutBuffer_NOR), - static_cast(&mesh->streamoutBuffer_PRE), - }; - - GetDevice()->BindResourcesCS(vbs, SKINNINGSLOT_IN_VERTEX_POS, ARRAYSIZE(vbs), threadID); - GetDevice()->BindUnorderedAccessResourcesCS(sos, 0, ARRAYSIZE(sos), threadID); - - GetDevice()->Dispatch((UINT)ceilf((float)mesh->vertices_POS.size() / SKINNING_COMPUTE_THREADCOUNT), 1, 1, threadID); - - } - - // Upload CPU skinned vertex buffer (Soft body VB) - if (mesh->softBody) - { - //GetDevice()->UpdateBuffer(&mesh->vertexBuffer_POS, mesh->vertices_Transformed_POS.data(), threadID, (int)(sizeof(Mesh::Vertex_POS)*mesh->vertices_Transformed_POS.size())); - //GetDevice()->UpdateBuffer(&mesh->vertexBuffer_NOR, mesh->vertices_Transformed_NOR.data(), threadID, (int)(sizeof(Mesh::Vertex_NOR)*mesh->vertices_Transformed_NOR.size())); - //GetDevice()->UpdateBuffer(&mesh->streamoutBuffer_PRE, mesh->vertices_Transformed_PRE.data(), threadID, (int)(sizeof(Mesh::Vertex_POS)*mesh->vertices_Transformed_PRE.size())); - mesh->bufferOffset_POS = GetDevice()->AppendRingBuffer(dynamicVertexBufferPool, mesh->vertices_Transformed_POS.data(), sizeof(Mesh::Vertex_POS)*mesh->vertices_Transformed_POS.size(), threadID); - mesh->bufferOffset_NOR = GetDevice()->AppendRingBuffer(dynamicVertexBufferPool, mesh->vertices_Transformed_NOR.data(), sizeof(Mesh::Vertex_NOR)*mesh->vertices_Transformed_NOR.size(), threadID); - mesh->bufferOffset_PRE = GetDevice()->AppendRingBuffer(dynamicVertexBufferPool, mesh->vertices_Transformed_PRE.data(), sizeof(Mesh::Vertex_POS)*mesh->vertices_Transformed_PRE.size(), threadID); - } - } - } - - if (streamOutSetUp) - { - // Unload skinning shader - GetDevice()->BindCS(nullptr, threadID); - GetDevice()->UnBindUnorderedAccessResources(0, 3, threadID); - GetDevice()->UnBindResources(SKINNINGSLOT_IN_VERTEX_POS, 4, threadID); - } - - } - GetDevice()->EventEnd(threadID); - wiProfiler::GetInstance().EndRange(threadID); // skinning - - - RefreshEnvProbes(threadID); - - // Bind environment probes: - { - const GPUResource* envMaps[] = { - globalEnvProbes[0] == nullptr ? enviroMap : globalEnvProbes[0]->cubeMap.GetTexture(), - globalEnvProbes[1] == nullptr ? enviroMap : globalEnvProbes[1]->cubeMap.GetTexture(), - }; - GetDevice()->BindResourcesPS(envMaps, TEXSLOT_ENV0, ARRAYSIZE(envMaps), threadID); - GetDevice()->BindResourcesCS(envMaps, TEXSLOT_ENV0, ARRAYSIZE(envMaps), threadID); - } - - const FrameCulling& mainCameraCulling = frameCullings[getCamera()]; ManageDecalAtlas(threadID); - - // Fill Light Array with lights + decals in the frustum + + // Fill Light Array with lights + decals in the frustum: { const CulledList& culledLights = mainCameraCulling.culledLights; static ShaderEntityType* entityArray = (ShaderEntityType*)_mm_malloc(sizeof(ShaderEntityType)*MAX_SHADER_ENTITY_COUNT, 16); - ZeroMemory(entityArray, sizeof(ShaderEntityType)*MAX_SHADER_ENTITY_COUNT); XMMATRIX viewMatrix = cam->GetView(); @@ -2069,12 +1955,127 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID) lightCounter++; } - GetDevice()->UpdateBuffer(resourceBuffers[RBTYPE_ENTITYARRAY], entityArray, threadID, (int)(sizeof(ShaderEntityType)*lightCounter)); + entityArrayOffset = GetDevice()->AppendRingBuffer(static_cast(resourceBuffers[RBTYPE_ENTITYARRAY]), entityArray, sizeof(ShaderEntityType)*lightCounter, threadID); + entityArrayOffset /= sizeof(ShaderEntityType); GetDevice()->BindResourcePS(resourceBuffers[RBTYPE_ENTITYARRAY], SBSLOT_ENTITYARRAY, threadID); GetDevice()->BindResourceCS(resourceBuffers[RBTYPE_ENTITYARRAY], SBSLOT_ENTITYARRAY, threadID); } + + // These should be after entity array update because that updates some constants! + UpdateWorldCB(threadID); // only commits when parameters are changed + UpdateFrameCB(threadID); + BindPersistentState(threadID); + + + wiProfiler::GetInstance().BeginRange("Skinning", wiProfiler::DOMAIN_GPU, threadID); + GetDevice()->EventBegin("Skinning", threadID); + { + bool streamOutSetUp = false; + + for (Model* model : GetScene().models) + { + // Update material constant buffers: + MaterialCB materialGPUData; + for (auto& it : model->materials) + { + Material* material = it.second; + materialGPUData.Create(*material); + // These will probably not change every time so only issue a GPU memory update if it is necessary: + if (memcmp(&material->gpuData, &materialGPUData, sizeof(MaterialCB)) != 0) + { + material->gpuData = materialGPUData; + GetDevice()->UpdateBuffer(&material->constantBuffer, &materialGPUData, threadID); + } + } + + // Skinning: + for (MeshCollection::iterator iter = model->meshes.begin(); iter != model->meshes.end(); ++iter) + { + Mesh* mesh = iter->second; + + if (mesh->hasArmature() && !mesh->hasDynamicVB() && mesh->renderable && !mesh->vertices_POS.empty() + && mesh->streamoutBuffer_POS.IsValid() && mesh->vertexBuffer_POS.IsValid()) + { + Armature* armature = mesh->armature; + + if (!streamOutSetUp) + { + // Set up skinning shader + streamOutSetUp = true; + GetDevice()->BindVertexLayout(nullptr, threadID); + GPUBuffer* vbs[] = { + nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr + }; + const UINT strides[] = { + 0,0,0,0,0,0,0,0 + }; + GetDevice()->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, nullptr, threadID); + GetDevice()->BindCS(computeShaders[CSTYPE_SKINNING], threadID); + } + + // Upload bones for skinning to shader + for (unsigned int k = 0; k < armature->boneCollection.size(); k++) + { + armature->boneData[k].Create(armature->boneCollection[k]->boneRelativity); + } + GetDevice()->UpdateBuffer(&armature->boneBuffer, armature->boneData.data(), threadID, (int)(sizeof(Armature::ShaderBoneType) * armature->boneCollection.size())); + GetDevice()->BindResourceCS(&armature->boneBuffer, SKINNINGSLOT_IN_BONEBUFFER, threadID); + + // Do the skinning + const GPUResource* vbs[] = { + static_cast(&mesh->vertexBuffer_POS), + static_cast(&mesh->vertexBuffer_NOR), + static_cast(&mesh->vertexBuffer_BON), + }; + const GPUUnorderedResource* sos[] = { + static_cast(&mesh->streamoutBuffer_POS), + static_cast(&mesh->streamoutBuffer_NOR), + static_cast(&mesh->streamoutBuffer_PRE), + }; + + GetDevice()->BindResourcesCS(vbs, SKINNINGSLOT_IN_VERTEX_POS, ARRAYSIZE(vbs), threadID); + GetDevice()->BindUnorderedAccessResourcesCS(sos, 0, ARRAYSIZE(sos), threadID); + + GetDevice()->Dispatch((UINT)ceilf((float)mesh->vertices_POS.size() / SKINNING_COMPUTE_THREADCOUNT), 1, 1, threadID); + + } + else if (mesh->hasDynamicVB()) + { + // Upload CPU skinned vertex buffer (Soft body VB) + mesh->bufferOffset_POS = GetDevice()->AppendRingBuffer(dynamicVertexBufferPool, mesh->vertices_Transformed_POS.data(), sizeof(Mesh::Vertex_POS)*mesh->vertices_Transformed_POS.size(), threadID); + mesh->bufferOffset_NOR = GetDevice()->AppendRingBuffer(dynamicVertexBufferPool, mesh->vertices_Transformed_NOR.data(), sizeof(Mesh::Vertex_NOR)*mesh->vertices_Transformed_NOR.size(), threadID); + mesh->bufferOffset_PRE = GetDevice()->AppendRingBuffer(dynamicVertexBufferPool, mesh->vertices_Transformed_PRE.data(), sizeof(Mesh::Vertex_POS)*mesh->vertices_Transformed_PRE.size(), threadID); + } + } + } + + if (streamOutSetUp) + { + // Unload skinning shader + GetDevice()->BindCS(nullptr, threadID); + GetDevice()->UnBindUnorderedAccessResources(0, 3, threadID); + GetDevice()->UnBindResources(SKINNINGSLOT_IN_VERTEX_POS, 4, threadID); + } + + } + GetDevice()->EventEnd(threadID); + wiProfiler::GetInstance().EndRange(threadID); // skinning + + + RefreshEnvProbes(threadID); + + // Bind environment probes: + { + const GPUResource* envMaps[] = { + globalEnvProbes[0] == nullptr ? enviroMap : globalEnvProbes[0]->cubeMap.GetTexture(), + globalEnvProbes[1] == nullptr ? enviroMap : globalEnvProbes[1]->cubeMap.GetTexture(), + }; + GetDevice()->BindResourcesPS(envMaps, TEXSLOT_ENV0, ARRAYSIZE(envMaps), threadID); + GetDevice()->BindResourcesCS(envMaps, TEXSLOT_ENV0, ARRAYSIZE(envMaps), threadID); + } + // Update visible particlesystem vertices: for (auto& x : mainCameraCulling.culledEmittedParticleSystems) { @@ -4308,7 +4309,7 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle case BOUNDVERTEXBUFFERTYPE::POSITION: { GPUBuffer* vbs[] = { - mesh->softBody ? dynamicVertexBufferPool : (mesh->streamoutBuffer_POS.IsValid() ? &mesh->streamoutBuffer_POS : &mesh->vertexBuffer_POS), + mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_POS.IsValid() ? &mesh->streamoutBuffer_POS : &mesh->vertexBuffer_POS), dynamicVertexBufferPool }; UINT strides[] = { @@ -4316,7 +4317,7 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle sizeof(Instance) }; UINT offsets[] = { - mesh->softBody ? mesh->bufferOffset_POS : 0, + mesh->hasDynamicVB() ? mesh->bufferOffset_POS : 0, instanceOffset }; device->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, offsets, threadID); @@ -4325,7 +4326,7 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle case BOUNDVERTEXBUFFERTYPE::POSITION_TEXCOORD: { GPUBuffer* vbs[] = { - mesh->softBody ? dynamicVertexBufferPool : (mesh->streamoutBuffer_POS.IsValid() ? &mesh->streamoutBuffer_POS : &mesh->vertexBuffer_POS), + mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_POS.IsValid() ? &mesh->streamoutBuffer_POS : &mesh->vertexBuffer_POS), &mesh->vertexBuffer_TEX, dynamicVertexBufferPool }; @@ -4335,7 +4336,7 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle sizeof(Instance) }; UINT offsets[] = { - mesh->softBody ? mesh->bufferOffset_POS : 0, + mesh->hasDynamicVB() ? mesh->bufferOffset_POS : 0, 0, instanceOffset }; @@ -4345,10 +4346,10 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle case BOUNDVERTEXBUFFERTYPE::EVERYTHING: { GPUBuffer* vbs[] = { - mesh->softBody ? dynamicVertexBufferPool : (mesh->streamoutBuffer_POS.IsValid() ? &mesh->streamoutBuffer_POS : &mesh->vertexBuffer_POS), - mesh->softBody ? dynamicVertexBufferPool : (mesh->streamoutBuffer_NOR.IsValid() ? &mesh->streamoutBuffer_NOR : &mesh->vertexBuffer_NOR), + mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_POS.IsValid() ? &mesh->streamoutBuffer_POS : &mesh->vertexBuffer_POS), + mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_NOR.IsValid() ? &mesh->streamoutBuffer_NOR : &mesh->vertexBuffer_NOR), &mesh->vertexBuffer_TEX, - mesh->softBody ? dynamicVertexBufferPool : (mesh->streamoutBuffer_PRE.IsValid() ? &mesh->streamoutBuffer_PRE : &mesh->vertexBuffer_POS), + mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_PRE.IsValid() ? &mesh->streamoutBuffer_PRE : &mesh->vertexBuffer_POS), dynamicVertexBufferPool, dynamicVertexBufferPool }; @@ -4361,10 +4362,10 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle sizeof(InstancePrev), }; UINT offsets[] = { - mesh->softBody ? mesh->bufferOffset_POS : 0, - mesh->softBody ? mesh->bufferOffset_NOR : 0, + mesh->hasDynamicVB() ? mesh->bufferOffset_POS : 0, + mesh->hasDynamicVB() ? mesh->bufferOffset_NOR : 0, 0, - mesh->softBody ? mesh->bufferOffset_PRE : 0, + mesh->hasDynamicVB() ? mesh->bufferOffset_PRE : 0, instanceOffset, instancePrevOffset }; @@ -5428,6 +5429,7 @@ void wiRenderer::UpdateFrameCB(GRAPHICSTHREAD threadID) { FrameCB cb; + cb.mEntityArrayOffset = entityArrayOffset; cb.mTime = renderTime; cb.mTimePrev = renderTime_Prev; cb.mDeltaTime = deltaTime; @@ -6107,10 +6109,10 @@ void wiRenderer::CreateImpostor(Mesh* mesh) const UINT instancePrevOffset = GetDevice()->AppendRingBuffer(dynamicVertexBufferPool, &instancePrev, sizeof(instancePrev), threadID); GPUBuffer* vbs[] = { - (mesh->streamoutBuffer_POS.IsValid() ? &mesh->streamoutBuffer_POS : &mesh->vertexBuffer_POS), - (mesh->streamoutBuffer_NOR.IsValid() ? &mesh->streamoutBuffer_NOR : &mesh->vertexBuffer_NOR), + mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_POS.IsValid() ? &mesh->streamoutBuffer_POS : &mesh->vertexBuffer_POS), + mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_NOR.IsValid() ? &mesh->streamoutBuffer_NOR : &mesh->vertexBuffer_NOR), &mesh->vertexBuffer_TEX, - (mesh->streamoutBuffer_PRE.IsValid() ? &mesh->streamoutBuffer_PRE : &mesh->vertexBuffer_POS), + mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_PRE.IsValid() ? &mesh->streamoutBuffer_PRE : &mesh->vertexBuffer_POS), dynamicVertexBufferPool, dynamicVertexBufferPool }; @@ -6123,7 +6125,12 @@ void wiRenderer::CreateImpostor(Mesh* mesh) sizeof(InstancePrev) }; UINT offsets[] = { - 0,0,0,0,instanceOffset,instancePrevOffset + mesh->hasDynamicVB() ? mesh->bufferOffset_POS : 0, + mesh->hasDynamicVB() ? mesh->bufferOffset_NOR : 0, + 0, + mesh->hasDynamicVB() ? mesh->bufferOffset_PRE : 0, + instanceOffset, + instancePrevOffset }; GetDevice()->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, offsets, threadID); diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index 62f584a67..c0ca2182b 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -111,9 +111,10 @@ public: }; CBUFFER(FrameCB, CBSLOT_RENDERER_FRAME) { + UINT mEntityArrayOffset; float mTime; float mTimePrev; - float mDeltaTime; float pad0; + float mDeltaTime; XMFLOAT3 mWindDirection; float pad1; float mWindWaveSize; float mWindRandomness; @@ -250,6 +251,8 @@ protected: static wiGraphicsTypes::GPUQuery occlusionQueries[256]; + static UINT entityArrayOffset; + public: static std::string SHADERPATH; diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index d6716fcce..8abec5160 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 13; // minor bug fixes, alterations, refactors, updates - const int revision = 56; + const int revision = 57; long GetVersion()