Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2022-03-03 23:16:54 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-03-03 23:16:54 +0300
commit58e2ec18ae58918017170c915e7587759f322779 (patch)
tree8f646ae8a0d73d7cec6840e888d9095e3df3d576 /source/blender/draw/engines/eevee/eevee_gbuffer.hh
parentfbf4d8f8b5c60313a6ec15c7bd23e12f34b98878 (diff)
EEVEE: Deferred: Large refactor
This changes drastically the implementation to leverage arbitrary writes in order to reduce complexity, memory usage and increase speed. Since we are no longer dependent on the framebuffer requirement, we can allocate bigger size texture that fits all views and avoid the extra. Transparency, holdout and emissions are no longer deferred and are now composited using dual source blending. The indirect lighting and raytracing is still not functional but will also gets a large refactor on its own
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_gbuffer.hh')
-rw-r--r--source/blender/draw/engines/eevee/eevee_gbuffer.hh227
1 files changed, 91 insertions, 136 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_gbuffer.hh b/source/blender/draw/engines/eevee/eevee_gbuffer.hh
index 237a2ecaf31..dc217590038 100644
--- a/source/blender/draw/engines/eevee/eevee_gbuffer.hh
+++ b/source/blender/draw/engines/eevee/eevee_gbuffer.hh
@@ -33,110 +33,132 @@ enum eClosureBits {
CLOSURE_SSS = 1 << 1,
CLOSURE_REFLECTION = 1 << 2,
CLOSURE_REFRACTION = 1 << 3,
- CLOSURE_VOLUME = 1 << 4,
- CLOSURE_EMISSION = 1 << 5,
- CLOSURE_TRANSPARENCY = 1 << 6,
+ CLOSURE_AMBIENT_OCCLUSION = 1 << 5,
+ /* Non-stencil bits. */
+ CLOSURE_TRANSPARENCY = 1 << 8,
+ CLOSURE_EMISSION = 1 << 9,
+ CLOSURE_HOLDOUT = 1 << 10,
+ CLOSURE_VOLUME = 1 << 11,
};
+ENUM_OPERATORS(eClosureBits, CLOSURE_VOLUME);
+
+static inline eClosureBits extract_closure_mask(const GPUMaterial *gpumat)
+{
+ eClosureBits closure_bits = eClosureBits(0);
+ if (GPU_material_flag_get(gpumat, GPU_MATFLAG_DIFFUSE)) {
+ closure_bits |= CLOSURE_DIFFUSE;
+ }
+ if (GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT)) {
+ closure_bits |= CLOSURE_TRANSPARENCY;
+ }
+ if (GPU_material_flag_get(gpumat, GPU_MATFLAG_EMISSION)) {
+ closure_bits |= CLOSURE_EMISSION;
+ }
+ if (GPU_material_flag_get(gpumat, GPU_MATFLAG_GLOSSY)) {
+ closure_bits |= CLOSURE_REFLECTION;
+ }
+ if (GPU_material_flag_get(gpumat, GPU_MATFLAG_SUBSURFACE)) {
+ closure_bits |= CLOSURE_SSS;
+ }
+ if (GPU_material_flag_get(gpumat, GPU_MATFLAG_REFRACT)) {
+ closure_bits |= CLOSURE_REFRACTION;
+ }
+ if (GPU_material_flag_get(gpumat, GPU_MATFLAG_HOLDOUT)) {
+ closure_bits |= CLOSURE_HOLDOUT;
+ }
+ if (GPU_material_flag_get(gpumat, GPU_MATFLAG_AO)) {
+ closure_bits |= CLOSURE_AMBIENT_OCCLUSION;
+ }
+ return closure_bits;
+}
+
struct GBuffer {
+ Instance &inst;
+
TextureFromPool transmit_color_tx = {"GbufferTransmitColor"};
TextureFromPool transmit_normal_tx = {"GbufferTransmitNormal"};
TextureFromPool transmit_data_tx = {"GbufferTransmitData"};
+
TextureFromPool reflect_color_tx = {"GbufferReflectionColor"};
TextureFromPool reflect_normal_tx = {"GbufferReflectionNormal"};
- TextureFromPool volume_tx = {"GbufferVolume"};
- TextureFromPool emission_tx = {"GbufferEmission"};
- TextureFromPool transparency_tx = {"GbufferTransparency"};
-
- Framebuffer gbuffer_fb = {"Gbuffer"};
- Framebuffer volume_fb = {"VolumeHeterogeneous"};
-
- TextureFromPool holdout_tx = {"HoldoutRadiance"};
- TextureFromPool diffuse_tx = {"DiffuseRadiance"};
- Framebuffer radiance_fb = {"Radiance"};
- Framebuffer radiance_clear_fb = {"RadianceClear"};
-
- Framebuffer holdout_fb = {"Holdout"};
-
- TextureFromPool depth_behind_tx = {"DepthBehind"};
-
- Framebuffer depth_behind_fb = {"DepthCopy"};
+ TextureFromPool radiance_diffuse_tx = {"DiffuseRadiance"};
/** Raytracing. */
TextureFromPool ray_data_tx = {"RayData"};
TextureFromPool ray_radiance_tx = {"RayRadiance"};
TextureFromPool ray_variance_tx = {"RayVariance"};
- Framebuffer ray_data_fb = {"RayData"};
- Framebuffer ray_denoise_fb = {"RayDenoise"};
- /* Owner of this GBuffer. Used to query temp textures. */
- void *owner;
+ TextureFromPool rpass_emission_tx = {"PassEmission"};
+ TextureFromPool rpass_diffuse_light_tx = {"PassDiffuseColor"};
+ TextureFromPool rpass_specular_light_tx = {"PassSpecularColor"};
+ TextureFromPool rpass_volume_light_tx = {"PassVolumeLight"};
+
+ /* Maximum texture size. Since we use imageLoad/Store instead of framebuffer, we only need to
+ * allocate the biggest texture. */
+ int2 extent = int2(-1);
- /* Pointer to the view's buffers. */
- GPUTexture *depth_tx = nullptr;
- GPUTexture *combined_tx = nullptr;
- int layer = -1;
+ GBuffer(Instance &inst_) : inst(inst_){};
- void sync(GPUTexture *depth_tx_, GPUTexture *combined_tx_, void *owner_, int layer_ = -1)
+ void begin_sync()
{
- owner = owner_;
- depth_tx = depth_tx_;
- combined_tx = combined_tx_;
- layer = layer_;
+ extent = int2(-1);
+
transmit_color_tx.sync();
transmit_normal_tx.sync();
transmit_data_tx.sync();
reflect_color_tx.sync();
reflect_normal_tx.sync();
- volume_tx.sync();
- emission_tx.sync();
- transparency_tx.sync();
- holdout_tx.sync();
- diffuse_tx.sync();
- depth_behind_tx.sync();
+ radiance_diffuse_tx.sync();
ray_data_tx.sync();
ray_radiance_tx.sync();
ray_variance_tx.sync();
+ rpass_emission_tx.sync();
+ rpass_diffuse_light_tx.sync();
+ rpass_specular_light_tx.sync();
+ rpass_volume_light_tx.sync();
}
- void prepare(eClosureBits closures_used)
+ void view_sync(int2 view_extent)
{
- int2 extent = {GPU_texture_width(depth_tx), GPU_texture_height(depth_tx)};
+ extent = math::max(extent, view_extent);
+ }
+
+ void acquire(eClosureBits closures_used)
+ {
+ DrawEngineType *owner = (DrawEngineType *)&inst;
- /* TODO Reuse for different config. */
if (closures_used & (CLOSURE_DIFFUSE | CLOSURE_SSS | CLOSURE_REFRACTION)) {
transmit_color_tx.acquire(extent, GPU_R11F_G11F_B10F, owner);
}
+ else {
+ transmit_color_tx.acquire(int2(1), GPU_R11F_G11F_B10F, owner);
+ }
+
if (closures_used & (CLOSURE_SSS | CLOSURE_REFRACTION)) {
transmit_normal_tx.acquire(extent, GPU_RGBA16F, owner);
transmit_data_tx.acquire(extent, GPU_R11F_G11F_B10F, owner);
}
else if (closures_used & CLOSURE_DIFFUSE) {
transmit_normal_tx.acquire(extent, GPU_RG16F, owner);
- }
- if (closures_used & CLOSURE_SSS) {
- diffuse_tx.acquire(extent, GPU_RGBA16F, owner);
+ transmit_data_tx.acquire(int2(1), GPU_R11F_G11F_B10F, owner);
}
if (closures_used & CLOSURE_REFLECTION) {
reflect_color_tx.acquire(extent, GPU_R11F_G11F_B10F, owner);
reflect_normal_tx.acquire(extent, GPU_RGBA16F, owner);
}
-
- if (closures_used & CLOSURE_VOLUME) {
- /* TODO(fclem): This is killing performance.
- * Idea: use interleaved data pattern to fill only a 32bpp buffer. */
- volume_tx.acquire(extent, GPU_RGBA32UI, owner);
+ else {
+ reflect_color_tx.acquire(int2(1), GPU_R11F_G11F_B10F, owner);
+ reflect_normal_tx.acquire(int2(1), GPU_RGBA16F, owner);
}
- if (closures_used & CLOSURE_EMISSION) {
- emission_tx.acquire(extent, GPU_R11F_G11F_B10F, owner);
+ if (closures_used & CLOSURE_SSS) {
+ radiance_diffuse_tx.acquire(extent, GPU_RGBA16F, owner);
}
-
- if (closures_used & CLOSURE_TRANSPARENCY) {
- /* TODO(fclem): Speedup by using Dithered holdout and GPU_RGB10_A2. */
- transparency_tx.acquire(extent, GPU_RGBA16, owner);
+ else {
+ radiance_diffuse_tx.acquire(int2(1), GPU_RGBA16F, owner);
}
if (closures_used & (CLOSURE_DIFFUSE | CLOSURE_REFLECTION | CLOSURE_REFRACTION)) {
@@ -145,97 +167,30 @@ struct GBuffer {
ray_variance_tx.acquire(extent, GPU_R8, owner);
}
- holdout_tx.acquire(extent, GPU_R11F_G11F_B10F, owner);
- depth_behind_tx.acquire(extent, GPU_DEPTH24_STENCIL8, owner);
-
- /* Layer attachement also works with cubemap. */
- gbuffer_fb.ensure(GPU_ATTACHMENT_TEXTURE_LAYER(depth_tx, layer),
- GPU_ATTACHMENT_TEXTURE(transmit_color_tx),
- GPU_ATTACHMENT_TEXTURE(transmit_normal_tx),
- GPU_ATTACHMENT_TEXTURE(transmit_data_tx),
- GPU_ATTACHMENT_TEXTURE(reflect_color_tx),
- GPU_ATTACHMENT_TEXTURE(reflect_normal_tx),
- GPU_ATTACHMENT_TEXTURE(volume_tx),
- GPU_ATTACHMENT_TEXTURE(emission_tx),
- GPU_ATTACHMENT_TEXTURE(transparency_tx));
- }
-
- void bind(void)
- {
- GPU_framebuffer_bind(gbuffer_fb);
- GPU_framebuffer_clear_stencil(gbuffer_fb, 0x0);
- }
-
- void bind_radiance(void)
- {
- /* Layer attachement also works with cubemap. */
- radiance_fb.ensure(GPU_ATTACHMENT_TEXTURE_LAYER(depth_tx, layer),
- GPU_ATTACHMENT_TEXTURE(combined_tx),
- GPU_ATTACHMENT_TEXTURE(diffuse_tx));
- GPU_framebuffer_bind(radiance_fb);
- }
-
- void bind_volume(void)
- {
- /* Layer attachement also works with cubemap. */
- volume_fb.ensure(GPU_ATTACHMENT_TEXTURE_LAYER(depth_tx, layer),
- GPU_ATTACHMENT_TEXTURE(volume_tx),
- GPU_ATTACHMENT_TEXTURE(transparency_tx));
- GPU_framebuffer_bind(volume_fb);
- }
-
- void bind_tracing(void)
- {
- /* Layer attachement also works with cubemap. */
- /* Attach depth_stencil buffer to only trace the surfaces that need it. */
- ray_data_fb.ensure(GPU_ATTACHMENT_TEXTURE_LAYER(depth_tx, layer),
- GPU_ATTACHMENT_TEXTURE(ray_data_tx),
- GPU_ATTACHMENT_TEXTURE(ray_radiance_tx));
- GPU_framebuffer_bind(ray_data_fb);
-
- float color[4] = {0.0f};
- GPU_framebuffer_clear_color(ray_data_fb, color);
- }
-
- void bind_holdout(void)
- {
- holdout_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(holdout_tx));
- GPU_framebuffer_bind(holdout_fb);
- }
-
- void copy_depth_behind(void)
- {
- depth_behind_fb.ensure(GPU_ATTACHMENT_TEXTURE(depth_behind_tx));
- GPU_framebuffer_bind(depth_behind_fb);
-
- GPU_framebuffer_blit(gbuffer_fb, 0, depth_behind_fb, 0, GPU_DEPTH_BIT);
- }
-
- void clear_radiance(void)
- {
- radiance_clear_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(diffuse_tx));
- GPU_framebuffer_bind(radiance_clear_fb);
-
- float color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- GPU_framebuffer_clear_color(radiance_clear_fb, color);
+ if (true) {
+ /* Dummies for everything for now. */
+ rpass_emission_tx.acquire(int2(1), GPU_RGBA16F, owner);
+ rpass_diffuse_light_tx.acquire(int2(1), GPU_RGBA16F, owner);
+ rpass_specular_light_tx.acquire(int2(1), GPU_RGBA16F, owner);
+ rpass_volume_light_tx.acquire(int2(1), GPU_RGBA16F, owner);
+ }
}
- void render_end(void)
+ void release(void)
{
transmit_color_tx.release();
transmit_normal_tx.release();
transmit_data_tx.release();
reflect_color_tx.release();
reflect_normal_tx.release();
- volume_tx.release();
- emission_tx.release();
- transparency_tx.release();
- holdout_tx.release();
- diffuse_tx.release();
- depth_behind_tx.release();
+ radiance_diffuse_tx.release();
ray_data_tx.release();
ray_radiance_tx.release();
ray_variance_tx.release();
+ rpass_emission_tx.release();
+ rpass_diffuse_light_tx.release();
+ rpass_specular_light_tx.release();
+ rpass_volume_light_tx.release();
}
};