From 06bdffc0e08c7f3b212499a4080dd7fa6003f842 Mon Sep 17 00:00:00 2001 From: turanszkij Date: Fri, 12 May 2017 12:21:34 +0200 Subject: [PATCH] implement update frequency part 2 --- WickedEngine/wiLoader.cpp | 33 ++++- WickedEngine/wiLoader.h | 2 + WickedEngine/wiRenderer.cpp | 232 ++++++++++++++++++------------------ 3 files changed, 145 insertions(+), 122 deletions(-) diff --git a/WickedEngine/wiLoader.cpp b/WickedEngine/wiLoader.cpp index 5db9c852b..6292a446a 100644 --- a/WickedEngine/wiLoader.cpp +++ b/WickedEngine/wiLoader.cpp @@ -1405,10 +1405,9 @@ void Material::init() // constant buffer creation GPUBufferDesc bd; - ZeroMemory(&bd, sizeof(bd)); bd.BindFlags = BIND_CONSTANT_BUFFER; - bd.Usage = USAGE_DYNAMIC; - bd.CPUAccessFlags = CPU_ACCESS_WRITE; + bd.Usage = USAGE_DEFAULT; // try to keep it in default memory because it will probably be updated non frequently! + bd.CPUAccessFlags = 0; bd.ByteWidth = sizeof(MaterialCB); wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, &constantBuffer); } @@ -1568,6 +1567,34 @@ void Material::Serialize(wiArchive& archive) } } +wiGraphicsTypes::GPUBuffer* Material::constantBuffer_Impostor = nullptr; +void Material::CreateImpostorMaterialCB() +{ + // imposor material constantbuffer is always the same, because every param is baked into the textures + if (constantBuffer_Impostor == nullptr) + { + constantBuffer_Impostor = new wiGraphicsTypes::GPUBuffer; + + MaterialCB mcb; + ZeroMemory(&mcb, sizeof(mcb)); + mcb.baseColor = XMFLOAT4(1, 1, 1, 1); + mcb.texMulAdd = XMFLOAT4(1, 1, 0, 0); + mcb.normalMapStrength = 1.0f; + mcb.roughness = 1.0f; + mcb.reflectance = 1.0f; + mcb.metalness = 1.0f; + + GPUBufferDesc bd; + bd.BindFlags = BIND_CONSTANT_BUFFER; + bd.Usage = USAGE_IMMUTABLE; + bd.CPUAccessFlags = 0; + bd.ByteWidth = sizeof(MaterialCB); + SubresourceData initData; + initData.pSysMem = &mcb; + wiRenderer::GetDevice()->CreateBuffer(&bd, &initData, constantBuffer_Impostor); + } +} + void Material::MaterialCB::Create(const Material& mat) { baseColor = XMFLOAT4(mat.baseColor.x, mat.baseColor.y, mat.baseColor.z, mat.alpha); diff --git a/WickedEngine/wiLoader.h b/WickedEngine/wiLoader.h index 9d11b93b4..22c030de8 100644 --- a/WickedEngine/wiLoader.h +++ b/WickedEngine/wiLoader.h @@ -187,6 +187,8 @@ struct Material }; MaterialCB gpuData; wiGraphicsTypes::GPUBuffer constantBuffer; + static wiGraphicsTypes::GPUBuffer* constantBuffer_Impostor; + static void CreateImpostorMaterialCB(); bool toonshading; bool water,shadeless; diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 83c2e05bf..d4909d70f 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -257,6 +257,8 @@ void wiRenderer::SetUpStaticComponents() BindPersistentState(GRAPHICSTHREAD_IMMEDIATE); UpdateWorldCB(GRAPHICSTHREAD_IMMEDIATE); + + Material::CreateImpostorMaterialCB(); } void wiRenderer::CleanUpStatic() { @@ -1799,8 +1801,8 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID) { Material* material = it.second; materialGPUData.Create(*material); - // These will probably not change every time so only issue an update if it is necessary: - if (memcmp(&material->gpuData, &materialGPUData, sizeof(Material::MaterialCB) != 0)) + // These will probably not change every time so only issue a GPU memory update if it is necessary: + if (memcmp(&material->gpuData, &materialGPUData, sizeof(Material::MaterialCB)) != 0) { material->gpuData = materialGPUData; GetDevice()->UpdateBuffer(&material->constantBuffer, &materialGPUData, threadID); @@ -3700,132 +3702,124 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle targetStencilRef = mesh->stencilRef; - //if (mesh->hasImpostor() && shaderType != SHADERTYPE_VOXELIZE) - //{ - // int k = 0; - // for (const Object* instance : visibleInstances) - // { - // if (instance->emitterType != Object::EmitterType::EMITTER_INVISIBLE) - // { - // const float impostorThreshold = instance->bounds.getRadius(); - // float dist = wiMath::Distance(eye, instance->bounds.getCenter()); - // float dither = instance->transparency; - // dither = wiMath::SmoothStep(1.0f, dither, wiMath::Clamp((dist - impostorDistance) / impostorThreshold, 0, 1)); - // if (dither > 1.0f - FLT_EPSILON) - // continue; + if (mesh->hasImpostor() && shaderType != SHADERTYPE_VOXELIZE) + { + int k = 0; + for (const Object* instance : visibleInstances) + { + if (instance->emitterType != Object::EmitterType::EMITTER_INVISIBLE) + { + const float impostorThreshold = instance->bounds.getRadius(); + float dist = wiMath::Distance(eye, instance->bounds.getCenter()); + float dither = instance->transparency; + dither = wiMath::SmoothStep(1.0f, dither, wiMath::Clamp((dist - impostorDistance) / impostorThreshold, 0, 1)); + if (dither > 1.0f - FLT_EPSILON) + continue; - // if (!occlusionCulling || !instance->IsOccluded()) - // { - // XMStoreFloat4x4(&tempMat, mesh->aabb.getAsBoxMatrix()*XMLoadFloat4x4(&instance->world)); - // mesh->AddRenderableInstance(Instance(tempMat, dither, instance->color), k, threadID); - // ++k; - // } - // } - // } - // if (k > 0) - // { - // mesh->UpdateRenderableInstances(k, threadID); + if (!occlusionCulling || !instance->IsOccluded()) + { + XMStoreFloat4x4(&tempMat, mesh->aabb.getAsBoxMatrix()*XMLoadFloat4x4(&instance->world)); + mesh->AddRenderableInstance(Instance(tempMat, dither, instance->color), k, threadID); + ++k; + } + } + } + if (k > 0) + { + mesh->UpdateRenderableInstances(k, threadID); - // MaterialCB mcb; - // ZeroMemory(&mcb, sizeof(mcb)); - // mcb.baseColor = XMFLOAT4(1, 1, 1, 1); - // mcb.texMulAdd = XMFLOAT4(1, 1, 0, 0); - // mcb.normalMapStrength = 1.0f; - // mcb.roughness = 1.0f; - // mcb.reflectance = 1.0f; - // mcb.metalness = 1.0f; - // UpdateMaterialCB(mcb, threadID); + GetDevice()->BindConstantBufferPS(Material::constantBuffer_Impostor, CB_GETBINDSLOT(Material::MaterialCB), threadID); - // if (shaderType == SHADERTYPE_SHADOW || shaderType == SHADERTYPE_SHADOWCUBE) - // { - // GetDevice()->BindRasterizerState(rasterizers[RSTYPE_SHADOW], threadID); - // } - // else - // { - // GetDevice()->BindRasterizerState(wireRender ? rasterizers[RSTYPE_WIRE] : rasterizers[RSTYPE_FRONT], threadID); - // } + if (shaderType == SHADERTYPE_SHADOW || shaderType == SHADERTYPE_SHADOWCUBE) + { + GetDevice()->BindRasterizerState(rasterizers[RSTYPE_SHADOW], threadID); + } + else + { + GetDevice()->BindRasterizerState(wireRender ? rasterizers[RSTYPE_WIRE] : rasterizers[RSTYPE_FRONT], threadID); + } - // GetDevice()->BindDepthStencilState(depthStencils[targetDepthStencilState], targetStencilRef, threadID); + GetDevice()->BindDepthStencilState(depthStencils[targetDepthStencilState], targetStencilRef, threadID); - // GetDevice()->BindIndexBuffer(nullptr, threadID); + GetDevice()->BindIndexBuffer(nullptr, threadID); - // if (shaderType == SHADERTYPE_ALPHATESTONLY || shaderType == SHADERTYPE_TEXTURE || shaderType == SHADERTYPE_SHADOW || shaderType == SHADERTYPE_SHADOWCUBE) - // { - // GPUBuffer* vbs[] = { - // &Mesh::impostorVBs[VPROP_POS], - // &Mesh::impostorVBs[VPROP_TEX], - // &mesh->instanceBuffer - // }; - // UINT strides[] = { - // sizeof(XMFLOAT4), - // sizeof(XMFLOAT4), - // sizeof(Instance) - // }; - // GetDevice()->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, threadID); - // } - // else - // { - // GPUBuffer* vbs[] = { - // &Mesh::impostorVBs[VPROP_POS], - // &Mesh::impostorVBs[VPROP_NOR], - // &Mesh::impostorVBs[VPROP_TEX], - // &Mesh::impostorVBs[VPROP_POS], - // &mesh->instanceBuffer - // }; - // UINT strides[] = { - // sizeof(XMFLOAT4), - // sizeof(XMFLOAT4), - // sizeof(XMFLOAT4), - // sizeof(XMFLOAT4), - // sizeof(Instance) - // }; - // GetDevice()->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, threadID); - // } + if (shaderType == SHADERTYPE_ALPHATESTONLY || shaderType == SHADERTYPE_TEXTURE || shaderType == SHADERTYPE_SHADOW || shaderType == SHADERTYPE_SHADOWCUBE) + { + GPUBuffer* vbs[] = { + &Mesh::impostorVBs[VPROP_POS], + &Mesh::impostorVBs[VPROP_TEX], + &mesh->instanceBuffer + }; + UINT strides[] = { + sizeof(XMFLOAT4), + sizeof(XMFLOAT4), + sizeof(Instance) + }; + GetDevice()->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, threadID); + } + else + { + GPUBuffer* vbs[] = { + &Mesh::impostorVBs[VPROP_POS], + &Mesh::impostorVBs[VPROP_NOR], + &Mesh::impostorVBs[VPROP_TEX], + &Mesh::impostorVBs[VPROP_POS], + &mesh->instanceBuffer + }; + UINT strides[] = { + sizeof(XMFLOAT4), + sizeof(XMFLOAT4), + sizeof(XMFLOAT4), + sizeof(XMFLOAT4), + sizeof(Instance) + }; + GetDevice()->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, threadID); + } - // GetDevice()->BindResourcePS(mesh->impostorTarget.GetTexture(0), TEXSLOT_ONDEMAND0, threadID); - // if (!easyTextureBind) - // { - // GetDevice()->BindResourcePS(mesh->impostorTarget.GetTexture(1), TEXSLOT_ONDEMAND1, threadID); - // GetDevice()->BindResourcePS(mesh->impostorTarget.GetTexture(2), TEXSLOT_ONDEMAND2, threadID); - // GetDevice()->BindResourcePS(mesh->impostorTarget.GetTexture(3), TEXSLOT_ONDEMAND3, threadID); - // GetDevice()->BindResourcePS(mesh->impostorTarget.GetTexture(4), TEXSLOT_ONDEMAND4, threadID); - // } + GetDevice()->BindResourcePS(mesh->impostorTarget.GetTexture(0), TEXSLOT_ONDEMAND0, threadID); + if (!easyTextureBind) + { + GetDevice()->BindResourcePS(mesh->impostorTarget.GetTexture(1), TEXSLOT_ONDEMAND1, threadID); + GetDevice()->BindResourcePS(mesh->impostorTarget.GetTexture(2), TEXSLOT_ONDEMAND2, threadID); + GetDevice()->BindResourcePS(mesh->impostorTarget.GetTexture(3), TEXSLOT_ONDEMAND3, threadID); + GetDevice()->BindResourcePS(mesh->impostorTarget.GetTexture(4), TEXSLOT_ONDEMAND4, threadID); + } - // if (wireRender) - // { - // GetDevice()->BindPS(pixelShaders[PSTYPE_OBJECT_SIMPLEST], threadID); - // } - // else - // { - // switch (shaderType) - // { - // case SHADERTYPE_DEFERRED: - // GetDevice()->BindPS(pixelShaders[PSTYPE_OBJECT_DEFERRED_NORMALMAP], threadID); - // break; - // case SHADERTYPE_FORWARD: - // GetDevice()->BindPS(pixelShaders[PSTYPE_OBJECT_FORWARD_DIRLIGHT_NORMALMAP], threadID); - // break; - // case SHADERTYPE_TILEDFORWARD: - // GetDevice()->BindPS(pixelShaders[PSTYPE_OBJECT_TILEDFORWARD], threadID); - // break; - // case SHADERTYPE_SHADOW: - // GetDevice()->BindPS(pixelShaders[PSTYPE_SHADOW], threadID); - // break; - // case SHADERTYPE_SHADOWCUBE: - // GetDevice()->BindPS(pixelShaders[PSTYPE_SHADOWCUBEMAPRENDER], threadID); - // break; - // case SHADERTYPE_ALPHATESTONLY: - // GetDevice()->BindPS(pixelShaders[PSTYPE_OBJECT_ALPHATESTONLY], threadID); - // break; - // default: - // GetDevice()->BindPS(pixelShaders[PSTYPE_OBJECT_TEXTUREONLY], threadID); - // break; - // } - // } - // GetDevice()->DrawInstanced(6 * 6, k, threadID); // 6 * 6: see Mesh::CreateImpostorVB function - // } - //} + if (wireRender) + { + GetDevice()->BindPS(pixelShaders[PSTYPE_OBJECT_SIMPLEST], threadID); + } + else + { + switch (shaderType) + { + case SHADERTYPE_DEFERRED: + GetDevice()->BindPS(pixelShaders[PSTYPE_OBJECT_DEFERRED_NORMALMAP], threadID); + break; + case SHADERTYPE_FORWARD: + GetDevice()->BindPS(pixelShaders[PSTYPE_OBJECT_FORWARD_DIRLIGHT_NORMALMAP], threadID); + break; + case SHADERTYPE_TILEDFORWARD: + GetDevice()->BindPS(pixelShaders[PSTYPE_OBJECT_TILEDFORWARD], threadID); + break; + case SHADERTYPE_SHADOW: + GetDevice()->BindPS(pixelShaders[PSTYPE_SHADOW], threadID); + break; + case SHADERTYPE_SHADOWCUBE: + GetDevice()->BindPS(pixelShaders[PSTYPE_SHADOWCUBEMAPRENDER], threadID); + break; + case SHADERTYPE_ALPHATESTONLY: + GetDevice()->BindPS(pixelShaders[PSTYPE_OBJECT_ALPHATESTONLY], threadID); + break; + default: + GetDevice()->BindPS(pixelShaders[PSTYPE_OBJECT_TEXTUREONLY], threadID); + break; + } + } + GetDevice()->DrawInstanced(6 * 6, k, threadID); // 6 * 6: see Mesh::CreateImpostorVB function + } + } if (shaderType == SHADERTYPE_VOXELIZE) {