DRW: Remove legacy DRWView

No functional change expected.
This commit is contained in:
Clément Foucault
2024-12-05 17:53:02 +01:00
parent 490cc5d011
commit d8ca7dc743
7 changed files with 1 additions and 534 deletions

View File

@@ -184,7 +184,7 @@ void Instance::view_update()
/** \name Sync
*
* Sync will gather data from the scene that can change over a time step (i.e: motion steps).
* IMPORTANT: xxx.sync() functions area responsible for creating DRW resources (i.e: DRWView) as
* IMPORTANT: xxx.sync() functions area responsible for creating DRW resources as
* well as querying temp texture pool. All DRWPasses should be ready by the end end_sync().
* \{ */

View File

@@ -82,7 +82,6 @@ typedef struct DRWPass DRWPass;
typedef struct DRWShaderLibrary DRWShaderLibrary;
typedef struct DRWShadingGroup DRWShadingGroup;
typedef struct DRWUniform DRWUniform;
typedef struct DRWView DRWView;
/* TODO: Put it somewhere else? */
struct BoundSphere {
@@ -294,35 +293,6 @@ enum eDRWAttrType {
DRW_ATTR_FLOAT,
};
/* Views. */
/**
* Create a view with culling.
*/
DRWView *DRW_view_create(const float viewmat[4][4],
const float winmat[4][4],
const float (*culling_viewmat)[4],
const float (*culling_winmat)[4]);
/**
* Create a view with culling done by another view.
*/
DRWView *DRW_view_create_sub(const DRWView *parent_view,
const float viewmat[4][4],
const float winmat[4][4]);
/**
* Update matrices of a view created with #DRW_view_create.
*/
void DRW_view_update(DRWView *view,
const float viewmat[4][4],
const float winmat[4][4],
const float (*culling_viewmat)[4],
const float (*culling_winmat)[4]);
/**
* Update matrices of a view created with #DRW_view_create_sub.
*/
void DRW_view_update_sub(DRWView *view, const float viewmat[4][4], const float winmat[4][4]);
/* Viewport. */
const float *DRW_viewport_size_get();

View File

@@ -10,7 +10,6 @@
#include "draw_common_shader_shared.hh"
struct DRWView;
struct FluidModifierData;
struct GPUMaterial;
struct GPUTexture;

View File

@@ -376,7 +376,6 @@ DRWData *DRW_viewport_data_create()
drw_data->callbuffers = BLI_memblock_create(sizeof(DRWCallBuffer));
drw_data->shgroups = BLI_memblock_create(sizeof(DRWShadingGroup));
drw_data->uniforms = BLI_memblock_create(sizeof(DRWUniformChunk));
drw_data->views = BLI_memblock_create(sizeof(DRWView));
drw_data->images = BLI_memblock_create(sizeof(GPUTexture *));
drw_data->obattrs_ubo_pool = DRW_uniform_attrs_pool_new();
drw_data->vlattrs_name_cache = BLI_ghash_new(
@@ -446,7 +445,6 @@ static void drw_viewport_data_reset(DRWData *drw_data)
BLI_memblock_clear(drw_data->shgroups, nullptr);
BLI_memblock_clear(drw_data->uniforms, nullptr);
BLI_memblock_clear(drw_data->passes, nullptr);
BLI_memblock_clear(drw_data->views, nullptr);
BLI_memblock_clear(drw_data->images, nullptr);
DRW_uniform_attrs_pool_clear_all(drw_data->obattrs_ubo_pool);
DRW_instance_data_list_free_unused(drw_data->idatalist);
@@ -467,7 +465,6 @@ void DRW_viewport_data_free(DRWData *drw_data)
BLI_memblock_destroy(drw_data->cullstates, nullptr);
BLI_memblock_destroy(drw_data->shgroups, nullptr);
BLI_memblock_destroy(drw_data->uniforms, nullptr);
BLI_memblock_destroy(drw_data->views, nullptr);
BLI_memblock_destroy(drw_data->passes, nullptr);
BLI_memblock_destroy(drw_data->images, nullptr);
DRW_uniform_attrs_pool_free(drw_data->obattrs_ubo_pool);
@@ -588,11 +585,7 @@ static void drw_manager_init(DRWManager *dst, GPUViewport *viewport, const int s
if (rv3d != nullptr) {
dst->pixsize = rv3d->pixsize;
dst->view_default = DRW_view_create(rv3d->viewmat, rv3d->winmat, nullptr, nullptr);
blender::draw::View::default_set(float4x4(rv3d->viewmat), float4x4(rv3d->winmat));
dst->view_active = dst->view_default;
dst->view_previous = nullptr;
}
else if (region) {
View2D *v2d = &region->v2d;
@@ -608,16 +601,10 @@ static void drw_manager_init(DRWManager *dst, GPUViewport *viewport, const int s
winmat[3][0] = -1.0f;
winmat[3][1] = -1.0f;
dst->view_default = DRW_view_create(viewmat, winmat, nullptr, nullptr);
blender::draw::View::default_set(float4x4(viewmat), float4x4(winmat));
dst->view_active = dst->view_default;
dst->view_previous = nullptr;
}
else {
dst->pixsize = 1.0f;
dst->view_default = nullptr;
dst->view_active = nullptr;
dst->view_previous = nullptr;
}
/* fclem: Is this still needed ? */

View File

@@ -450,42 +450,6 @@ struct DRWPass {
char name[MAX_PASS_NAME];
};
#define MAX_CULLED_VIEWS 32
struct DRWView {
/**
* These float4x4 (as well as the ViewMatrices) have alignment requirements in C++
* (see math::MatBase) that isn't fulfilled in C. So they need to be manually aligned.
* Since the DRWView are allocated using BLI_memblock, the chunks are given to be 16 bytes
* aligned (equal to the alignment of float4x4). We then assert that the DRWView itself is 16
* bytes aligned.
*/
float4x4 persmat;
float4x4 persinv;
ViewMatrices storage;
/** Parent view if this is a sub view. nullptr otherwise. */
DRWView *parent;
float4 clip_planes[6];
/** Number of active clip planes. */
int clip_planes_len;
/** Does culling result needs to be updated. */
bool is_dirty;
/** Does facing needs to be reversed? */
bool is_inverted;
/** Culling */
uint32_t culling_mask;
BoundBox frustum_corners;
BoundSphere frustum_bsphere;
float frustum_planes[6][4];
/** Custom visibility function. */
void *user_data;
};
/* Needed to assert that alignment is the same in C++ and C. */
BLI_STATIC_ASSERT_ALIGN(DRWView, 16);
/** \} */
/* -------------------------------------------------------------------- */
@@ -551,7 +515,6 @@ struct DRWData {
BLI_memblock *cullstates;
BLI_memblock *shgroups;
BLI_memblock *uniforms;
BLI_memblock *views;
BLI_memblock *passes;
BLI_memblock *images;
GPUUniformBuf **matrices_ubo;
@@ -662,9 +625,6 @@ struct DRWManager {
/** True, when drawing is in progress, see #DRW_draw_in_progress. */
bool in_progress;
DRWView *view_default;
DRWView *view_active;
DRWView *view_previous;
uint primary_view_num;
#ifdef USE_GPU_SELECT

View File

@@ -59,331 +59,3 @@ eDRWCommandType command_type_get(const uint64_t *command_type_bits, int index)
{
return eDRWCommandType((command_type_bits[index / 16] >> ((index % 16) * 4)) & 0xF);
}
/* -------------------------------------------------------------------- */
/** \name View (DRW_view)
* \{ */
/* Extract the 8 corners from a Projection Matrix.
* Although less accurate, this solution can be simplified as follows:
* BKE_boundbox_init_from_minmax(&bbox, (const float[3]){-1.0f, -1.0f, -1.0f}, (const
* float[3]){1.0f, 1.0f, 1.0f}); for (int i = 0; i < 8; i++) {mul_project_m4_v3(projinv,
* bbox.vec[i]);}
*/
static void draw_frustum_boundbox_calc(const float (*viewinv)[4],
const float (*projmat)[4],
BoundBox *r_bbox)
{
float left, right, bottom, top, near, far;
bool is_persp = projmat[3][3] == 0.0f;
#if 0 /* Equivalent to this but it has accuracy problems. */
BKE_boundbox_init_from_minmax(
&bbox, blender::float3{-1.0f, -1.0f, -1.0f}, blender::float3{1.0f, 1.0f, 1.0f});
for (int i = 0; i < 8; i++) {
mul_project_m4_v3(projinv, bbox.vec[i]);
}
#endif
projmat_dimensions(projmat, &left, &right, &bottom, &top, &near, &far);
r_bbox->vec[0][2] = r_bbox->vec[3][2] = r_bbox->vec[7][2] = r_bbox->vec[4][2] = -near;
r_bbox->vec[0][0] = r_bbox->vec[3][0] = left;
r_bbox->vec[4][0] = r_bbox->vec[7][0] = right;
r_bbox->vec[0][1] = r_bbox->vec[4][1] = bottom;
r_bbox->vec[7][1] = r_bbox->vec[3][1] = top;
/* Get the coordinates of the far plane. */
if (is_persp) {
float sca_far = far / near;
left *= sca_far;
right *= sca_far;
bottom *= sca_far;
top *= sca_far;
}
r_bbox->vec[1][2] = r_bbox->vec[2][2] = r_bbox->vec[6][2] = r_bbox->vec[5][2] = -far;
r_bbox->vec[1][0] = r_bbox->vec[2][0] = left;
r_bbox->vec[6][0] = r_bbox->vec[5][0] = right;
r_bbox->vec[1][1] = r_bbox->vec[5][1] = bottom;
r_bbox->vec[2][1] = r_bbox->vec[6][1] = top;
/* Transform into world space. */
for (int i = 0; i < 8; i++) {
mul_m4_v3(viewinv, r_bbox->vec[i]);
}
}
static void draw_frustum_culling_planes_calc(const float (*persmat)[4], float (*frustum_planes)[4])
{
planes_from_projmat(persmat,
frustum_planes[0],
frustum_planes[5],
frustum_planes[1],
frustum_planes[3],
frustum_planes[4],
frustum_planes[2]);
/* Normalize. */
for (int p = 0; p < 6; p++) {
frustum_planes[p][3] /= normalize_v3(frustum_planes[p]);
}
}
static void draw_frustum_bound_sphere_calc(const BoundBox *bbox,
const float (*viewinv)[4],
const float (*projmat)[4],
const float (*projinv)[4],
BoundSphere *bsphere)
{
/* Extract Bounding Sphere */
if (projmat[3][3] != 0.0f) {
/* Orthographic */
/* The most extreme points on the near and far plane. (normalized device coords). */
const float *nearpoint = bbox->vec[0];
const float *farpoint = bbox->vec[6];
/* just use median point */
mid_v3_v3v3(bsphere->center, farpoint, nearpoint);
bsphere->radius = len_v3v3(bsphere->center, farpoint);
}
else if (projmat[2][0] == 0.0f && projmat[2][1] == 0.0f) {
/* Perspective with symmetrical frustum. */
/* We obtain the center and radius of the circumscribed circle of the
* isosceles trapezoid composed by the diagonals of the near and far clipping plane */
/* center of each clipping plane */
float mid_min[3], mid_max[3];
mid_v3_v3v3(mid_min, bbox->vec[3], bbox->vec[4]);
mid_v3_v3v3(mid_max, bbox->vec[2], bbox->vec[5]);
/* square length of the diagonals of each clipping plane */
float a_sq = len_squared_v3v3(bbox->vec[3], bbox->vec[4]);
float b_sq = len_squared_v3v3(bbox->vec[2], bbox->vec[5]);
/* distance squared between clipping planes */
float h_sq = len_squared_v3v3(mid_min, mid_max);
float fac = (4 * h_sq + b_sq - a_sq) / (8 * h_sq);
/* The goal is to get the smallest sphere,
* not the sphere that passes through each corner */
CLAMP(fac, 0.0f, 1.0f);
interp_v3_v3v3(bsphere->center, mid_min, mid_max, fac);
/* distance from the center to one of the points of the far plane (1, 2, 5, 6) */
bsphere->radius = len_v3v3(bsphere->center, bbox->vec[1]);
}
else {
/* Perspective with asymmetrical frustum. */
/* We put the sphere center on the line that goes from origin
* to the center of the far clipping plane. */
/* Detect which of the corner of the far clipping plane is the farthest to the origin */
float nfar[4]; /* most extreme far point in NDC space */
float farxy[2]; /* far-point projection onto the near plane */
float farpoint[3] = {0.0f}; /* most extreme far point in camera coordinate */
float nearpoint[3]; /* most extreme near point in camera coordinate */
float farcenter[3] = {0.0f}; /* center of far clipping plane in camera coordinate */
float F = -1.0f, N; /* square distance of far and near point to origin */
float f, n; /* distance of far and near point to z axis. f is always > 0 but n can be < 0 */
float e, s; /* far and near clipping distance (<0) */
float c; /* slope of center line = distance of far clipping center
* to z axis / far clipping distance. */
float z; /* projection of sphere center on z axis (<0) */
/* Find farthest corner and center of far clip plane. */
float corner[3] = {1.0f, 1.0f, 1.0f}; /* in clip space */
for (int i = 0; i < 4; i++) {
float point[3];
mul_v3_project_m4_v3(point, projinv, corner);
float len = len_squared_v3(point);
if (len > F) {
copy_v3_v3(nfar, corner);
copy_v3_v3(farpoint, point);
F = len;
}
add_v3_v3(farcenter, point);
/* rotate by 90 degree to walk through the 4 points of the far clip plane */
float tmp = corner[0];
corner[0] = -corner[1];
corner[1] = tmp;
}
/* the far center is the average of the far clipping points */
mul_v3_fl(farcenter, 0.25f);
/* the extreme near point is the opposite point on the near clipping plane */
copy_v3_fl3(nfar, -nfar[0], -nfar[1], -1.0f);
mul_v3_project_m4_v3(nearpoint, projinv, nfar);
/* this is a frustum projection */
N = len_squared_v3(nearpoint);
e = farpoint[2];
s = nearpoint[2];
/* distance to view Z axis */
f = len_v2(farpoint);
/* get corresponding point on the near plane */
mul_v2_v2fl(farxy, farpoint, s / e);
/* this formula preserve the sign of n */
sub_v2_v2(nearpoint, farxy);
n = f * s / e - len_v2(nearpoint);
c = len_v2(farcenter) / e;
/* the big formula, it simplifies to (F-N)/(2(e-s)) for the symmetric case */
z = (F - N) / (2.0f * (e - s + c * (f - n)));
bsphere->center[0] = farcenter[0] * z / e;
bsphere->center[1] = farcenter[1] * z / e;
bsphere->center[2] = z;
/* For XR, the view matrix may contain a scale factor. Then, transforming only the center
* into world space after calculating the radius will result in incorrect behavior. */
mul_m4_v3(viewinv, bsphere->center); /* Transform to world space. */
mul_m4_v3(viewinv, farpoint);
bsphere->radius = len_v3v3(bsphere->center, farpoint);
}
}
static void draw_view_matrix_state_update(DRWView *view,
const float viewmat[4][4],
const float winmat[4][4])
{
ViewMatrices *storage = &view->storage;
copy_m4_m4(storage->viewmat.ptr(), viewmat);
invert_m4_m4(storage->viewinv.ptr(), storage->viewmat.ptr());
copy_m4_m4(storage->winmat.ptr(), winmat);
invert_m4_m4(storage->wininv.ptr(), storage->winmat.ptr());
mul_m4_m4m4(view->persmat.ptr(), winmat, viewmat);
invert_m4_m4(view->persinv.ptr(), view->persmat.ptr());
}
DRWView *DRW_view_create(const float viewmat[4][4],
const float winmat[4][4],
const float (*culling_viewmat)[4],
const float (*culling_winmat)[4])
{
DRWView *view = static_cast<DRWView *>(BLI_memblock_alloc(DST.vmempool->views));
if (DST.primary_view_num < MAX_CULLED_VIEWS) {
view->culling_mask = 1u << DST.primary_view_num++;
}
else {
BLI_assert(0);
view->culling_mask = 0u;
}
view->clip_planes_len = 0;
view->parent = nullptr;
DRW_view_update(view, viewmat, winmat, culling_viewmat, culling_winmat);
return view;
}
DRWView *DRW_view_create_sub(const DRWView *parent_view,
const float viewmat[4][4],
const float winmat[4][4])
{
/* Search original parent. */
const DRWView *ori_view = parent_view;
while (ori_view->parent != nullptr) {
ori_view = ori_view->parent;
}
DRWView *view = static_cast<DRWView *>(BLI_memblock_alloc(DST.vmempool->views));
/* Perform copy. */
*view = *ori_view;
view->parent = (DRWView *)ori_view;
DRW_view_update_sub(view, viewmat, winmat);
return view;
}
/* DRWView Update:
* This is meant to be done on existing views when rendering in a loop and there is no
* need to allocate more DRWViews. */
void DRW_view_update_sub(DRWView *view, const float viewmat[4][4], const float winmat[4][4])
{
BLI_assert(view->parent != nullptr);
view->is_dirty = true;
view->is_inverted = (is_negative_m4(viewmat) == is_negative_m4(winmat));
draw_view_matrix_state_update(view, viewmat, winmat);
}
void DRW_view_update(DRWView *view,
const float viewmat[4][4],
const float winmat[4][4],
const float (*culling_viewmat)[4],
const float (*culling_winmat)[4])
{
/* DO NOT UPDATE THE DEFAULT VIEW.
* Create sub-views instead, or a copy. */
BLI_assert(view != DST.view_default);
BLI_assert(view->parent == nullptr);
view->is_dirty = true;
view->is_inverted = (is_negative_m4(viewmat) == is_negative_m4(winmat));
draw_view_matrix_state_update(view, viewmat, winmat);
/* Prepare frustum culling. */
#ifdef DRW_DEBUG_CULLING
static float mv[MAX_CULLED_VIEWS][4][4], mw[MAX_CULLED_VIEWS][4][4];
/* Select view here. */
if (view->culling_mask != 0) {
uint index = bitscan_forward_uint(view->culling_mask);
if (G.debug_value == 0) {
copy_m4_m4(mv[index], culling_viewmat ? culling_viewmat : viewmat);
copy_m4_m4(mw[index], culling_winmat ? culling_winmat : winmat);
}
else {
culling_winmat = mw[index];
culling_viewmat = mv[index];
}
}
#endif
float wininv[4][4];
if (culling_winmat) {
winmat = culling_winmat;
invert_m4_m4(wininv, winmat);
}
else {
copy_m4_m4(wininv, view->storage.wininv.ptr());
}
float viewinv[4][4];
if (culling_viewmat) {
viewmat = culling_viewmat;
invert_m4_m4(viewinv, viewmat);
}
else {
copy_m4_m4(viewinv, view->storage.viewinv.ptr());
}
draw_frustum_boundbox_calc(viewinv, winmat, &view->frustum_corners);
draw_frustum_culling_planes_calc(view->persmat.ptr(), view->frustum_planes);
draw_frustum_bound_sphere_calc(
&view->frustum_corners, viewinv, winmat, wininv, &view->frustum_bsphere);
#ifdef DRW_DEBUG_CULLING
if (G.debug_value != 0) {
DRW_debug_sphere(
view->frustum_bsphere.center, view->frustum_bsphere.radius, blender::float4{1, 1, 0, 1});
DRW_debug_bbox(&view->frustum_corners, blender::float4{1, 1, 0, 1});
}
#endif
}
/** \} */

View File

@@ -211,14 +211,6 @@ void drw_state_set(DRWState state)
GPU_shadow_offset(false);
}
/* TODO: this should be part of shader state. */
if (state & DRW_STATE_CLIP_PLANES) {
GPU_clip_distances(DST.view_active->clip_planes_len);
}
else {
GPU_clip_distances(0);
}
if (state & DRW_STATE_IN_FRONT_SELECT) {
/* XXX `GPU_depth_range` is not a perfect solution
* since very distant geometries can still be occluded.
@@ -332,90 +324,6 @@ void DRW_state_reset()
/** \} */
/* -------------------------------------------------------------------- */
/** \name Culling (DRW_culling)
* \{ */
static bool draw_call_is_culled(const DRWResourceHandle *handle, DRWView *view)
{
DRWCullingState *culling = static_cast<DRWCullingState *>(
DRW_memblock_elem_from_handle(DST.vmempool->cullstates, handle));
return (culling->mask & view->culling_mask) != 0;
}
/* Return True if the given BoundSphere intersect the current view frustum */
static bool draw_culling_sphere_test(const BoundSphere *frustum_bsphere,
const float (*frustum_planes)[4],
const BoundSphere *bsphere)
{
/* Bypass test if radius is negative. */
if (bsphere->radius < 0.0f) {
return true;
}
/* Do a rough test first: Sphere VS Sphere intersect. */
float center_dist_sq = len_squared_v3v3(bsphere->center, frustum_bsphere->center);
float radius_sum = bsphere->radius + frustum_bsphere->radius;
if (center_dist_sq > square_f(radius_sum)) {
return false;
}
/* TODO: we could test against the inscribed sphere of the frustum to early out positively. */
/* Test against the 6 frustum planes. */
/* TODO: order planes with sides first then far then near clip. Should be better culling
* heuristic when sculpting. */
for (int p = 0; p < 6; p++) {
float dist = plane_point_side_v3(frustum_planes[p], bsphere->center);
if (dist < -bsphere->radius) {
return false;
}
}
return true;
}
static void draw_compute_culling(DRWView *view)
{
view = view->parent ? view->parent : view;
/* TODO(fclem): multi-thread this. */
/* TODO(fclem): compute all dirty views at once. */
if (!view->is_dirty) {
return;
}
BLI_memblock_iter iter;
BLI_memblock_iternew(DST.vmempool->cullstates, &iter);
DRWCullingState *cull;
while ((cull = static_cast<DRWCullingState *>(BLI_memblock_iterstep(&iter)))) {
if (cull->bsphere.radius < 0.0) {
cull->mask = 0;
}
else {
bool culled = !draw_culling_sphere_test(
&view->frustum_bsphere, view->frustum_planes, &cull->bsphere);
#ifdef DRW_DEBUG_CULLING
if (G.debug_value != 0) {
if (culled) {
DRW_debug_sphere(
cull->bsphere.center, cull->bsphere.radius, blender::float4{1, 0, 0, 1});
}
else {
DRW_debug_sphere(
cull->bsphere.center, cull->bsphere.radius, blender::float4{0, 1, 0, 1});
}
}
#endif
SET_FLAG_FROM_TEST(cull->mask, culled, view->culling_mask);
}
}
view->is_dirty = false;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Draw (DRW_draw)
* \{ */
@@ -716,7 +624,6 @@ static void draw_call_resource_bind(DRWCommandsState *state, const DRWResourceHa
bool neg_scale = DRW_handle_negative_scale_get(handle);
if (neg_scale != state->neg_scale) {
state->neg_scale = neg_scale;
GPU_front_facing(neg_scale != DST.view_active->is_inverted);
}
int chunk = DRW_handle_chunk_get(handle);
@@ -870,7 +777,6 @@ static void draw_call_batching_finish(DRWShadingGroup *shgroup, DRWCommandsState
/* Reset state */
if (state->neg_scale) {
GPU_front_facing(DST.view_active->is_inverted);
}
if (state->obmats_loc != -1) {
GPU_uniformbuf_unbind(DST.vmempool->matrices_ubo[state->resource_chunk]);
@@ -949,9 +855,6 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
case DRW_CMD_DRAW:
case DRW_CMD_DRAW_INDIRECT:
case DRW_CMD_DRAW_INSTANCE:
if (draw_call_is_culled(&cmd->instance.handle, DST.view_active)) {
continue;
}
break;
default:
break;
@@ -1071,15 +974,6 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
}
}
static void drw_update_view()
{
/* TODO(fclem): update a big UBO and only bind ranges here. */
GPU_uniformbuf_update(G_draw.view_ubo, &DST.view_active->storage);
GPU_uniformbuf_update(G_draw.clipping_ubo, &DST.view_active->clip_planes);
draw_compute_culling(DST.view_active);
}
static void drw_draw_pass_ex(DRWPass *pass,
DRWShadingGroup *start_group,
DRWShadingGroup *end_group)
@@ -1098,12 +992,6 @@ static void drw_draw_pass_ex(DRWPass *pass,
BLI_assert_msg(DST.buffer_finish_called,
"DRW_render_instance_buffer_finish had not been called before drawing");
if (DST.view_previous != DST.view_active || DST.view_active->is_dirty) {
drw_update_view();
DST.view_active->is_dirty = false;
DST.view_previous = DST.view_active;
}
/* GPU_framebuffer_clear calls can change the state outside the DRW module.
* Force reset the affected states to avoid problems later. */
drw_state_set(DST.state | DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR);
@@ -1111,10 +999,6 @@ static void drw_draw_pass_ex(DRWPass *pass,
drw_state_set(pass->state);
drw_state_validate();
if (DST.view_active->is_inverted) {
GPU_front_facing(true);
}
DRW_stats_query_start(pass->name);
for (DRWShadingGroup *shgroup = start_group; shgroup; shgroup = shgroup->next) {
@@ -1148,11 +1032,6 @@ static void drw_draw_pass_ex(DRWPass *pass,
drw_state_set((DST.state & ~DRW_STATE_RASTERIZER_ENABLED) | DRW_STATE_DEFAULT);
}
/* Reset default. */
if (DST.view_active->is_inverted) {
GPU_front_facing(false);
}
DRW_stats_query_end();
}