DRW : Add AA to non meshes objects.

You can change the amount of samples in the user preferences. You do not need to restart blender to see the effect in the new viewport.

This adds another Multisample Framebuffer and textures (so even more memory required).

It works by blitting the default_fb to the multisample_fb each time the renderer need to render one or more "wire" pass.
It it then blit back to the default_fb so that the rest of pipeline is working as expected.

We COULD lower the GPU memory / bandwidth usage to render everything to the same multisample fbo and change the logic depending on if MSAA is enabled or not, but I think it's a bit too much work for now.
This commit is contained in:
2017-09-23 20:47:42 +02:00
parent 709315a0d7
commit 00955d8d7a
8 changed files with 104 additions and 5 deletions

View File

@@ -48,11 +48,14 @@ struct GPUOffScreen;
/* Buffer and textures used by the viewport by default */
typedef struct DefaultFramebufferList {
struct GPUFrameBuffer *default_fb;
struct GPUFrameBuffer *multisample_fb;
} DefaultFramebufferList;
typedef struct DefaultTextureList {
struct GPUTexture *color;
struct GPUTexture *depth;
struct GPUTexture *multisample_color;
struct GPUTexture *multisample_depth;
} DefaultTextureList;
void DRW_engines_register(void);

View File

@@ -90,6 +90,29 @@ typedef char DRWViewportEmptyList;
DRW_VIEWPORT_LIST_SIZE(*(((ty *)NULL)->stl)) \
}
/* Use of multisample framebuffers. */
#define MULTISAMPLE_SYNC_ENABLE(dfbl) { \
if (dfbl->multisample_fb != NULL) { \
DRW_stats_query_start("Multisample Blit"); \
DRW_framebuffer_blit(dfbl->default_fb, dfbl->multisample_fb, false); \
DRW_framebuffer_blit(dfbl->default_fb, dfbl->multisample_fb, true); \
DRW_framebuffer_bind(dfbl->multisample_fb); \
DRW_stats_query_end(); \
} \
}
#define MULTISAMPLE_SYNC_DISABLE(dfbl) { \
if (dfbl->multisample_fb != NULL) { \
DRW_stats_query_start("Multisample Resolve"); \
DRW_framebuffer_blit(dfbl->multisample_fb, dfbl->default_fb, false); \
DRW_framebuffer_blit(dfbl->multisample_fb, dfbl->default_fb, true); \
DRW_framebuffer_bind(dfbl->default_fb); \
DRW_stats_query_end(); \
} \
}
typedef struct DrawEngineDataSize {
int fbl_len;
int txl_len;
@@ -119,11 +142,14 @@ typedef struct DrawEngineType {
/* Buffer and textures used by the viewport by default */
typedef struct DefaultFramebufferList {
struct GPUFrameBuffer *default_fb;
struct GPUFrameBuffer *multisample_fb;
} DefaultFramebufferList;
typedef struct DefaultTextureList {
struct GPUTexture *color;
struct GPUTexture *depth;
struct GPUTexture *multisample_color;
struct GPUTexture *multisample_depth;
} DefaultTextureList;
#endif

View File

@@ -120,11 +120,16 @@ static void EDIT_ARMATURE_cache_populate(void *vedata, Object *ob)
static void EDIT_ARMATURE_draw_scene(void *vedata)
{
EDIT_ARMATURE_PassList *psl = ((EDIT_ARMATURE_Data *)vedata)->psl;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
MULTISAMPLE_SYNC_ENABLE(dfbl)
DRW_draw_pass(psl->bone_envelope);
DRW_draw_pass(psl->bone_solid);
DRW_draw_pass(psl->bone_wire);
DRW_draw_pass(psl->relationship);
MULTISAMPLE_SYNC_DISABLE(dfbl)
}
#if 0

View File

@@ -264,7 +264,9 @@ static void EDIT_CURVE_draw_scene(void *vedata)
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
UNUSED_VARS(fbl, dfbl, dtxl);
UNUSED_VARS(fbl, dtxl);
MULTISAMPLE_SYNC_ENABLE(dfbl)
/* Show / hide entire passes, swap framebuffers ... whatever you fancy */
/*
@@ -280,6 +282,8 @@ static void EDIT_CURVE_draw_scene(void *vedata)
DRW_draw_pass(psl->overlay_edge_pass);
DRW_draw_pass(psl->overlay_vert_pass);
MULTISAMPLE_SYNC_DISABLE(dfbl)
/* If you changed framebuffer, double check you rebind
* the default one with its textures attached before finishing */
}

View File

@@ -227,7 +227,9 @@ static void EDIT_LATTICE_draw_scene(void *vedata)
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
UNUSED_VARS(fbl, dfbl, dtxl);
UNUSED_VARS(fbl, dtxl);
MULTISAMPLE_SYNC_ENABLE(dfbl)
/* Show / hide entire passes, swap framebuffers ... whatever you fancy */
/*
@@ -242,6 +244,8 @@ static void EDIT_LATTICE_draw_scene(void *vedata)
DRW_draw_pass(psl->wire_pass);
DRW_draw_pass(psl->vert_pass);
MULTISAMPLE_SYNC_DISABLE(dfbl)
/* If you changed framebuffer, double check you rebind
* the default one with its textures attached before finishing */
}

View File

@@ -1826,15 +1826,20 @@ static void OBJECT_draw_scene(void *vedata)
DRW_stats_group_end();
}
MULTISAMPLE_SYNC_ENABLE(dfbl)
/* This needs to be drawn after the oultine */
// DRW_draw_pass(psl->bone_envelope); /* Never drawn in Object mode currently. */
DRW_draw_pass(psl->bone_wire);
DRW_draw_pass(psl->bone_solid);
DRW_draw_pass(psl->non_meshes);
DRW_draw_pass(psl->ob_center);
DRW_draw_pass(psl->particle);
DRW_draw_pass(psl->reference_image);
MULTISAMPLE_SYNC_DISABLE(dfbl)
DRW_draw_pass(psl->ob_center);
if (!DRW_state_is_select()) {
if (e_data.draw_grid) {
DRW_draw_pass(psl->grid);

View File

@@ -38,6 +38,7 @@
#include "BLI_string.h"
#include "DNA_vec_types.h"
#include "DNA_userdef_types.h"
#include "BKE_global.h"
@@ -71,6 +72,7 @@ struct GPUViewport {
/* debug */
GPUTexture *debug_depth;
int size[2];
int samples;
ListBase data; /* ViewportEngineData wrapped in LinkData */
unsigned int data_hash; /* If hash mismatch we free all ViewportEngineData in this viewport */
@@ -312,7 +314,7 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
int rect_h = BLI_rcti_size_y(rect) + 1;
if (dfbl->default_fb) {
if (rect_w != viewport->size[0] || rect_h != viewport->size[1]) {
if (rect_w != viewport->size[0] || rect_h != viewport->size[1] || U.ogl_multisamples != viewport->samples) {
gpu_viewport_buffers_free(
(FramebufferList *)viewport->fbl, default_fbl_len,
(TextureList *)viewport->txl, default_txl_len);
@@ -329,6 +331,56 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
gpu_viewport_texture_pool_clear_users(viewport);
/* Multisample Buffer */
if (U.ogl_multisamples > 0) {
if (!dfbl->default_fb) {
bool ok = true;
viewport->samples = U.ogl_multisamples;
dfbl->multisample_fb = GPU_framebuffer_create();
if (!dfbl->multisample_fb) {
ok = false;
goto cleanup_multisample;
}
/* Color */
dtxl->multisample_color = GPU_texture_create_2D_multisample(rect_w, rect_h, NULL, U.ogl_multisamples, NULL);
if (!dtxl->multisample_color) {
ok = false;
goto cleanup_multisample;
}
if (!GPU_framebuffer_texture_attach(dfbl->multisample_fb, dtxl->multisample_color, 0, 0)) {
ok = false;
goto cleanup_multisample;
}
/* Depth */
dtxl->multisample_depth = GPU_texture_create_depth_multisample(rect_w, rect_h, U.ogl_multisamples, NULL);
if (!dtxl->multisample_depth) {
ok = false;
goto cleanup_multisample;
}
if (!GPU_framebuffer_texture_attach(dfbl->multisample_fb, dtxl->multisample_depth, 0, 0)) {
ok = false;
goto cleanup_multisample;
}
else if (!GPU_framebuffer_check_valid(dfbl->multisample_fb, NULL)) {
ok = false;
goto cleanup_multisample;
}
cleanup_multisample:
if (!ok) {
GPU_viewport_free(viewport);
MEM_freeN(viewport);
return;
}
}
}
if (!dfbl->default_fb) {
bool ok = true;
viewport->size[0] = rect_w;
@@ -341,7 +393,6 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
}
/* Color */
/* No multi samples for now */
dtxl->color = GPU_texture_create_2D(rect_w, rect_h, NULL, NULL);
if (!dtxl->color) {
ok = false;

View File

@@ -4178,6 +4178,7 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_enum_items(prop, multi_sample_levels);
RNA_def_property_ui_text(prop, "MultiSample",
"Enable OpenGL multi-sampling, only for systems that support it, requires restart");
RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
prop = RNA_def_property(srna, "use_region_overlap", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_REGION_OVERLAP);