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; | |
| }; | |
| } | |