1#include "RenderMaterialInstance.h"
3#include "Rendering/IEffects.h"
4#include "Rendering/IBuffers.h"
5#include "Rendering/IContext.h"
6#include "Rendering/ITextures.h"
7#include "Rendering/ICapabilities.h"
11#include "RenderStates.h"
12#include "RenderResources.h"
13#include "Resources/MaterialManager.h"
18#include "Foundation/HashSequence.h"
19#include "Foundation/Logging/Logger.h"
29 for (
auto& buffer : that->ownedBuffers) {
35 for (
auto& buffer : that->buffers) {
37 buffer.generation = 0;
40 that->ownedBuffers.clear();
49 LOG_ERROR(logger,
"MeshStreamsLayout has streams but hash is zero.");
63 if (that->context->
variables->get(
"renderer.disableMaterialUpdates",
false)) {
72 clearBuffers(that, deviceBuffers);
74 that->buffers.resize(material->constantBuffers.
buffers.size());
76 for (
auto& buffer : material->constantBuffers.
buffers) {
78 if (buffer.isPerInstance && buffer.size) {
80 deviceBuffers->
annotate(that->buffers[buffer.index].handle, material->definition.name +
"_matinst_" + std::to_string(buffer.index));
82 that->ownedBuffers.push_back(that->buffers[buffer.index].handle);
83 that->buffers[buffer.index].bound =
true;
88 for (
auto& buffer : material->constantBuffers.
buffers) {
89 if (!buffer.isPerInstance)
continue;
91 auto& instanceBuffer = materialInstance->
buffers[buffer.index];
94 bool dirty = updateBuffer.generation != instanceBuffer.generation;
97 immediateContext->
updateBuffer(updateBuffer.handle, instanceBuffer.content.data(), buffer.size);
98 updateBuffer.generation = instanceBuffer.generation;
120 t.texture.filterMode,
121 Cogs::SamplerState::Never,
122 static_cast<unsigned int>(settings.anisotropicFiltering->getInt()),
126 that->samplerStates[t.key] = renderStates->getSamplerState(state);
137 if (!renderMaterial) {
138 return ActivationResult::Postponed;
141 if (renderMaterial->hasFailed()) {
142 instance->setFailed();
143 return ActivationResult::Failure;
145 else if (renderMaterial->isReleased()) {
146 LOG_ERROR(logger,
"Could not initialize material instance for released material.");
147 instance->setFailed();
148 return ActivationResult::Failure;
151 instance->setDelayed();
152 return ActivationResult::Delayed;
154 else if (!renderMaterial->
isActive()) {
155 return ActivationResult::Postponed;
158 return ActivationResult::Success;
167 context = resources->getContext();
169 renderMaterial = resources->getRenderMaterial(materialInstance->
material);
171 auto checkResult = checkMaterial(
this, renderMaterial);
175 updateTextureProperties(
this, materialInstance, device, renderStates);
178 loadedBindings.clear();
184 std::vector<RenderEffectBinding> stillPending;
186 for (RenderEffectBinding& pending : pendingBindings) {
188 if (pending.variantGeneration != variantGeneration)
continue;
192 &pending.streamsLayout,
193 pending.enginePermutation,
197 if (binding->renderEffect &&
202 loadedBindings.push_back(std::move(pending));
203 loadedBindings.back().variantGeneration = 0u;
206 stillPending.push_back(std::move(pending));
207 materialInstance->setChanged();
211 pendingBindings = std::move(stillPending);
213 for (
auto & loaded : loadedBindings) {
214 updateBindings(
this, materialInstance, materialInstance->
material, device, loaded.binding);
223void Cogs::Core::RenderMaterialInstance::release(
Renderer * renderer)
225 assert(!isReleased());
240 if (
const EffectBinding* bindings = getBindings(streamsLayout, permutation, passOptions, clipShape); bindings) {
242 if (!bindings->renderEffect ||
243 bindings->renderEffect->isDelayed() ||
251 if (bindings->renderEffect && bindings->renderEffect->isDelayed()) {
252 bindings->renderEffect->requestLoad();
253 context->engine->setDirty();
256 else if (renderMaterial->
isDelayed() || renderMaterial->pendingBindings.size()) {
258 material->setChanged();
261 if (materialInstance->hasFailedActivation()) {
262 materialInstance->setChanged();
263 materialInstance->
material->setChanged();
275 size_t permuationCode = getBindingCode(streamsLayout, permutation, passOptions, clipShape);
280 if (renderMaterial) {
281 binding = renderMaterial->
getBinding(permutationIndex,
289 if (binding && binding->renderEffect && binding->buffersGeneration == material->constantBuffers.
buffersGeneration) {
290 auto device = context->renderer->getDevice();
291 updateBindings(
this, materialInstance, material, device, binding);
292 updateTextureProperties(
this, materialInstance, device, &context->renderer->getRenderStates());
294 loadedBindings.push_back(
RenderEffectBinding{ permuationCode, streamsLayout, permutation, passOptions, clipShape, binding, 0 });
296 return checkReady(streamsLayout, permutation, passOptions, clipShape);
300 pendingBindings.emplace_back(
RenderEffectBinding{ permuationCode, streamsLayout, permutation, passOptions, clipShape, binding, variantGeneration });
302 materialInstance->setChanged();
303 context->engine->setDirty();
307 if (materialInstance->hasFailedActivation()) {
308 materialInstance->setChanged();
309 materialInstance->
material->setChanged();
321 permutation = context->renderer->getEnginePermutations().get(permutation->getIndex());
323 size_t code = getBindingCode(streamsLayout, permutation, passOptions, clipShape);
325 for (
auto & binding : loadedBindings) {
326 if (binding.permutationCode == code)
return binding.binding;
329 for (
auto & binding : pendingBindings) {
330 if (binding.permutationCode == code)
return binding.binding;
class IRenderer * renderer
Renderer.
std::unique_ptr< class Variables > variables
Variables service instance.
virtual const RenderSettings & getSettings() const =0
Get the settings of the renderer.
Contains render resources used by the renderer.
IGraphicsDevice * getDevice() override
Get the graphics device used by the renderer.
Represents a graphics device used to manage graphics resources and issue drawing commands.
virtual IContext * getImmediateContext()=0
Get a pointer to the immediate context used to issue commands to the graphics device.
virtual IBuffers * getBuffers()=0
Get a pointer to the buffer management interface.
Log implementation class.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
ClipShapeType
Specifices what kind of shape a clip shape has.
ActivationResult
Defines results for resource activation.
@ Success
Resource activated successfully.
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
constexpr size_t hashSequence(const T &t, const U &u)
Hash the last two items in a sequence of objects.
@ Write
The buffer can be mapped and written to by the CPU after creation.
@ ConstantBuffer
The buffer can be bound as input to effects as a constant buffer.
std::vector< MaterialPropertyBuffer > buffers
Constant buffer instances.
uint16_t buffersGeneration
If the constant buffer bindings need updates.
Material instances represent a specialized Material combined with state for all its buffers and prope...
std::vector< TextureValue > textureVariables
Texture property values for this instance.
uint16_t buffersGeneration
If the material buffer bindings need updates.
std::vector< MaterialPropertyBufferInstance > buffers
Buffer instances matching the buffers and layout of the parent material.
size_t variantGeneration
If the variant or definitions need updates.
size_t permutationIndex
Index of material permutation to use.
Material * material
Material resource this MaterialInstance is created from.
Material resources define the how of geometry rendering (the what is defined by Mesh and Texture reso...
const EffectBinding * getBindings(const MeshStreamsLayout &streamsLayout, const EnginePermutation *permutation, const RenderPassOptions &passOptions, ClipShapeType clipShape) const
const EffectBinding * checkReady(const MeshStreamsLayout &streamsLayout, const EnginePermutation *permutation, const RenderPassOptions &passOptions, ClipShapeType clipShape)
EffectBinding * getBinding(const size_t permutationIndex, const MaterialInstance *materialInstance, const MeshStreamsLayout *streamsLayout, const EnginePermutation *enginePermutation, const RenderPassOptions &passOptions, const ClipShapeType clipShape)
bool isDelayed() const
Get if the render resource is in a delayed state.
bool isActive() const
Get if the render resource is active and can be used for rendering.
static const Handle_t NoHandle
Represents a handle to nothing.
Provides buffer management functionality.
virtual void annotate(BufferHandle handle, const StringView &name)
Associate a name with an object for use in graphics debugging.
virtual BufferHandle loadBuffer(const void *data, const size_t size, Usage::EUsage usage, uint32_t accessMode, uint32_t bindFlags, uint32_t stride=0)=0
Loads a new buffer using the given data to populate the buffer.
virtual void releaseBuffer(BufferHandle bufferHandle)=0
Releases the buffer with the given bufferHandle.
Represents a graphics device context which can receive rendering commands.
virtual void updateBuffer(BufferHandle bufferHandle, const void *data, size_t size)=0
Replace contents of buffer with new data.
Encapsulates state for texture sampling in a state object.
@ Dynamic
Buffer will be loaded and modified with some frequency.