Blender V5.0
gpu_context_private.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2016 by Mike Erwin. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#pragma once
12
13#include "BKE_global.hh"
14
15#include "GPU_batch.hh"
16#include "GPU_context.hh"
17#include "GPU_texture_pool.hh"
18
19#include "gpu_debug_private.hh"
22#include "gpu_shader_private.hh"
23#include "gpu_state_private.hh"
24
25#include <pthread.h>
26
27struct GPUMatrixState;
28
29namespace blender::gpu {
30
31class Context {
32 public:
34 Shader *shader = nullptr;
38 Immediate *imm = nullptr;
39
51
53 bool debug_is_capturing = false;
54
55 /* GPUContext counter used to assign a unique ID to each GPUContext.
56 * NOTE(Metal): This is required by the Metal Backend, as a bug exists in the global OS shader
57 * cache wherein compilation of identical source from two distinct threads can result in an
58 * invalid cache collision, result in a broken shader object. Appending the unique context ID
59 * onto compiled sources ensures the source hashes are different. */
60 static int context_counter;
61 int context_id = 0;
62
63 /* Used as a stack. Each render_begin/end pair will push pop from the stack. */
65
67 VertBuf *dummy_vbo = nullptr;
69 Batch *procedural_points_batch = nullptr;
70 Batch *procedural_lines_batch = nullptr;
73
76
80
81 protected:
83 pthread_t thread_;
87
88 public:
89 Context();
90 virtual ~Context();
91
92 static Context *get();
93
94 virtual void activate() = 0;
95 virtual void deactivate() = 0;
96 virtual void begin_frame() = 0;
97 virtual void end_frame() = 0;
98
99 /* Will push all pending commands to the GPU. */
100 virtual void flush() = 0;
101 /* Will wait until the GPU has finished executing all command. */
102 virtual void finish() = 0;
103
104 virtual void memory_statistics_get(int *r_total_mem, int *r_free_mem) = 0;
105
106 virtual void debug_group_begin(const char * /*name*/, int /*index*/) {};
107 virtual void debug_group_end() {};
108
109 /* Returns true if capture successfully started. */
110 virtual bool debug_capture_begin(const char *title) = 0;
111 virtual void debug_capture_end() = 0;
112 virtual void *debug_capture_scope_create(const char *name) = 0;
113 virtual bool debug_capture_scope_begin(void *scope) = 0;
114 virtual void debug_capture_scope_end(void *scope) = 0;
115
116 /* Consider all buffers slot empty after these call for error checking.
117 * But doesn't really free them. */
118 virtual void debug_unbind_all_ubo() = 0;
119 virtual void debug_unbind_all_ssbo() = 0;
120
121 bool is_active_on_thread();
122
128
129 /* When using `--debug-gpu`, assert that the shader fragments write to all the writable
130 * attachments of the bound frame-buffer. */
132 {
133 if (!(G.debug & G_DEBUG_GPU)) {
134 return;
135 }
136
137 if (!(state_manager->state.write_mask & GPUWriteMask::GPU_WRITE_COLOR)) {
138 return;
139 }
140
141 uint16_t fragment_output_bits = sh->fragment_output_bits;
142 uint16_t fb_attachments_bits = active_fb->get_color_attachments_bitset();
143
144 if ((fb_attachments_bits & ~fragment_output_bits) != 0) {
145 std::string msg;
146 msg = msg + "Shader (" + sh->name_get() + ") does not write to all frame-buffer (" +
147 active_fb->name_get() + ") color attachments";
148 BLI_assert_msg(false, msg.c_str());
149 std::cerr << msg << std::endl;
150 }
151 }
152
153 protected:
158 void free_resources();
159};
160
161/* Syntactic sugar. */
162static inline GPUContext *wrap(Context *ctx)
163{
164 return reinterpret_cast<GPUContext *>(ctx);
165}
166static inline Context *unwrap(GPUContext *ctx)
167{
168 return reinterpret_cast<Context *>(ctx);
169}
170static inline const Context *unwrap(const GPUContext *ctx)
171{
172 return reinterpret_cast<const Context *>(ctx);
173}
174
175} // namespace blender::gpu
@ G_DEBUG_GPU
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
@ GPU_WRITE_COLOR
Definition GPU_state.hh:24
virtual void debug_unbind_all_ssbo()=0
Vector< StorageBuf * > printf_buf
virtual void debug_group_begin(const char *, int)
static Context * get()
virtual void debug_capture_scope_end(void *scope)=0
virtual void memory_statistics_get(int *r_total_mem, int *r_free_mem)=0
virtual void finish()=0
virtual void debug_unbind_all_ubo()=0
GPUMatrixState * matrix_state
virtual bool debug_capture_scope_begin(void *scope)=0
virtual void * debug_capture_scope_create(const char *name)=0
Batch * procedural_triangles_batch_get()
VertBuf * dummy_vbo_get()
void assert_framebuffer_shader_compatibility(Shader *sh)
virtual void debug_capture_end()=0
Batch * procedural_triangle_strips_batch_get()
virtual bool debug_capture_begin(const char *title)=0
virtual void activate()=0
virtual void end_frame()=0
Batch * procedural_lines_batch_get()
virtual void begin_frame()=0
Batch * procedural_points_batch_get()
virtual void deactivate()=0
virtual void flush()=0
StringRefNull name_get() const
#define G(x, y, z)
static Context * unwrap(GPUContext *ctx)
static GPUContext * wrap(Context *ctx)
Vector< StringRef > DebugStack
const char * name