1#include "RenderTargetsGLES30.h"
3#include "TexturesGLES30.h"
4#include "CapabilitiesGLES30.h"
5#include "GraphicsDeviceGLES30.h"
20 void glFramebufferTextureMultiviewOVR(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews)
24 const attachment = $1;
25 const texture = Module.GL.textures[$2];
27 const baseViewIndex = $4;
31 for (
const item of Object.values(Module.GL.contexts)) {
32 if (item && item.hasOwnProperty(
'GLctx')) {
33 const ext = item.GLctx.getExtension(
"OVR_multiview2");
35 ext.framebufferTextureMultiviewOVR(target, attachment, texture, level, baseViewIndex, numViews);
40 }, target, attachment, texture, level, baseViewIndex, numViews);
43 void glFramebufferTextureMultisampleMultiviewOVR(GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews)
47 const attachment = $1;
48 const texture = Module.GL.textures[$2];
51 const baseViewIndex = $5;
55 for (
const item of Object.values(Module.GL.contexts)) {
56 if (item && item.hasOwnProperty(
'GLctx')) {
59 const ext = item.GLctx.getExtension(
"OCULUS_multiview");
61 ext.framebufferTextureMultisampleMultiviewOVR(target, attachment, texture, level, samples, baseViewIndex, numViews);
66 }, target, attachment, texture, level, samples, baseViewIndex, numViews);
79 GLuint& depthRenderbuffer,
87 assert((fbo == 0) && (depthRenderbuffer == 0) && (colorCount <= Cogs::OpenGLES30::kMaxRenderTargets));
88 glGenFramebuffers(1, &fbo);
89 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
92 assert((colorCount == 0) || (colorViewDesc && colorViewData));
93 GLenum drawBuffers[Cogs::OpenGLES30::kMaxRenderTargets];
94 for (
size_t i = 0; i < colorCount; i++) {
95 drawBuffers[i] = GL_COLOR_ATTACHMENT0 +
static_cast<GLint
>(i);
104 switch (tex.format) {
105 case Cogs::Format::R8_UNORM: [[fallthrough]];
106 case Cogs::Format::R8G8_UNORM: [[fallthrough]];
107 case Cogs::Format::R8G8B8_UNORM: [[fallthrough]];
108 case Cogs::Format::R8G8B8A8_UNORM: [[fallthrough]];
109 case Cogs::Format::R16_UNORM: [[fallthrough]];
110 case Cogs::Format::R16G16_UNORM: [[fallthrough]];
111 case Cogs::Format::R16G16B16_UNORM: [[fallthrough]];
112 case Cogs::Format::R16G16B16A16_UNORM: [[fallthrough]];
113 case Cogs::Format::R8_SNORM: [[fallthrough]];
114 case Cogs::Format::R8G8_SNORM: [[fallthrough]];
115 case Cogs::Format::R8G8B8_SNORM: [[fallthrough]];
116 case Cogs::Format::R8G8B8A8_SNORM: [[fallthrough]];
117 case Cogs::Format::R16_SNORM: [[fallthrough]];
118 case Cogs::Format::R16G16_SNORM: [[fallthrough]];
119 case Cogs::Format::R16G16B16_SNORM: [[fallthrough]];
120 case Cogs::Format::R16G16B16A16_SNORM: [[fallthrough]];
121 case Cogs::Format::R16_FLOAT: [[fallthrough]];
122 case Cogs::Format::R16G16_FLOAT: [[fallthrough]];
123 case Cogs::Format::R16G16B16_FLOAT: [[fallthrough]];
124 case Cogs::Format::R16G16B16A16_FLOAT: [[fallthrough]];
125 case Cogs::Format::R32_FLOAT: [[fallthrough]];
126 case Cogs::Format::R32G32_FLOAT: [[fallthrough]];
127 case Cogs::Format::R32G32B32_FLOAT: [[fallthrough]];
128 case Cogs::Format::R32G32B32A32_FLOAT: [[fallthrough]];
129 case Cogs::Format::A8_UNORM: [[fallthrough]];
130 case Cogs::Format::BC1_TYPELESS: [[fallthrough]];
131 case Cogs::Format::BC1_UNORM: [[fallthrough]];
132 case Cogs::Format::BC1_UNORM_SRGB: [[fallthrough]];
133 case Cogs::Format::BC2_UNORM: [[fallthrough]];
134 case Cogs::Format::BC2_UNORM_SRGB: [[fallthrough]];
135 case Cogs::Format::BC3_UNORM: [[fallthrough]];
136 case Cogs::Format::BC3_UNORM_SRGB: [[fallthrough]];
137 case Cogs::Format::BC4_UNORM: [[fallthrough]];
138 case Cogs::Format::BC4_SNORM: [[fallthrough]];
139 case Cogs::Format::BC5_UNORM: [[fallthrough]];
140 case Cogs::Format::BC5_SNORM: [[fallthrough]];
141 case Cogs::Format::R8G8B8A8_UNORM_SRGB: [[fallthrough]];
142 case Cogs::Format::R10G10B10A2_UNORM:
143 viewData.basicType = 1;
146 case Cogs::Format::R8_UINT: [[fallthrough]];
147 case Cogs::Format::R8G8_UINT: [[fallthrough]];
148 case Cogs::Format::R8G8B8_UINT: [[fallthrough]];
149 case Cogs::Format::R8G8B8A8_UINT: [[fallthrough]];
150 case Cogs::Format::R16_UINT: [[fallthrough]];
151 case Cogs::Format::R16G16_UINT: [[fallthrough]];
152 case Cogs::Format::R16G16B16_UINT: [[fallthrough]];
153 case Cogs::Format::R16G16B16A16_UINT: [[fallthrough]];
154 case Cogs::Format::R32_UINT: [[fallthrough]];
155 case Cogs::Format::R32G32_UINT: [[fallthrough]];
156 case Cogs::Format::R32G32B32_UINT: [[fallthrough]];
157 case Cogs::Format::R32G32B32A32_UINT: [[fallthrough]];
158 case Cogs::Format::R10G10B10A2_UINT:
159 viewData.basicType = 2;
162 case Cogs::Format::R8_SINT: [[fallthrough]];
163 case Cogs::Format::R8G8_SINT: [[fallthrough]];
164 case Cogs::Format::R8G8B8_SINT: [[fallthrough]];
165 case Cogs::Format::R8G8B8A8_SINT: [[fallthrough]];
166 case Cogs::Format::R16_SINT: [[fallthrough]];
167 case Cogs::Format::R16G16_SINT: [[fallthrough]];
168 case Cogs::Format::R16G16B16_SINT: [[fallthrough]];
169 case Cogs::Format::R16G16B16A16_SINT: [[fallthrough]];
170 case Cogs::Format::R32_SINT: [[fallthrough]];
171 case Cogs::Format::R32G32_SINT: [[fallthrough]];
172 case Cogs::Format::R32G32B32_SINT: [[fallthrough]];
173 case Cogs::Format::R32G32B32A32_SINT:
174 viewData.basicType = 3;
178 viewData.basicType = 0;
183 if (1 < multiView.count) {
184 assert(tex.target == GL_TEXTURE_2D_ARRAY);
185 if (1 < multiView.samples) {
186 glFramebufferTextureMultisampleMultiviewOVR(GL_FRAMEBUFFER, drawBuffers[i], tex.textureId, viewDesc.levelIndex, multiView.samples, multiView.baseIndex, multiView.count);
189 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, drawBuffers[i], tex.textureId, viewDesc.levelIndex, multiView.baseIndex, multiView.count);
195 switch (tex.target) {
197 glFramebufferTexture2D(GL_FRAMEBUFFER, drawBuffers[i], GL_TEXTURE_2D, tex.textureId, viewDesc.levelIndex);
199 case GL_TEXTURE_CUBE_MAP:
200 glFramebufferTexture2D(GL_FRAMEBUFFER, drawBuffers[i], GL_TEXTURE_CUBE_MAP_POSITIVE_X + viewDesc.layerIndex, tex.textureId, depth.
levelIndex);
203 case GL_TEXTURE_2D_ARRAY:
204 glFramebufferTextureLayer(GL_FRAMEBUFFER, drawBuffers[i], tex.textureId, viewDesc.levelIndex, viewDesc.layerIndex);
206 case GL_TEXTURE_2D_MULTISAMPLE:
207 case GL_RENDERBUFFER:
208 glFramebufferRenderbuffer(GL_FRAMEBUFFER, drawBuffers[i], GL_RENDERBUFFER, tex.renderBuffer);
211 assert(
false &&
"Invalid texture type");
215 glDrawBuffers(GLsizei(colorCount), drawBuffers);
220 if (1 < multiView.count) {
223 assert(tex.target == GL_TEXTURE_2D_ARRAY);
224 if (1 < multiView.samples) {
225 glFramebufferTextureMultisampleMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, tex.textureId, depth.
levelIndex, multiView.samples, multiView.baseIndex, multiView.count);
228 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, tex.textureId, depth.
levelIndex, multiView.baseIndex, multiView.count);
235 switch (tex.target) {
237 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex.textureId, depth.
levelIndex);
239 case GL_TEXTURE_CUBE_MAP:
240 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + depth.
layerIndex, tex.textureId, depth.
levelIndex);
243 case GL_TEXTURE_2D_ARRAY:
244 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, tex.textureId, depth.
levelIndex, depth.
layerIndex);
246 case GL_TEXTURE_2D_MULTISAMPLE:
247 case GL_RENDERBUFFER:
248 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, tex.renderBuffer);
251 assert(
false &&
"Invalid texture type");
257 if (colorCount == 0 || colorViewDesc ==
nullptr || !
HandleIsValid(colorViewDesc[0].texture)) {
262 GLenum format = GL_DEPTH_COMPONENT32F;
263 GLsizei width = tex.width;
264 GLsizei height = tex.height;
266 glGenRenderbuffers(1, &depthRenderbuffer);
267 glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
268 if (tex.target == GL_TEXTURE_2D_MULTISAMPLE) {
269 GLint maxSampleCount = 0;
270 glGetInternalformativ(GL_RENDERBUFFER, format, GL_SAMPLES, 1, &maxSampleCount);
271 assert(0 <= maxSampleCount);
272 GLsizei numSamples = std::min(maxSampleCount, GLint(tex.numSamples));
273 glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples, format, width, height);
276 glRenderbufferStorage(GL_RENDERBUFFER, format, width, height);
278 glBindRenderbuffer(GL_RENDERBUFFER, 0);
279 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
283 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
284 if (status != GL_FRAMEBUFFER_COMPLETE) {
285 LOG_ERROR_ONCE(logger,
"Failed to create rendertarget: %s", Cogs::OpenGLES30::framebuffersStatusString(status));
286 glBindFramebuffer(GL_FRAMEBUFFER, 0);
288 glDeleteFramebuffers(1, &fbo);
291 if (depthRenderbuffer) {
292 glDeleteRenderbuffers(1, &depthRenderbuffer);
293 depthRenderbuffer = 0;
302const char* Cogs::OpenGLES30::framebuffersStatusString(GLenum status)
306 case GL_FRAMEBUFFER_UNDEFINED:
return "GL_FRAMEBUFFER_UNDEFINED";
307 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
308 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
309 case GL_FRAMEBUFFER_UNSUPPORTED:
return "GL_FRAMEBUFFER_UNSUPPORTED";
310 case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
return "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE";
311 case GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR:
return "GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR";
312 default:
return "<unknown>";
316bool Cogs::RenderTargetsGLES30::bindRenderTargets(RenderTargetHandle renderTargetHandle, DepthStencilHandle depthStencilHandle)
323 DepthStencilTargetGLES30& depthStencil = depthStencils[depthStencilHandle];
324 if (depthStencil.broken) {
328 if (depthStencil.fbo != 0) {
329 glBindFramebuffer(GL_FRAMEBUFFER, depthStencil.fbo);
333 size_t colorViewCount = 0;
334 RenderTargetViewDescription* colorViews =
nullptr;
335 RenderTargetViewDataGLES30* colorViewData =
nullptr;
338 if (depthStencil.renderTarget != renderTargetHandle) {
339 LOG_ERROR_ONCE(logger,
"depth-stencil target bound with a different rendertarget than with it was created.");
340 depthStencil.broken =
true;
344 RenderTargetGLES30& renderTarget = renderTargets[depthStencil.renderTarget];
345 colorViews = renderTarget.views;
346 colorViewData = renderTarget.viewData;
347 colorViewCount = renderTarget.numViews;
350 if (!setupFramebuffer(textures,
352 depthStencil.renderBuffer,
353 colorViews, colorViewData, colorViewCount,
355 depthStencil.multiView,
358 depthStencil.broken =
true;
362 LOG_TRACE(logger,
"Created color-depth render target");
367 RenderTargetGLES30& renderTarget = renderTargets[renderTargetHandle];
368 if (renderTarget.broken) {
372 if (renderTarget.fbo != 0) {
373 glBindFramebuffer(GL_FRAMEBUFFER, renderTarget.fbo);
377 GLuint renderBuffer = 0;
378 DepthStencilViewDescription depthStencilViewDesc{};
379 if(!setupFramebuffer(textures,
382 renderTarget.views, renderTarget.viewData, renderTarget.numViews,
383 depthStencilViewDesc,
384 renderTarget.multiView,
387 renderTarget.broken =
true;
390 assert(renderBuffer == 0);
391 LOG_TRACE(logger,
"Created color render target");
395 glBindFramebuffer(GL_FRAMEBUFFER, 0);
402 if (OpenGLES30::kMaxRenderTargets < numViews) {
403 LOG_ERROR(logger,
"maxRenderTargets (=%zu) < numViews (%zu)", OpenGLES30::kMaxRenderTargets, numViews);
408 renderTarget.numViews = uint8_t(numViews);
409 for (
size_t i = 0; i < renderTarget.numViews; i++) {
410 renderTarget.views[i] = renderTargetViews[i];
411 if (!HandleIsValid(renderTarget.views[i].texture)) {
412 LOG_ERROR_ONCE(logger,
"Cannot create rendertarget from NULL texture handle");
416 renderTarget.multiView.samples = 0;
417 renderTarget.multiView.baseIndex = 0;
418 renderTarget.multiView.count = 1;
419 renderTarget.broken = 0;
420 return renderTargets.addResource(std::move(renderTarget));
428 if (1 < multiView.
count) {
430 if (!deviceCaps.MultiView) {
431 LOG_ERROR_ONCE(logger,
"Cannot create multiview render target without multiview device support");
435 if (deviceCaps.MaxMultiViews < multiView.
count) {
436 LOG_ERROR_ONCE(logger,
"Requested %u rendertarget views but only %d is supported", multiView.
count, deviceCaps.MaxMultiViews);
440 for (
size_t i = 0; i < numViews; i++) {
441 if (!
HandleIsValid(renderTargetViews[i].texture) || textures->textures[renderTargetViews->
texture].target != GL_TEXTURE_2D_ARRAY) {
442 LOG_ERROR_ONCE(logger,
"Multiview rendering requires texture type GL_TEXTURE_2D_ARRAY");
451 RenderTargetGLES30& renderTarget = renderTargets[renderTargetHandle];
452 renderTarget.multiView.samples = deviceCaps.MultiSampleMultiView ? std::min(uint8_t(deviceCaps.MaxSamples), multiView.
samples) : 1;
453 renderTarget.multiView.baseIndex = multiView.
baseIndex;
454 renderTarget.multiView.count = multiView.
count;
456 return renderTargetHandle;
461 if (!HandleIsValid(renderTargetHandle)) {
466 depthStencilTarget.renderTarget = renderTargetHandle;
467 depthStencilTarget.multiView.samples = 1;
468 depthStencilTarget.multiView.baseIndex = 0;
469 depthStencilTarget.multiView.count = 1;
470 depthStencilTarget.broken = 0;
472 return this->depthStencils.addResource(std::move(depthStencilTarget));
482 depthStencilTarget.renderTarget = renderTargetHandle;
483 depthStencilTarget.view.texture = depthStencilTextureHandle;
484 depthStencilTarget.view.layerIndex = 0;
485 depthStencilTarget.view.numLayers = 1;
486 depthStencilTarget.view.levelIndex = 0;
487 depthStencilTarget.multiView.samples = 0;
488 depthStencilTarget.multiView.baseIndex = 0;
489 depthStencilTarget.multiView.count = 1;
490 depthStencilTarget.broken = 0;
491 return depthStencils.addResource(std::move(depthStencilTarget));
498 LOG_ERROR_ONCE(logger,
"Cannot create depth stencil target from invalid render target");
503 depthStencilTarget.renderTarget = renderTargetHandle;
504 depthStencilTarget.view = depthStencilView;
505 depthStencilTarget.multiView.samples = 0;
506 depthStencilTarget.multiView.baseIndex = 0;
507 depthStencilTarget.multiView.count = 1;
508 depthStencilTarget.broken = 0;
509 return depthStencils.addResource(std::move(depthStencilTarget));
516 if (!deviceCaps.MultiView) {
517 LOG_ERROR_ONCE(logger,
"Cannot create multiview depth-stencil target without multiview device support");
520 if (deviceCaps.MaxMultiViews < multiView.
count) {
521 LOG_ERROR_ONCE(logger,
"Requested %u depth-stencil views but only %d is supported", multiView.
count, deviceCaps.MaxMultiViews);
525 const RenderTargetGLES30& renderTarget = renderTargets[renderTargetHandle];
526 uint32_t samples = deviceCaps.MultiSampleMultiView ? std::min(uint8_t(deviceCaps.MaxSamples), multiView.
samples) : 1;
527 if (renderTarget.multiView.count != multiView.
count || renderTarget.multiView.samples != samples) {
528 LOG_ERROR_ONCE(logger,
"Multiview mis-match count: %u != %u, samples: %u != %u",
529 renderTarget.multiView.count, multiView.
count, renderTarget.multiView.samples, samples);
534 LOG_ERROR_ONCE(logger,
"Depth stencil texture is invalid");
541 DepthStencilTargetGLES30& depthStencil = depthStencils[depthStencilHandle];
542 depthStencil.multiView.samples = deviceCaps.MultiSampleMultiView ? std::min(uint8_t(deviceCaps.MaxSamples), multiView.
samples) : 1;
543 depthStencil.multiView.baseIndex = multiView.
baseIndex;
544 depthStencil.multiView.count = multiView.
count;
546 return depthStencilHandle;
552 if (renderTarget.fbo) {
553 glDeleteFramebuffers(1, &renderTarget.fbo);
554 renderTarget.fbo = 0;
556 renderTargets.removeResource(renderTargetHandle);
562 if (depthStencilTarget.fbo) {
563 glDeleteFramebuffers(1, &depthStencilTarget.fbo);
564 depthStencilTarget.fbo = 0;
566 if (depthStencilTarget.renderBuffer != 0) {
567 glDeleteRenderbuffers(1, &depthStencilTarget.renderBuffer);
568 depthStencilTarget.renderBuffer = 0;
570 depthStencils.removeResource(depthStencilHandle);
577 if (HandleIsValid(renderTargetHandle)) {
580 layout.
samples = std::max<uint8_t>(1, renderTarget.multiView.samples);
582 for (
size_t i = 0; i < renderTarget.numViews; ++i) {
594 if (HandleIsValid(depthStencilHandle)) {
597 ? this->textures->textures[depthStencil.view.
texture].format
598 : TextureFormat::D32_FLOAT;
599 }
else if (!HandleIsValid(renderTargetHandle)) {
608 return loadBlendState(blendState, blendState);
615 blendState.enabled = blendStateColor.
enabled || blendStateAlpha.
enabled;
618 blendState.blend.colorSrc = blendStateColor.
sourceBlend;
620 blendState.operation.color = blendStateColor.
operation;
624 blendState.blend.colorSrc = BlendState::Blend::One;
625 blendState.blend.colorDst = BlendState::Blend::Zero;
626 blendState.operation.color = BlendState::BlendOperation::Add;
630 blendState.blend.alphaSrc = blendStateAlpha.
sourceBlend;
632 blendState.operation.alpha = blendStateAlpha.
operation;
636 blendState.blend.alphaSrc = BlendState::Blend::One;
637 blendState.blend.alphaDst = BlendState::Blend::Zero;
638 blendState.operation.alpha = BlendState::BlendOperation::Add;
641 return this->blendStates.addResource(std::move(blendState));
647 blendStates.removeResource(handle);
652 return rasterizerStates.addResource(rasterizerState);
657 rasterizerStates.removeResource(handle);
662 return depthStencilStates.addResource(depthStencilState);
667 depthStencilStates.removeResource(handle);
673 std::vector<RenderTargetHandle> renderTargetHandles;
674 for (
auto& renderTarget : renderTargets) {
675 renderTargetHandles.push_back(renderTargets.getHandle(renderTarget));
677 for (
auto& renderTarget : renderTargetHandles) {
678 releaseRenderTarget(renderTarget);
682 std::vector<DepthStencilHandle> depthStencilHandles;
683 for (
auto& depthStencil : depthStencils) {
684 depthStencilHandles.push_back(depthStencils.getHandle(depthStencil));
686 for (
auto& depthStencil : depthStencilHandles) {
687 releaseDepthStencilTarget(depthStencil);
Log implementation class.
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
Encapsulates blend state for the graphics pipeline in a state object.
uint8_t enabled
If blending is enabled.
Blend destinationBlend
Blend option for the blend destination data.
BlendOperation operation
How the two blend values are combined.
Blend sourceBlend
Blend option for the blend source data.
Encapsulates state for depth buffer usage and stencil buffer usage in a state object.
Describes a single depth stencil view and which resources to use from the underlying texture.
TextureHandle texture
Texture handle.
uint8_t levelIndex
Index of the mipmap level to render to.
uint16_t layerIndex
Index of the first layer (if array) to write depth to.
Contains device capabilities.
Settings for graphics device initialization.
int numSamples
Number of samples to use for back buffer MSAA.
TextureFormat colorFormat
Back buffer format.
static const Handle_t InvalidHandle
Represents an invalid handle.
Describes multiview framebuffer layout.
uint8_t samples
Number of multisample samples, 0 and 1 implies no multisampling.
uint8_t baseIndex
Texture array index for first texture slice to render into.
uint8_t count
Number of texture array slices to render into.
Encapsulates state for primitive rasterization in a state object.
Describes the formats and sample count of a render target's attachments.
TextureFormat colorFormats[8]
Formats of the color targets, only the first numColorTargets entries are valid.
TextureFormat depthStencilFormat
Format of the depth stencil target, TextureFormat::Unknown if there is none.
uint8_t samples
Number of samples, 1 implies no multisampling.
uint8_t numColorTargets
Number of valid entries in colorFormats.
Describes a single render target view and which resources to use from the underlying texture.
TextureHandle texture
Texture handle.
BlendStateHandle loadBlendState(const BlendState &blendState) override
Load a blend state object.
virtual RenderTargetHandle createRenderTarget(const RenderTargetViewDescription *renderTargetViews, const size_t numViews) override
Create a render target using the given view descriptions.
RenderTargetLayout getLayout(const RenderTargetHandle renderTargetHandle, const DepthStencilHandle depthStencilHandle) override
Get the view layout for the given render target / depth stencil target pair.
RasterizerStateHandle loadRasterizerState(const RasterizerState &rasterizerState) override
Load a rasterizer state object.
void releaseDepthStencilTarget(DepthStencilHandle depthStencilHandle) override
Release the depth target with the given depthStencilHandle.
DepthStencilStateHandle loadDepthStencilState(const DepthStencilState &depthStencilState) override
Load a depth stencil state object.
void releaseRasterizerState(RasterizerStateHandle handle) override
Release the rasterizer state with the given handle.
void releaseRenderTarget(RenderTargetHandle renderTargetHandle) override
Release the render target with the given renderTargetHandle.
DepthStencilHandle createDepthStencilTarget(const RenderTargetHandle handle) override
Creates a depth/stencil target to back the render target with the given handle.
void releaseBlendState(BlendStateHandle handle) override
Release the blend state with the given handle.
void releaseDepthStencilState(DepthStencilStateHandle handle) override
Release the depth stencil state with the given handle.
void releaseResources() override
Release all allocated render target resources.