small strides towards more const safety

This commit is contained in:
Turanszki Janos
2019-03-01 00:46:07 +00:00
parent 657666a300
commit 0e08c9038b
8 changed files with 161 additions and 135 deletions
+2 -2
View File
@@ -213,9 +213,9 @@ void RenderPath3D::FixedUpdate()
void RenderPath3D::Update(float dt)
{
wiRenderer::UpdatePerFrameData(dt);
RenderPath2D::Update(dt);
wiRenderer::UpdatePerFrameData(dt);
}
void RenderPath3D::Compose()
+22 -18
View File
@@ -225,12 +225,27 @@ uint32_t wiEmittedParticle::GetMemorySizeInBytes() const
return retVal;
}
void wiEmittedParticle::Update(float dt)
void wiEmittedParticle::UpdateCPU(const TransformComponent& transform, float dt)
{
if (IsPaused())
return;
emit = max(0, emit - floorf(emit));
CreateSelfBuffers();
center = transform.GetPosition();
emit += (float)count*dt;
// Swap CURRENT alivelist with NEW alivelist
aliveList[0].swap(aliveList[1]);
if (IsDebug())
{
wiRenderer::GetDevice()->DownloadResource(counterBuffer.get(), debugDataReadbackBuffer.get(), &debugData, GRAPHICSTHREAD_IMMEDIATE);
}
}
void wiEmittedParticle::Burst(float num)
{
@@ -246,18 +261,17 @@ void wiEmittedParticle::Restart()
}
//#define DEBUG_SORTING // slow but great for debug!!
void wiEmittedParticle::UpdateRenderData(const TransformComponent& transform, const MaterialComponent& material, const MeshComponent* mesh, GRAPHICSTHREAD threadID)
void wiEmittedParticle::UpdateGPU(const TransformComponent& transform, const MaterialComponent& material, const MeshComponent* mesh, GRAPHICSTHREAD threadID) const
{
center = transform.GetPosition();
CreateSelfBuffers();
if (particleBuffer == nullptr)
{
return;
}
GraphicsDevice* device = wiRenderer::GetDevice();
if (!IsPaused())
{
device->EventBegin("UpdateEmittedParticles", threadID);
EmittedParticleCB cb;
@@ -568,16 +582,6 @@ void wiEmittedParticle::UpdateRenderData(const TransformComponent& transform, co
device->UnbindUAVs(0, ARRAYSIZE(uavs), threadID);
device->UnbindResources(0, ARRAYSIZE(res), threadID);
device->EventEnd(threadID);
// Swap CURRENT alivelist with NEW alivelist
aliveList[0].swap(aliveList[1]);
emit -= (UINT)emit;
}
if (IsDebug())
{
device->DownloadResource(counterBuffer.get(), debugDataReadbackBuffer.get(), &debugData, threadID);
}
}
@@ -601,7 +605,7 @@ void wiEmittedParticle::Draw(const CameraComponent& camera, const MaterialCompon
GPUResource* res[] = {
particleBuffer.get(),
aliveList[0].get()
aliveList[1].get() // NEW aliveList
};
device->TransitionBarrier(res, ARRAYSIZE(res), RESOURCE_STATE_UNORDERED_ACCESS, RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, threadID);
device->BindResources(VS, res, 0, ARRAYSIZE(res), threadID);
+2 -2
View File
@@ -48,12 +48,12 @@ private:
uint32_t MAX_PARTICLES = 1000;
public:
void Update(float dt);
void UpdateCPU(const TransformComponent& transform, float dt);
void Burst(float num);
void Restart();
// Must have a transform and material component, but mesh is optional
void UpdateRenderData(const TransformComponent& transform, const MaterialComponent& material, const MeshComponent* mesh, GRAPHICSTHREAD threadID);
void UpdateGPU(const TransformComponent& transform, const MaterialComponent& material, const MeshComponent* mesh, GRAPHICSTHREAD threadID) const;
void Draw(const CameraComponent& camera, const MaterialComponent& material, GRAPHICSTHREAD threadID) const;
ParticleCounters GetDebugData() { return debugData; }
+54 -33
View File
@@ -29,43 +29,64 @@ static GraphicsPSO PSO[RENDERPASS_COUNT][2];
static GraphicsPSO PSO_wire;
static ComputePSO CPSO_simulate;
void wiHairParticle::UpdateRenderData(const MeshComponent& mesh, const MaterialComponent& material, GRAPHICSTHREAD threadID)
void wiHairParticle::UpdateCPU(const TransformComponent& transform, const MeshComponent& mesh, float dt)
{
if (strandCount == 0)
world = transform.world;
XMFLOAT3 _min = mesh.aabb.getMin();
XMFLOAT3 _max = mesh.aabb.getMax();
_max.x += length;
_max.y += length;
_max.z += length;
_min.x -= length;
_min.y -= length;
_min.z -= length;
aabb = AABB(_min, _max);
aabb = aabb.get(world);
if (dt > 0)
{
return;
_flags &= ~REGENERATE_FRAME;
if (cb == nullptr || (strandCount * segmentCount) != particleBuffer->GetDesc().ByteWidth / sizeof(Patch))
{
_flags |= REGENERATE_FRAME;
cb.reset(new GPUBuffer);
particleBuffer.reset(new GPUBuffer);
simulationBuffer.reset(new GPUBuffer);
GPUBufferDesc bd;
bd.Usage = USAGE_DEFAULT;
bd.BindFlags = BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS;
bd.CPUAccessFlags = 0;
bd.MiscFlags = RESOURCE_MISC_BUFFER_STRUCTURED;
bd.StructureByteStride = sizeof(Patch);
bd.ByteWidth = bd.StructureByteStride * strandCount * segmentCount;
wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, particleBuffer.get());
bd.StructureByteStride = sizeof(PatchSimulationData);
bd.ByteWidth = bd.StructureByteStride * strandCount * segmentCount;
wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, simulationBuffer.get());
bd.Usage = USAGE_DYNAMIC;
bd.ByteWidth = sizeof(HairParticleCB);
bd.BindFlags = BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, cb.get());
}
}
bool regenerate = false;
if(cb == nullptr || (strandCount * segmentCount) != particleBuffer->GetDesc().ByteWidth / sizeof(Patch))
}
void wiHairParticle::UpdateGPU(const MeshComponent& mesh, const MaterialComponent& material, GRAPHICSTHREAD threadID) const
{
if (strandCount == 0 || particleBuffer == nullptr)
{
regenerate = true;
cb.reset(new GPUBuffer);
particleBuffer.reset(new GPUBuffer);
simulationBuffer.reset(new GPUBuffer);
GPUBufferDesc bd;
bd.Usage = USAGE_DEFAULT;
bd.BindFlags = BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS;
bd.CPUAccessFlags = 0;
bd.MiscFlags = RESOURCE_MISC_BUFFER_STRUCTURED;
bd.StructureByteStride = sizeof(Patch);
bd.ByteWidth = bd.StructureByteStride * strandCount * segmentCount;
wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, particleBuffer.get());
bd.StructureByteStride = sizeof(PatchSimulationData);
bd.ByteWidth = bd.StructureByteStride * strandCount * segmentCount;
wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, simulationBuffer.get());
bd.Usage = USAGE_DYNAMIC;
bd.ByteWidth = sizeof(HairParticleCB);
bd.BindFlags = BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, cb.get());
return;
}
GraphicsDevice* device = wiRenderer::GetDevice();
@@ -76,7 +97,7 @@ void wiHairParticle::UpdateRenderData(const MeshComponent& mesh, const MaterialC
HairParticleCB hcb;
hcb.xWorld = world;
hcb.xColor = material.baseColor;
hcb.xHairRegenerate = regenerate ? 1 : 0;
hcb.xHairRegenerate = (_flags & REGENERATE_FRAME) ? 1 : 0;
hcb.xLength = length;
hcb.xStiffness = stiffness;
hcb.xHairRandomness = randomness;
+3 -1
View File
@@ -18,12 +18,14 @@ private:
std::unique_ptr<wiGraphicsTypes::GPUBuffer> simulationBuffer;
public:
void UpdateRenderData(const MeshComponent& mesh, const MaterialComponent& material, GRAPHICSTHREAD threadID);
void UpdateCPU(const TransformComponent& transform, const MeshComponent& mesh, float dt);
void UpdateGPU(const MeshComponent& mesh, const MaterialComponent& material, GRAPHICSTHREAD threadID) const;
void Draw(const CameraComponent& camera, const MaterialComponent& material, RENDERPASS renderPass, bool transparent, GRAPHICSTHREAD threadID) const;
enum FLAGS
{
EMPTY = 0,
REGENERATE_FRAME = 1 << 0,
};
uint32_t _flags = EMPTY;
+73 -63
View File
@@ -264,6 +264,8 @@ struct FrameCulling
};
unordered_map<const CameraComponent*, FrameCulling> frameCullings;
vector<uint32_t> pendingMaterialUpdates;
GFX_STRUCT Instance
{
XMFLOAT4A mat0;
@@ -3510,7 +3512,35 @@ void UpdatePerFrameData(float dt)
scene.Update(dt * GetGameSpeed());
// Need to swap prev and current vertex buffers for any dynamic meshes BEFORE render threads are kicked:
// See which materials will need to update their GPU render data:
wiJobSystem::Execute([&] {
pendingMaterialUpdates.clear();
for (size_t i = 0; i < scene.materials.GetCount(); ++i)
{
MaterialComponent& material = scene.materials[i];
if (material.IsDirty())
{
material.SetDirty(false);
pendingMaterialUpdates.push_back(uint32_t(i));
if (material.constantBuffer == nullptr)
{
GPUBufferDesc desc;
desc.Usage = USAGE_DEFAULT;
desc.BindFlags = BIND_CONSTANT_BUFFER;
desc.ByteWidth = sizeof(MaterialCB);
material.constantBuffer.reset(new GPUBuffer);
HRESULT hr = device->CreateBuffer(&desc, nullptr, material.constantBuffer.get());
assert(SUCCEEDED(hr));
}
}
}
});
// Need to swap prev and current vertex buffers for any dynamic meshes BEFORE render threads are kicked
// and also create skinning bone buffers:
wiJobSystem::Execute([&] {
for (size_t i = 0; i < scene.meshes.GetCount(); ++i)
{
@@ -3518,6 +3548,23 @@ void UpdatePerFrameData(float dt)
if (mesh.IsSkinned() && scene.armatures.Contains(mesh.armatureID))
{
ArmatureComponent& armature = *scene.armatures.GetComponent(mesh.armatureID);
if (armature.boneBuffer == nullptr)
{
GPUBufferDesc bd;
bd.Usage = USAGE_DYNAMIC;
bd.CPUAccessFlags = CPU_ACCESS_WRITE;
bd.ByteWidth = sizeof(ArmatureComponent::ShaderBoneType) * (UINT)armature.boneCollection.size();
bd.BindFlags = BIND_SHADER_RESOURCE;
bd.MiscFlags = RESOURCE_MISC_BUFFER_STRUCTURED;
bd.StructureByteStride = sizeof(ArmatureComponent::ShaderBoneType);
armature.boneBuffer.reset(new GPUBuffer);
HRESULT hr = device->CreateBuffer(&bd, nullptr, armature.boneBuffer.get());
assert(SUCCEEDED(hr));
}
if (mesh.vertexBuffer_PRE == nullptr)
{
mesh.vertexBuffer_PRE.reset(new GPUBuffer);
@@ -3738,7 +3785,7 @@ void UpdatePerFrameData(float dt)
void UpdateRenderData(GRAPHICSTHREAD threadID)
{
GraphicsDevice* device = GetDevice();
Scene& scene = GetScene(); // this is not const, so that means that later render passes will depend on this
const Scene& scene = GetScene();
// Process deferred MIP generation:
deferredMIPGenLock.lock();
@@ -3751,45 +3798,22 @@ void UpdateRenderData(GRAPHICSTHREAD threadID)
// Update material constant buffers:
MaterialCB materialGPUData;
for (size_t i = 0; i < scene.materials.GetCount(); ++i)
for (auto& materialIndex : pendingMaterialUpdates)
{
MaterialComponent& material = scene.materials[i];
const MaterialComponent& material = scene.materials[materialIndex];
if (material.IsDirty())
{
material.SetDirty(false);
materialGPUData.g_xMat_baseColor = material.baseColor;
materialGPUData.g_xMat_texMulAdd = material.texMulAdd;
materialGPUData.g_xMat_roughness = material.roughness;
materialGPUData.g_xMat_reflectance = material.reflectance;
materialGPUData.g_xMat_metalness = material.metalness;
materialGPUData.g_xMat_emissive = material.emissive;
materialGPUData.g_xMat_refractionIndex = material.refractionIndex;
materialGPUData.g_xMat_subsurfaceScattering = material.subsurfaceScattering;
materialGPUData.g_xMat_normalMapStrength = (material.normalMap == nullptr ? 0 : material.normalMapStrength);
materialGPUData.g_xMat_parallaxOcclusionMapping = material.parallaxOcclusionMapping;
if (material.constantBuffer == nullptr)
{
GPUBufferDesc desc;
desc.Usage = USAGE_DEFAULT;
desc.BindFlags = BIND_CONSTANT_BUFFER;
desc.ByteWidth = sizeof(MaterialCB);
SubresourceData InitData;
InitData.pSysMem = &materialGPUData;
material.constantBuffer.reset(new GPUBuffer);
device->CreateBuffer(&desc, &InitData, material.constantBuffer.get());
}
else
{
device->UpdateBuffer(material.constantBuffer.get(), &materialGPUData, threadID);
}
}
materialGPUData.g_xMat_baseColor = material.baseColor;
materialGPUData.g_xMat_texMulAdd = material.texMulAdd;
materialGPUData.g_xMat_roughness = material.roughness;
materialGPUData.g_xMat_reflectance = material.reflectance;
materialGPUData.g_xMat_metalness = material.metalness;
materialGPUData.g_xMat_emissive = material.emissive;
materialGPUData.g_xMat_refractionIndex = material.refractionIndex;
materialGPUData.g_xMat_subsurfaceScattering = material.subsurfaceScattering;
materialGPUData.g_xMat_normalMapStrength = (material.normalMap == nullptr ? 0 : material.normalMapStrength);
materialGPUData.g_xMat_parallaxOcclusionMapping = material.parallaxOcclusionMapping;
device->UpdateBuffer(material.constantBuffer.get(), &materialGPUData, threadID);
}
@@ -4038,23 +4062,7 @@ void UpdateRenderData(GRAPHICSTHREAD threadID)
if (mesh.IsSkinned() && scene.armatures.Contains(mesh.armatureID))
{
ArmatureComponent& armature = *scene.armatures.GetComponent(mesh.armatureID);
if (armature.boneBuffer == nullptr)
{
GPUBufferDesc bd;
bd.Usage = USAGE_DYNAMIC;
bd.CPUAccessFlags = CPU_ACCESS_WRITE;
bd.ByteWidth = sizeof(ArmatureComponent::ShaderBoneType) * (UINT)armature.boneCollection.size();
bd.BindFlags = BIND_SHADER_RESOURCE;
bd.MiscFlags = RESOURCE_MISC_BUFFER_STRUCTURED;
bd.StructureByteStride = sizeof(ArmatureComponent::ShaderBoneType);
armature.boneBuffer.reset(new GPUBuffer);
HRESULT hr = device->CreateBuffer(&bd, nullptr, armature.boneBuffer.get());
assert(SUCCEEDED(hr));
}
const ArmatureComponent& armature = *scene.armatures.GetComponent(mesh.armatureID);
if (!streamOutSetUp)
{
@@ -4149,19 +4157,19 @@ void UpdateRenderData(GRAPHICSTHREAD threadID)
// GPU Particle systems simulation/sorting/culling:
for (size_t i = 0; i < scene.emitters.GetCount(); ++i)
{
wiEmittedParticle& emitter = scene.emitters[i];
const wiEmittedParticle& emitter = scene.emitters[i];
Entity entity = scene.emitters.GetEntity(i);
const TransformComponent& transform = *scene.transforms.GetComponent(entity);
const MaterialComponent& material = *scene.materials.GetComponent(entity);
const MeshComponent* mesh = scene.meshes.GetComponent(emitter.meshID);
emitter.UpdateRenderData(transform, material, mesh, threadID);
emitter.UpdateGPU(transform, material, mesh, threadID);
}
// Hair particle systems simulation:
// Hair particle systems GPU simulation:
for (size_t i = 0; i < scene.hairs.GetCount(); ++i)
{
wiHairParticle& hair = scene.hairs[i];
const wiHairParticle& hair = scene.hairs[i];
if (hair.meshID != INVALID_ENTITY && GetCamera().frustum.CheckBox(hair.aabb))
{
@@ -4172,7 +4180,7 @@ void UpdateRenderData(GRAPHICSTHREAD threadID)
Entity entity = scene.hairs.GetEntity(i);
const MaterialComponent& material = *scene.materials.GetComponent(entity);
hair.UpdateRenderData(*mesh, material, threadID);
hair.UpdateGPU(*mesh, material, threadID);
}
}
}
@@ -4237,6 +4245,7 @@ void OcclusionCulling_Render(GRAPHICSTHREAD threadID)
device->BindGraphicsPSO(PSO_occlusionquery, threadID);
// TODO: This is not const, so not thread safe!
Scene& scene = GetScene();
int queryID = 0;
@@ -5809,6 +5818,7 @@ void DrawDebugWorld(const CameraComponent& camera, GRAPHICSTHREAD threadID)
void DrawSky(GRAPHICSTHREAD threadID)
{
GraphicsDevice* device = GetDevice();
const Scene& scene = GetScene();
device->EventBegin("DrawSky", threadID);
@@ -5819,7 +5829,7 @@ void DrawSky(GRAPHICSTHREAD threadID)
else
{
device->BindGraphicsPSO(PSO_sky[SKYRENDERING_DYNAMIC], threadID);
if (GetScene().weather.cloudiness > 0)
if (scene.weather.cloudiness > 0)
{
device->BindResource(PS, textures[TEXTYPE_2D_CLOUDS], TEXSLOT_ONDEMAND0, threadID);
}
@@ -6313,7 +6323,7 @@ void RefreshImpostors(GRAPHICSTHREAD threadID)
{
continue;
}
MaterialComponent& material = *GetScene().materials.GetComponent(subset.materialID);
const MaterialComponent& material = *scene.materials.GetComponent(subset.materialID);
device->BindConstantBuffer(PS, material.constantBuffer.get(), CB_GETBINDSLOT(MaterialCB), threadID);
@@ -7690,7 +7700,7 @@ unordered_map<Texture2D*, wiRectPacker::rect_xywh> packedLightmaps;
void RenderObjectLightMap(ObjectComponent& object, bool updateBVHAndScene, GRAPHICSTHREAD threadID)
{
GraphicsDevice* device = GetDevice();
Scene& scene = GetScene();
const Scene& scene = GetScene();
HRESULT hr;
device->EventBegin("RenderObjectLightMap", threadID);
+4 -15
View File
@@ -1915,7 +1915,9 @@ namespace wiSceneSystem
wiJobSystem::Dispatch((uint32_t)emitters.GetCount(), small_subtask_groupsize, [&](wiJobDispatchArgs args) {
wiEmittedParticle& emitter = emitters[args.jobIndex];
emitter.Update(dt);
Entity entity = emitters.GetEntity(args.jobIndex);
const TransformComponent& transform = *transforms.GetComponent(entity);
emitter.UpdateCPU(transform, dt);
});
wiJobSystem::Dispatch((uint32_t)hairs.GetCount(), small_subtask_groupsize, [&](wiJobDispatchArgs args) {
@@ -1923,7 +1925,6 @@ namespace wiSceneSystem
wiHairParticle& hair = hairs[args.jobIndex];
Entity entity = hairs.GetEntity(args.jobIndex);
const TransformComponent& transform = *transforms.GetComponent(entity);
hair.world = transform.world;
if (hair.meshID != INVALID_ENTITY)
{
@@ -1931,19 +1932,7 @@ namespace wiSceneSystem
if (mesh != nullptr)
{
XMFLOAT3 min = mesh->aabb.getMin();
XMFLOAT3 max = mesh->aabb.getMax();
max.x += hair.length;
max.y += hair.length;
max.z += hair.length;
min.x -= hair.length;
min.y -= hair.length;
min.z -= hair.length;
hair.aabb = AABB(min, max);
hair.aabb = hair.aabb.get(hair.world);
hair.UpdateCPU(transform, *mesh, dt);
}
}
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wiVersion
// minor features, major updates
const int minor = 24;
// minor bug fixes, alterations, refactors, updates
const int revision = 42;
const int revision = 43;
long GetVersion()