Spaces:
Build error
Build error
/* | |
* SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | |
* SPDX-License-Identifier: Apache-2.0 | |
* | |
* 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. | |
*/ | |
/** @file render_buffer.h | |
* @author Thomas Müller & Alex Evans, NVIDIA | |
*/ | |
namespace ngp { | |
typedef unsigned int GLenum; | |
typedef int GLint; | |
typedef unsigned int GLuint; | |
class SurfaceProvider { | |
public: | |
virtual cudaSurfaceObject_t surface() = 0; | |
virtual cudaArray_t array() = 0; | |
virtual ivec2 resolution() const = 0; | |
virtual void resize(const ivec2&, int n_channels = 4) = 0; | |
}; | |
class CudaSurface2D : public SurfaceProvider { | |
public: | |
CudaSurface2D() { | |
m_array = nullptr; | |
m_surface = 0; | |
} | |
~CudaSurface2D() { | |
free(); | |
} | |
void free(); | |
void resize(const ivec2& size, int n_channels) override; | |
cudaSurfaceObject_t surface() override { | |
return m_surface; | |
} | |
cudaArray_t array() override { | |
return m_array; | |
} | |
ivec2 resolution() const override { | |
return m_size; | |
} | |
private: | |
ivec2 m_size = ivec2(0); | |
int m_n_channels = 0; | |
cudaArray_t m_array; | |
cudaSurfaceObject_t m_surface; | |
}; | |
class GLTexture : public SurfaceProvider { | |
public: | |
GLTexture() = default; | |
GLTexture(const std::string& texture_name) | |
: m_texture_name(texture_name), m_texture_id(0) | |
{ } | |
GLTexture(const GLTexture& other) = delete; | |
GLTexture(GLTexture&& other) | |
: m_texture_name(move(other.m_texture_name)), m_texture_id(other.m_texture_id) { | |
other.m_texture_id = 0; | |
} | |
GLTexture& operator=(GLTexture&& other) { | |
m_texture_name = move(other.m_texture_name); | |
std::swap(m_texture_id, other.m_texture_id); | |
return *this; | |
} | |
~GLTexture(); | |
GLuint texture(); | |
cudaSurfaceObject_t surface() override; | |
cudaArray_t array() override; | |
void blit_from_cuda_mapping(); | |
const std::string& texture_name() const { return m_texture_name; } | |
bool is_8bit() { return m_is_8bit; } | |
void load(const fs::path& path); | |
void load(const float* data, ivec2 new_size, int n_channels); | |
void load(const uint8_t* data, ivec2 new_size, int n_channels); | |
void resize(const ivec2& new_size, int n_channels, bool is_8bit); | |
void resize(const ivec2& new_size, int n_channels) override { | |
resize(new_size, n_channels, false); | |
} | |
ivec2 resolution() const override { | |
return m_size; | |
} | |
private: | |
class CUDAMapping { | |
public: | |
CUDAMapping(GLuint texture_id, const ivec2& size, int n_channels); | |
~CUDAMapping(); | |
cudaSurfaceObject_t surface() const { return m_cuda_surface ? m_cuda_surface->surface() : m_surface; } | |
cudaArray_t array() const { return m_cuda_surface ? m_cuda_surface->array() : m_mapped_array; } | |
bool is_interop() const { return !m_cuda_surface; } | |
const float* data_cpu(); | |
private: | |
cudaGraphicsResource_t m_graphics_resource = {}; | |
cudaArray_t m_mapped_array = {}; | |
cudaSurfaceObject_t m_surface = {}; | |
ivec2 m_size; | |
int m_n_channels; | |
std::vector<float> m_data_cpu; | |
std::unique_ptr<CudaSurface2D> m_cuda_surface; | |
}; | |
std::string m_texture_name; | |
GLuint m_texture_id = 0; | |
ivec2 m_size = ivec2(0); | |
int m_n_channels = 0; | |
GLint m_internal_format; | |
GLenum m_format; | |
bool m_is_8bit = false; | |
std::unique_ptr<CUDAMapping> m_cuda_mapping; | |
}; | |
bool check_shader(uint32_t handle, const char* desc, bool program); | |
uint32_t compile_shader(bool pixel, const char* code); | |
struct CudaRenderBufferView { | |
vec4* frame_buffer = nullptr; | |
float* depth_buffer = nullptr; | |
ivec2 resolution = ivec2(0); | |
uint32_t spp = 0; | |
std::shared_ptr<Buffer2D<uint8_t>> hidden_area_mask = nullptr; | |
void clear(cudaStream_t stream) const; | |
}; | |
class CudaRenderBuffer { | |
public: | |
CudaRenderBuffer(const std::shared_ptr<SurfaceProvider>& rgba, const std::shared_ptr<SurfaceProvider>& depth = nullptr) : m_rgba_target{rgba}, m_depth_target{depth} {} | |
CudaRenderBuffer(const CudaRenderBuffer& other) = delete; | |
CudaRenderBuffer& operator=(const CudaRenderBuffer& other) = delete; | |
CudaRenderBuffer(CudaRenderBuffer&& other) = default; | |
CudaRenderBuffer& operator=(CudaRenderBuffer&& other) = default; | |
cudaSurfaceObject_t surface() { | |
return m_rgba_target->surface(); | |
} | |
ivec2 in_resolution() const { | |
return m_in_resolution; | |
} | |
ivec2 out_resolution() const { | |
return m_rgba_target->resolution(); | |
} | |
void resize(const ivec2& res); | |
void reset_accumulation() { | |
m_spp = 0; | |
} | |
uint32_t spp() const { | |
return m_spp; | |
} | |
void set_spp(uint32_t value) { | |
m_spp = value; | |
} | |
vec4* frame_buffer() const { | |
return m_frame_buffer.data(); | |
} | |
float* depth_buffer() const { | |
return m_depth_buffer.data(); | |
} | |
vec4* accumulate_buffer() const { | |
return m_accumulate_buffer.data(); | |
} | |
CudaRenderBufferView view() const { | |
return { | |
frame_buffer(), | |
depth_buffer(), | |
in_resolution(), | |
spp(), | |
hidden_area_mask(), | |
}; | |
} | |
void clear_frame(cudaStream_t stream); | |
void accumulate(float exposure, cudaStream_t stream); | |
void tonemap(float exposure, const vec4& background_color, EColorSpace output_color_space, float znear, float zfar, bool snap_to_pixel_centers, cudaStream_t stream); | |
void overlay_image( | |
float alpha, | |
const vec3& exposure, | |
const vec4& background_color, | |
EColorSpace output_color_space, | |
const void* __restrict__ image, | |
EImageDataType image_data_type, | |
const ivec2& resolution, | |
int fov_axis, | |
float zoom, | |
const vec2& screen_center, | |
cudaStream_t stream | |
); | |
void overlay_depth( | |
float alpha, | |
const float* __restrict__ depth, | |
float depth_scale, | |
const ivec2& resolution, | |
int fov_axis, | |
float zoom, | |
const vec2& screen_center, | |
cudaStream_t stream | |
); | |
void overlay_false_color(ivec2 training_resolution, bool to_srgb, int fov_axis, cudaStream_t stream, const float *error_map, ivec2 error_map_resolution, const float *average, float brightness, bool viridis); | |
SurfaceProvider& surface_provider() { | |
return *m_rgba_target; | |
} | |
void set_color_space(EColorSpace color_space) { | |
if (color_space != m_color_space) { | |
m_color_space = color_space; | |
reset_accumulation(); | |
} | |
} | |
void set_tonemap_curve(ETonemapCurve tonemap_curve) { | |
if (tonemap_curve != m_tonemap_curve) { | |
m_tonemap_curve = tonemap_curve; | |
reset_accumulation(); | |
} | |
} | |
void enable_dlss(IDlssProvider& dlss_provider, const ivec2& max_out_res); | |
void disable_dlss(); | |
void set_dlss_sharpening(float value) { | |
m_dlss_sharpening = value; | |
} | |
const std::unique_ptr<IDlss>& dlss() const { | |
return m_dlss; | |
} | |
void set_hidden_area_mask(const std::shared_ptr<Buffer2D<uint8_t>>& hidden_area_mask) { | |
m_hidden_area_mask = hidden_area_mask; | |
} | |
const std::shared_ptr<Buffer2D<uint8_t>>& hidden_area_mask() const { | |
return m_hidden_area_mask; | |
} | |
private: | |
uint32_t m_spp = 0; | |
EColorSpace m_color_space = EColorSpace::Linear; | |
ETonemapCurve m_tonemap_curve = ETonemapCurve::Identity; | |
std::unique_ptr<IDlss> m_dlss; | |
float m_dlss_sharpening = 0.0f; | |
ivec2 m_in_resolution = ivec2(0); | |
GPUMemory<vec4> m_frame_buffer; | |
GPUMemory<float> m_depth_buffer; | |
GPUMemory<vec4> m_accumulate_buffer; | |
std::shared_ptr<Buffer2D<uint8_t>> m_hidden_area_mask = nullptr; | |
std::shared_ptr<SurfaceProvider> m_rgba_target; | |
std::shared_ptr<SurfaceProvider> m_depth_target; | |
}; | |
} | |