Add class to manage resources for a RenderTarget.

PiperOrigin-RevId: 888016283
Change-Id: I4959e63e95fad4f75a7a04fabf0879f0b9238f9f
This commit is contained in:
Haroon Qureshi
2026-03-23 04:17:15 -07:00
committed by Copybara-Service
parent 5664b9e89e
commit babcfd6575
7 changed files with 199 additions and 87 deletions
+2
View File
@@ -48,6 +48,8 @@ target_sources(${MUJOCO_FILAMENT_TARGET_NAME}
filament/model_util.h
filament/object_manager.cc
filament/object_manager.h
filament/render_target_util.cc
filament/render_target_util.h
filament/renderables.cc
filament/renderables.h
filament/scene_view.cc
@@ -43,7 +43,7 @@
#include "experimental/filament/filament/object_manager.h"
#include "experimental/filament/filament/model_util.h"
#include "experimental/filament/filament/scene_view.h"
#include "experimental/filament/filament/texture_util.h"
#include "experimental/filament/filament/render_target_util.h"
#include "experimental/filament/render_context_filament.h"
namespace mujoco {
@@ -219,43 +219,18 @@ void FilamentContext::SetFrameBuffer(int framebuffer) {
}
void FilamentContext::PrepareRenderTargets(int width, int height) {
for (int i = 0; i < kNumRenderTargetTextureTypes; ++i) {
target_textures_[i] = CreateRenderTargetTexture(
engine_, width, height, static_cast<RenderTargetTextureType>(i));
}
color_target_ = std::make_unique<RenderTargetAndTextures>(
engine_, kRenderTargetColor, kRenderTargetDepth);
color_target_->Prepare(width, height);
// Render target for color pass.
filament::RenderTarget::Builder color_target_builder;
color_target_builder.texture(filament::RenderTarget::AttachmentPoint::COLOR0,
target_textures_[kRenderTargetColor]);
color_target_builder.texture(filament::RenderTarget::AttachmentPoint::DEPTH,
target_textures_[kRenderTargetDepth]);
color_target_ = color_target_builder.build(*engine_);
// Render target for depth pass.
filament::RenderTarget::Builder depth_target_builder;
depth_target_builder.texture(filament::RenderTarget::AttachmentPoint::COLOR0,
target_textures_[kRenderTargetDepthColor]);
depth_target_builder.texture(filament::RenderTarget::AttachmentPoint::DEPTH,
target_textures_[kRenderTargetDepth]);
depth_target_ = depth_target_builder.build(*engine_);
depth_target_ = std::make_unique<RenderTargetAndTextures>(
engine_, kRenderTargetDepthColor, kRenderTargetDepth);
depth_target_->Prepare(width, height);
}
void FilamentContext::DestroyRenderTargets() {
if (depth_target_) {
engine_->destroy(depth_target_);
depth_target_ = nullptr;
}
if (color_target_) {
engine_->destroy(color_target_);
color_target_ = nullptr;
}
for (int i = 0; i < kNumRenderTargetTextureTypes; ++i) {
if (target_textures_[i]) {
engine_->destroy(target_textures_[i]);
target_textures_[i] = nullptr;
}
}
depth_target_.reset();
color_target_.reset();
}
static void ReadColorPixels(filament::Renderer* renderer,
@@ -295,15 +270,17 @@ void FilamentContext::ReadPixels(mjrRect viewport, unsigned char* rgb,
if (rgb) {
if (renderer_->beginFrame(offscreen_swap_chain_)) {
scene_view_->Render(renderer_, last_render_mode_, color_target_);
scene_view_->Render(renderer_, last_render_mode_,
color_target_->GetRenderTarget());
// Render the GUI to the texture as well if requested.
if (gui_view_ && gui_swap_chain_target_ == kOffscreenSwapChain) {
gui_view_->Render(renderer_, color_target_);
gui_view_->Render(renderer_, color_target_->GetRenderTarget());
}
const size_t num_bytes = viewport.width * viewport.height * 3;
ReadColorPixels(renderer_, color_target_, viewport, rgb, num_bytes);
ReadColorPixels(renderer_, color_target_->GetRenderTarget(), viewport,
rgb, num_bytes);
renderer_->endFrame();
}
@@ -312,10 +289,11 @@ void FilamentContext::ReadPixels(mjrRect viewport, unsigned char* rgb,
if (depth) {
if (renderer_->beginFrame(offscreen_swap_chain_)) {
scene_view_->Render(renderer_, SceneView::DrawMode::kDepth,
depth_target_);
depth_target_->GetRenderTarget());
const size_t num_bytes = viewport.width * viewport.height * sizeof(float);
ReadDepthPixels(renderer_, depth_target_, viewport, depth, num_bytes);
ReadDepthPixels(renderer_, depth_target_->GetRenderTarget(), viewport,
depth, num_bytes);
renderer_->endFrame();
}
@@ -26,7 +26,7 @@
#include "experimental/filament/filament/gui_view.h"
#include "experimental/filament/filament/object_manager.h"
#include "experimental/filament/filament/scene_view.h"
#include "experimental/filament/filament/texture_util.h"
#include "experimental/filament/filament/render_target_util.h"
#include "experimental/filament/render_context_filament.h"
namespace mujoco {
@@ -77,15 +77,11 @@ class FilamentContext {
filament::SwapChain* window_swap_chain_ = nullptr;
filament::SwapChain* offscreen_swap_chain_ = nullptr;
filament::Renderer* renderer_ = nullptr;
filament::RenderTarget* color_target_ = nullptr;
filament::RenderTarget* depth_target_ = nullptr;
filament::Texture* target_textures_[kNumRenderTargetTextureTypes] = {
nullptr, nullptr, nullptr};
SceneView::DrawMode last_render_mode_ = SceneView::DrawMode::kNormal;
SwapChainType scene_swap_chain_target_ = kWindowSwapChain;
SwapChainType gui_swap_chain_target_ = kWindowSwapChain;
std::unique_ptr<RenderTargetAndTextures> color_target_;
std::unique_ptr<RenderTargetAndTextures> depth_target_;
std::unique_ptr<ObjectManager> object_manager_;
std::unique_ptr<SceneView> scene_view_;
std::unique_ptr<GuiView> gui_view_;
@@ -0,0 +1,103 @@
// Copyright 2026 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "experimental/filament/filament/render_target_util.h"
#include <filament/Engine.h>
#include <filament/RenderTarget.h>
#include <filament/Texture.h>
#include <mujoco/mujoco.h>
namespace mujoco {
static filament::Texture* CreateRenderTargetTexture(
filament::Engine* engine, int width, int height,
RenderTargetTextureType type) {
filament::Texture::Builder builder;
builder.width(width);
builder.height(height);
switch (type) {
case kRenderTargetColor:
builder.usage(filament::Texture::Usage::COLOR_ATTACHMENT |
filament::Texture::Usage::BLIT_SRC);
builder.format(filament::Texture::InternalFormat::RGB8);
break;
case kRenderTargetDepth:
builder.usage(filament::Texture::Usage::DEPTH_ATTACHMENT |
filament::Texture::Usage::SAMPLEABLE);
builder.format(filament::Texture::InternalFormat::DEPTH32F);
break;
case kRenderTargetDepthColor:
builder.usage(filament::Texture::Usage::COLOR_ATTACHMENT |
filament::Texture::Usage::BLIT_SRC);
builder.format(filament::Texture::InternalFormat::R32F);
break;
case kRenderTargetReflectionColor:
builder.usage(filament::Texture::Usage::COLOR_ATTACHMENT |
filament::Texture::Usage::BLIT_SRC |
filament::Texture::Usage::SAMPLEABLE);
builder.format(filament::Texture::InternalFormat::RGBA8);
break;
default:
mju_error("Unknown type: %d", static_cast<int>(type));
}
return builder.build(*engine);
}
RenderTargetAndTextures::RenderTargetAndTextures(filament::Engine* engine,
RenderTargetTextureType color,
RenderTargetTextureType depth)
: engine_(engine), color_type_(color), depth_type_(depth) {}
RenderTargetAndTextures::~RenderTargetAndTextures() noexcept {
Destroy();
}
void RenderTargetAndTextures::Prepare(int width, int height) {
if (width == width_ && height == height_) {
return;
}
Destroy();
width_ = width;
height_ = height;
color_texture_ =
CreateRenderTargetTexture(engine_, width, height, color_type_);
depth_texture_ =
CreateRenderTargetTexture(engine_, width, height, depth_type_);
filament::RenderTarget::Builder builder;
builder.texture(filament::RenderTarget::AttachmentPoint::COLOR,
color_texture_);
builder.texture(filament::RenderTarget::AttachmentPoint::DEPTH,
depth_texture_);
render_target_ = builder.build(*engine_);
}
void RenderTargetAndTextures::Destroy() {
if (render_target_) {
engine_->destroy(render_target_);
render_target_ = nullptr;
}
if (color_texture_) {
engine_->destroy(color_texture_);
color_texture_ = nullptr;
}
if (depth_texture_) {
engine_->destroy(depth_texture_);
depth_texture_ = nullptr;
}
}
} // namespace mujoco
@@ -0,0 +1,74 @@
// Copyright 2026 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_RENDER_TARGET_UTIL_H_
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_RENDER_TARGET_UTIL_H_
#include <filament/Engine.h>
#include <filament/Texture.h>
namespace mujoco {
// The different types of textures we can create for a render target.
enum RenderTargetTextureType {
kRenderTargetNone,
kRenderTargetColor,
kRenderTargetDepth,
kRenderTargetDepthColor,
kRenderTargetReflectionColor,
kNumRenderTargetTextureTypes,
};
// Manages a filament RenderTarget and the textures which are bound to it.
class RenderTargetAndTextures {
public:
// Defines the types of textures to create for the color and depth
// attachments.
RenderTargetAndTextures(filament::Engine* engine,
RenderTargetTextureType color,
RenderTargetTextureType depth);
~RenderTargetAndTextures() noexcept;
RenderTargetAndTextures(const RenderTargetAndTextures&) = delete;
RenderTargetAndTextures& operator=(const RenderTargetAndTextures&) = delete;
// Creates the textures and render target if the width of height differ from
// the last time the render target was prepared.
void Prepare(int width, int height);
// Returns the color texture.
filament::Texture* GetColorTexture() const { return color_texture_; }
// Returns the depth texture.
filament::Texture* GetDepthTexture() const { return depth_texture_; }
// Returns the render target.
filament::RenderTarget* GetRenderTarget() const { return render_target_; }
private:
void Destroy();
filament::Engine* engine_ = nullptr;
filament::Texture* color_texture_ = nullptr;
filament::Texture* depth_texture_ = nullptr;
filament::RenderTarget* render_target_ = nullptr;
RenderTargetTextureType color_type_ = kRenderTargetNone;
RenderTargetTextureType depth_type_ = kRenderTargetNone;
int width_ = 0;
int height_ = 0;
};
} // namespace mujoco
#endif // MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_RENDER_TARGET_UTIL_H_
@@ -178,33 +178,4 @@ filament::Texture* CreateKtxTexture(
const bool is_srgb = false;
return ktxreader::Ktx1Reader::createTexture(engine, bundle, is_srgb);
}
filament::Texture* CreateRenderTargetTexture(filament::Engine* engine,
int width, int height,
RenderTargetTextureType type) {
filament::Texture::Builder builder;
builder.width(width);
builder.height(height);
switch (type) {
case kRenderTargetColor:
builder.usage(filament::Texture::Usage::COLOR_ATTACHMENT |
filament::Texture::Usage::BLIT_SRC);
builder.format(filament::Texture::InternalFormat::RGB8);
break;
case kRenderTargetDepth:
builder.usage(filament::Texture::Usage::DEPTH_ATTACHMENT |
filament::Texture::Usage::SAMPLEABLE);
builder.format(filament::Texture::InternalFormat::DEPTH32F);
break;
case kRenderTargetDepthColor:
builder.usage(filament::Texture::Usage::COLOR_ATTACHMENT |
filament::Texture::Usage::BLIT_SRC);
builder.format(filament::Texture::InternalFormat::R32F);
break;
default:
mju_error("Unknown type: %d", static_cast<int>(type));
}
return builder.build(*engine);
}
} // namespace mujoco
@@ -39,18 +39,6 @@ filament::Texture* CreateKtxTexture(
filament::Engine* engine, const uint8_t* data, int size,
filament::math::float3* spherical_harmonics_out);
enum RenderTargetTextureType {
kRenderTargetColor,
kRenderTargetDepth,
kRenderTargetDepthColor,
kNumRenderTargetTextureTypes,
};
// Creates a filament RenderTargetTexture for the given target type.
filament::Texture* CreateRenderTargetTexture(filament::Engine* engine,
int width, int height,
RenderTargetTextureType type);
} // namespace mujoco
#endif // MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_TEXTURE_UTIL_H_