2018-02-28 01:16:23 +01:00
|
|
|
/*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
2019-01-23 11:29:18 +11:00
|
|
|
* Copyright 2016, Blender Foundation.
|
2018-02-28 01:16:23 +01:00
|
|
|
*/
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup draw
|
2018-02-28 01:16:23 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* Private functions / structs of the draw manager */
|
|
|
|
|
|
|
|
#ifndef __DRAW_MANAGER_H__
|
|
|
|
#define __DRAW_MANAGER_H__
|
|
|
|
|
|
|
|
#include "DRW_engine.h"
|
|
|
|
#include "DRW_render.h"
|
|
|
|
|
2019-05-31 01:45:41 +02:00
|
|
|
#include "BLI_assert.h"
|
2018-02-28 01:16:23 +01:00
|
|
|
#include "BLI_linklist.h"
|
2019-05-31 01:45:41 +02:00
|
|
|
#include "BLI_memblock.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_threads.h"
|
2018-02-28 01:16:23 +01:00
|
|
|
|
|
|
|
#include "GPU_batch.h"
|
2018-07-17 21:11:23 +02:00
|
|
|
#include "GPU_context.h"
|
2018-02-28 01:16:23 +01:00
|
|
|
#include "GPU_framebuffer.h"
|
|
|
|
#include "GPU_shader.h"
|
|
|
|
#include "GPU_uniformbuffer.h"
|
|
|
|
#include "GPU_viewport.h"
|
|
|
|
|
|
|
|
#include "draw_instance_data.h"
|
|
|
|
|
|
|
|
/* Use draw manager to call GPU_select, see: DRW_draw_select_loop */
|
|
|
|
#define USE_GPU_SELECT
|
|
|
|
|
2019-05-31 01:45:41 +02:00
|
|
|
/* Use drawcall batching using instanced rendering. */
|
|
|
|
#define USE_BATCHING 1
|
|
|
|
|
2019-05-22 00:32:12 +02:00
|
|
|
// #define DRW_DEBUG_CULLING
|
2019-01-17 18:33:08 +01:00
|
|
|
#define DRW_DEBUG_USE_UNIFORM_NAME 0
|
|
|
|
#define DRW_UNIFORM_BUFFER_NAME 64
|
|
|
|
|
2018-02-28 01:16:23 +01:00
|
|
|
/* ------------ Profiling --------------- */
|
|
|
|
|
|
|
|
#define USE_PROFILE
|
|
|
|
|
|
|
|
#ifdef USE_PROFILE
|
|
|
|
# include "PIL_time.h"
|
|
|
|
|
2018-03-17 04:47:26 +01:00
|
|
|
# define PROFILE_TIMER_FALLOFF 0.04
|
2018-02-28 01:16:23 +01:00
|
|
|
|
2019-04-20 11:28:21 +02:00
|
|
|
# define PROFILE_START(time_start) \
|
|
|
|
double time_start = PIL_check_seconds_timer(); \
|
|
|
|
((void)0)
|
2018-02-28 01:16:23 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
# define PROFILE_END_ACCUM(time_accum, time_start) \
|
|
|
|
{ \
|
|
|
|
time_accum += (PIL_check_seconds_timer() - time_start) * 1e3; \
|
|
|
|
} \
|
|
|
|
((void)0)
|
2018-02-28 01:16:23 +01:00
|
|
|
|
|
|
|
/* exp average */
|
2019-04-17 06:17:24 +02:00
|
|
|
# define PROFILE_END_UPDATE(time_update, time_start) \
|
|
|
|
{ \
|
|
|
|
double _time_delta = (PIL_check_seconds_timer() - time_start) * 1e3; \
|
|
|
|
time_update = (time_update * (1.0 - PROFILE_TIMER_FALLOFF)) + \
|
|
|
|
(_time_delta * PROFILE_TIMER_FALLOFF); \
|
|
|
|
} \
|
|
|
|
((void)0)
|
2018-02-28 01:16:23 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
#else /* USE_PROFILE */
|
2018-02-28 01:16:23 +01:00
|
|
|
|
|
|
|
# define PROFILE_START(time_start) ((void)0)
|
|
|
|
# define PROFILE_END_ACCUM(time_accum, time_start) ((void)0)
|
|
|
|
# define PROFILE_END_UPDATE(time_update, time_start) ((void)0)
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
#endif /* USE_PROFILE */
|
2018-02-28 01:16:23 +01:00
|
|
|
|
|
|
|
/* ------------ Data Structure --------------- */
|
|
|
|
/**
|
|
|
|
* Data structure containing all drawcalls organized by passes and materials.
|
|
|
|
* DRWPass > DRWShadingGroup > DRWCall > DRWCallState
|
|
|
|
* > DRWUniform
|
2019-03-19 15:17:46 +11:00
|
|
|
*/
|
2018-02-28 01:16:23 +01:00
|
|
|
|
2019-05-20 18:01:42 +02:00
|
|
|
typedef struct DRWCullingState {
|
|
|
|
uint32_t mask;
|
|
|
|
/* Culling: Using Bounding Sphere for now for faster culling.
|
|
|
|
* Not ideal for planes. Could be extended. */
|
|
|
|
BoundSphere bsphere;
|
|
|
|
/* Grrr only used by EEVEE. */
|
2019-04-17 06:17:24 +02:00
|
|
|
void *user_data;
|
2019-05-20 18:01:42 +02:00
|
|
|
} DRWCullingState;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-31 01:45:41 +02:00
|
|
|
/* Minimum max UBO size is 64KiB. We take the largest
|
|
|
|
* UBO struct and alloc the max number.
|
|
|
|
* ((1 << 16) / sizeof(DRWObjectMatrix)) = 512
|
|
|
|
* Keep in sync with common_view_lib.glsl */
|
|
|
|
#define DRW_RESOURCE_CHUNK_LEN 512
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Identifier used to sort similar drawcalls together.
|
|
|
|
* Also used to reference elements inside memory blocks.
|
|
|
|
*
|
|
|
|
* From MSB to LSB
|
|
|
|
* 1 bit for negative scale.
|
|
|
|
* 22 bits for chunk id.
|
|
|
|
* 9 bits for resource id inside the chunk. (can go up to 511)
|
|
|
|
* |-|----------------------|---------|
|
|
|
|
*
|
2019-09-19 13:18:52 +10:00
|
|
|
* Use manual bit-shift and mask instead of bit-fields to avoid
|
|
|
|
* compiler dependent behavior that would mess the ordering of
|
2019-05-31 01:45:41 +02:00
|
|
|
* the members thus changing the sorting order.
|
|
|
|
*/
|
|
|
|
typedef uint32_t DRWResourceHandle;
|
|
|
|
|
|
|
|
BLI_INLINE uint32_t DRW_handle_negative_scale_get(const DRWResourceHandle *handle)
|
|
|
|
{
|
|
|
|
return (*handle & 0x80000000) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
BLI_INLINE uint32_t DRW_handle_chunk_get(const DRWResourceHandle *handle)
|
|
|
|
{
|
|
|
|
return (*handle & 0x7FFFFFFF) >> 9;
|
|
|
|
}
|
|
|
|
|
|
|
|
BLI_INLINE uint32_t DRW_handle_id_get(const DRWResourceHandle *handle)
|
|
|
|
{
|
|
|
|
return (*handle & 0x000001FF);
|
|
|
|
}
|
|
|
|
|
|
|
|
BLI_INLINE void DRW_handle_increment(DRWResourceHandle *handle)
|
|
|
|
{
|
|
|
|
*handle += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
BLI_INLINE void DRW_handle_negative_scale_enable(DRWResourceHandle *handle)
|
|
|
|
{
|
|
|
|
*handle |= 0x80000000;
|
|
|
|
}
|
|
|
|
|
|
|
|
BLI_INLINE void *DRW_memblock_elem_from_handle(struct BLI_memblock *memblock,
|
|
|
|
const DRWResourceHandle *handle)
|
|
|
|
{
|
|
|
|
int elem = DRW_handle_id_get(handle);
|
|
|
|
int chunk = DRW_handle_chunk_get(handle);
|
|
|
|
return BLI_memblock_elem_get(memblock, chunk, elem);
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct DRWObjectMatrix {
|
2019-04-17 06:17:24 +02:00
|
|
|
float model[4][4];
|
|
|
|
float modelinverse[4][4];
|
2019-05-31 01:45:41 +02:00
|
|
|
} DRWObjectMatrix;
|
|
|
|
|
|
|
|
typedef struct DRWObjectInfos {
|
|
|
|
float orcotexfac[2][4];
|
2019-09-13 23:02:45 +02:00
|
|
|
float ob_color[4];
|
2019-05-31 01:45:41 +02:00
|
|
|
float ob_index;
|
|
|
|
float pad; /* UNUSED*/
|
|
|
|
float ob_random;
|
2019-12-02 01:40:58 +01:00
|
|
|
float ob_flag; /* sign is negative scaling, */
|
2019-05-31 01:45:41 +02:00
|
|
|
} DRWObjectInfos;
|
|
|
|
|
|
|
|
BLI_STATIC_ASSERT_ALIGN(DRWObjectMatrix, 16)
|
|
|
|
BLI_STATIC_ASSERT_ALIGN(DRWObjectInfos, 16)
|
2018-02-28 01:16:23 +01:00
|
|
|
|
2019-05-31 01:45:41 +02:00
|
|
|
typedef enum {
|
|
|
|
/* Draw Commands */
|
|
|
|
DRW_CMD_DRAW = 0, /* Only sortable type. Must be 0. */
|
|
|
|
DRW_CMD_DRAW_RANGE = 1,
|
|
|
|
DRW_CMD_DRAW_INSTANCE = 2,
|
2020-03-09 16:27:24 +01:00
|
|
|
DRW_CMD_DRAW_INSTANCE_RANGE = 3,
|
|
|
|
DRW_CMD_DRAW_PROCEDURAL = 4,
|
2019-05-31 01:45:41 +02:00
|
|
|
/* Other Commands */
|
|
|
|
DRW_CMD_CLEAR = 12,
|
|
|
|
DRW_CMD_DRWSTATE = 13,
|
|
|
|
DRW_CMD_STENCIL = 14,
|
|
|
|
DRW_CMD_SELECTID = 15,
|
|
|
|
/* Needs to fit in 4bits */
|
|
|
|
} eDRWCommandType;
|
|
|
|
|
|
|
|
#define DRW_MAX_DRAW_CMD_TYPE DRW_CMD_DRAW_PROCEDURAL
|
|
|
|
|
|
|
|
typedef struct DRWCommandDraw {
|
|
|
|
GPUBatch *batch;
|
|
|
|
DRWResourceHandle handle;
|
|
|
|
} DRWCommandDraw;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-31 01:45:41 +02:00
|
|
|
/* Assume DRWResourceHandle to be 0. */
|
|
|
|
typedef struct DRWCommandDrawRange {
|
2019-05-11 19:16:46 +02:00
|
|
|
GPUBatch *batch;
|
2020-03-09 16:27:24 +01:00
|
|
|
DRWResourceHandle handle;
|
2019-05-11 19:16:46 +02:00
|
|
|
uint vert_first;
|
|
|
|
uint vert_count;
|
2019-05-31 01:45:41 +02:00
|
|
|
} DRWCommandDrawRange;
|
|
|
|
|
|
|
|
typedef struct DRWCommandDrawInstance {
|
|
|
|
GPUBatch *batch;
|
|
|
|
DRWResourceHandle handle;
|
2019-05-11 19:16:46 +02:00
|
|
|
uint inst_count;
|
2020-04-03 16:59:34 +11:00
|
|
|
uint use_attrs; /* bool */
|
2019-05-31 01:45:41 +02:00
|
|
|
} DRWCommandDrawInstance;
|
2019-05-31 01:45:41 +02:00
|
|
|
|
2020-03-09 16:27:24 +01:00
|
|
|
typedef struct DRWCommandDrawInstanceRange {
|
|
|
|
GPUBatch *batch;
|
|
|
|
DRWResourceHandle handle;
|
|
|
|
uint inst_first;
|
|
|
|
uint inst_count;
|
|
|
|
} DRWCommandDrawInstanceRange;
|
|
|
|
|
2019-05-31 01:45:41 +02:00
|
|
|
typedef struct DRWCommandDrawProcedural {
|
|
|
|
GPUBatch *batch;
|
|
|
|
DRWResourceHandle handle;
|
|
|
|
uint vert_count;
|
|
|
|
} DRWCommandDrawProcedural;
|
|
|
|
|
|
|
|
typedef struct DRWCommandSetMutableState {
|
|
|
|
/** State changes (or'd or and'd with the pass's state) */
|
|
|
|
DRWState enable;
|
|
|
|
DRWState disable;
|
|
|
|
} DRWCommandSetMutableState;
|
|
|
|
|
|
|
|
typedef struct DRWCommandSetStencil {
|
2020-03-09 16:27:24 +01:00
|
|
|
uint write_mask;
|
|
|
|
uint comp_mask;
|
|
|
|
uint ref;
|
2019-05-31 01:45:41 +02:00
|
|
|
} DRWCommandSetStencil;
|
|
|
|
|
|
|
|
typedef struct DRWCommandSetSelectID {
|
|
|
|
GPUVertBuf *select_buf;
|
|
|
|
uint select_id;
|
|
|
|
} DRWCommandSetSelectID;
|
|
|
|
|
|
|
|
typedef struct DRWCommandClear {
|
|
|
|
eGPUFrameBufferBits clear_channels;
|
|
|
|
uchar r, g, b, a; /* [0..1] for each channels. Normalized. */
|
|
|
|
float depth; /* [0..1] for depth. Normalized. */
|
|
|
|
uchar stencil; /* Stencil value [0..255] */
|
|
|
|
} DRWCommandClear;
|
|
|
|
|
|
|
|
typedef union DRWCommand {
|
|
|
|
DRWCommandDraw draw;
|
|
|
|
DRWCommandDrawRange range;
|
|
|
|
DRWCommandDrawInstance instance;
|
2020-03-09 16:27:24 +01:00
|
|
|
DRWCommandDrawInstanceRange instance_range;
|
2019-05-31 01:45:41 +02:00
|
|
|
DRWCommandDrawProcedural procedural;
|
|
|
|
DRWCommandSetMutableState state;
|
|
|
|
DRWCommandSetStencil stencil;
|
|
|
|
DRWCommandSetSelectID select_id;
|
|
|
|
DRWCommandClear clear;
|
|
|
|
} DRWCommand;
|
|
|
|
|
|
|
|
/* Used for agregating calls into GPUVertBufs. */
|
|
|
|
struct DRWCallBuffer {
|
|
|
|
GPUVertBuf *buf;
|
|
|
|
GPUVertBuf *buf_select;
|
|
|
|
int count;
|
|
|
|
};
|
2018-02-28 01:16:23 +01:00
|
|
|
|
2018-02-28 17:11:54 +01:00
|
|
|
/* Used by DRWUniform.type */
|
|
|
|
typedef enum {
|
2019-05-31 01:45:41 +02:00
|
|
|
DRW_UNIFORM_INT = 0,
|
2019-04-17 06:17:24 +02:00
|
|
|
DRW_UNIFORM_INT_COPY,
|
|
|
|
DRW_UNIFORM_FLOAT,
|
|
|
|
DRW_UNIFORM_FLOAT_COPY,
|
|
|
|
DRW_UNIFORM_TEXTURE,
|
|
|
|
DRW_UNIFORM_TEXTURE_PERSIST,
|
|
|
|
DRW_UNIFORM_TEXTURE_REF,
|
|
|
|
DRW_UNIFORM_BLOCK,
|
|
|
|
DRW_UNIFORM_BLOCK_PERSIST,
|
2019-05-31 01:45:41 +02:00
|
|
|
DRW_UNIFORM_TFEEDBACK_TARGET,
|
|
|
|
/** Per drawcall uniforms/UBO */
|
|
|
|
DRW_UNIFORM_BLOCK_OBMATS,
|
|
|
|
DRW_UNIFORM_BLOCK_OBINFOS,
|
|
|
|
DRW_UNIFORM_RESOURCE_CHUNK,
|
2020-03-09 16:27:24 +01:00
|
|
|
DRW_UNIFORM_RESOURCE_ID,
|
2019-05-31 01:45:41 +02:00
|
|
|
/** Legacy / Fallback */
|
|
|
|
DRW_UNIFORM_BASE_INSTANCE,
|
|
|
|
DRW_UNIFORM_MODEL_MATRIX,
|
|
|
|
DRW_UNIFORM_MODEL_MATRIX_INVERSE,
|
|
|
|
DRW_UNIFORM_MODELVIEWPROJECTION_MATRIX,
|
|
|
|
/* WARNING: set DRWUniform->type
|
|
|
|
* bit length accordingly. */
|
2018-02-28 17:11:54 +01:00
|
|
|
} DRWUniformType;
|
2018-02-28 01:16:23 +01:00
|
|
|
|
|
|
|
struct DRWUniform {
|
2019-04-17 06:17:24 +02:00
|
|
|
union {
|
|
|
|
/* For reference or array/vector types. */
|
|
|
|
const void *pvalue;
|
|
|
|
/* Single values. */
|
2019-05-31 01:45:41 +02:00
|
|
|
float fvalue[4];
|
|
|
|
int ivalue[4];
|
2019-04-17 06:17:24 +02:00
|
|
|
};
|
|
|
|
int location;
|
2019-05-31 01:45:41 +02:00
|
|
|
uint32_t type : 5; /* DRWUniformType */
|
|
|
|
uint32_t length : 5; /* cannot be more than 16 */
|
|
|
|
uint32_t arraysize : 5; /* cannot be more than 16 too */
|
|
|
|
uint32_t name_ofs : 17; /* name offset in name buffer. */
|
2018-02-28 01:16:23 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
struct DRWShadingGroup {
|
2019-04-17 06:17:24 +02:00
|
|
|
DRWShadingGroup *next;
|
|
|
|
|
2019-05-31 01:45:41 +02:00
|
|
|
GPUShader *shader; /* Shader to bind */
|
|
|
|
struct DRWUniformChunk *uniforms; /* Uniforms pointers */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-13 17:56:20 +02:00
|
|
|
struct {
|
2019-05-31 01:45:41 +02:00
|
|
|
/* Chunks of draw calls. */
|
|
|
|
struct DRWCommandChunk *first, *last;
|
|
|
|
} cmd;
|
2019-05-13 17:56:20 +02:00
|
|
|
|
2019-05-31 01:45:41 +02:00
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
int objectinfo; /* Equal to 1 if the shader needs obinfos. */
|
|
|
|
DRWResourceHandle pass_handle; /* Memblock key to parent pass. */
|
|
|
|
};
|
|
|
|
struct {
|
|
|
|
float distance; /* Distance from camera. */
|
|
|
|
uint original_index; /* Original position inside the shgroup list. */
|
|
|
|
} z_sorting;
|
|
|
|
};
|
2018-02-28 01:16:23 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
#define MAX_PASS_NAME 32
|
|
|
|
|
|
|
|
struct DRWPass {
|
2019-04-17 06:17:24 +02:00
|
|
|
/* Linked list */
|
|
|
|
struct {
|
|
|
|
DRWShadingGroup *first;
|
|
|
|
DRWShadingGroup *last;
|
|
|
|
} shgroups;
|
|
|
|
|
2019-05-31 01:45:41 +02:00
|
|
|
DRWResourceHandle handle;
|
2019-04-17 06:17:24 +02:00
|
|
|
DRWState state;
|
|
|
|
char name[MAX_PASS_NAME];
|
2018-02-28 01:16:23 +01:00
|
|
|
};
|
|
|
|
|
2019-05-20 18:01:42 +02:00
|
|
|
/* keep in sync with viewBlock */
|
2019-05-21 23:56:55 +02:00
|
|
|
typedef struct DRWViewUboStorage {
|
|
|
|
/* View matrices */
|
|
|
|
float persmat[4][4];
|
|
|
|
float persinv[4][4];
|
|
|
|
float viewmat[4][4];
|
|
|
|
float viewinv[4][4];
|
|
|
|
float winmat[4][4];
|
|
|
|
float wininv[4][4];
|
|
|
|
|
2019-05-20 18:01:42 +02:00
|
|
|
float clipplanes[6][4];
|
2019-08-01 13:53:25 +10:00
|
|
|
/* Should not be here. Not view dependent (only main view). */
|
2019-05-20 18:01:42 +02:00
|
|
|
float viewcamtexcofac[4];
|
2019-05-21 23:56:55 +02:00
|
|
|
} DRWViewUboStorage;
|
2019-05-20 18:01:42 +02:00
|
|
|
|
2019-05-31 01:45:41 +02:00
|
|
|
BLI_STATIC_ASSERT_ALIGN(DRWViewUboStorage, 16)
|
|
|
|
|
2019-05-20 18:01:42 +02:00
|
|
|
#define MAX_CULLED_VIEWS 32
|
|
|
|
|
|
|
|
struct DRWView {
|
|
|
|
/** Parent view if this is a sub view. NULL otherwise. */
|
|
|
|
struct DRWView *parent;
|
|
|
|
|
2019-05-21 23:56:55 +02:00
|
|
|
DRWViewUboStorage storage;
|
2019-05-20 18:01:42 +02:00
|
|
|
/** Number of active clipplanes. */
|
|
|
|
int clip_planes_len;
|
|
|
|
/** Does culling result needs to be updated. */
|
|
|
|
bool is_dirty;
|
2020-02-19 19:36:12 +01:00
|
|
|
/** Does facing needs to be reversed? */
|
|
|
|
bool is_inverted;
|
2019-05-20 18:01:42 +02:00
|
|
|
/** Culling */
|
|
|
|
uint32_t culling_mask;
|
|
|
|
BoundBox frustum_corners;
|
|
|
|
BoundSphere frustum_bsphere;
|
|
|
|
float frustum_planes[6][4];
|
|
|
|
/** Custom visibility function. */
|
|
|
|
DRWCallVisibilityFn *visibility_fn;
|
|
|
|
void *user_data;
|
|
|
|
};
|
|
|
|
|
2019-05-31 01:45:41 +02:00
|
|
|
/* ------------ Data Chunks --------------- */
|
|
|
|
/**
|
|
|
|
* In order to keep a cache friendly data structure,
|
|
|
|
* we alloc most of our little data into chunks of multiple item.
|
|
|
|
* Iteration, allocation and memory usage are better.
|
|
|
|
* We loose a bit of memory by allocating more than what we need
|
|
|
|
* but it's counterbalanced by not needing the linked-list pointers
|
|
|
|
* for each item.
|
|
|
|
**/
|
|
|
|
|
|
|
|
typedef struct DRWUniformChunk {
|
|
|
|
struct DRWUniformChunk *next; /* single-linked list */
|
|
|
|
uint32_t uniform_len;
|
|
|
|
uint32_t uniform_used;
|
|
|
|
DRWUniform uniforms[10];
|
|
|
|
} DRWUniformChunk;
|
|
|
|
|
|
|
|
typedef struct DRWCommandChunk {
|
|
|
|
struct DRWCommandChunk *next;
|
|
|
|
uint32_t command_len;
|
|
|
|
uint32_t command_used;
|
|
|
|
/* 4bits for each command. */
|
|
|
|
uint64_t command_type[6];
|
|
|
|
/* -- 64 bytes aligned -- */
|
|
|
|
DRWCommand commands[96];
|
|
|
|
/* -- 64 bytes aligned -- */
|
|
|
|
} DRWCommandChunk;
|
|
|
|
|
|
|
|
typedef struct DRWCommandSmallChunk {
|
|
|
|
struct DRWCommandChunk *next;
|
|
|
|
uint32_t command_len;
|
|
|
|
uint32_t command_used;
|
|
|
|
/* 4bits for each command. */
|
|
|
|
/* TODO reduce size of command_type. */
|
|
|
|
uint64_t command_type[6];
|
|
|
|
DRWCommand commands[6];
|
|
|
|
} DRWCommandSmallChunk;
|
|
|
|
|
2019-11-18 16:25:59 +11:00
|
|
|
/* Only true for 64-bit platforms. */
|
|
|
|
#ifdef __LP64__
|
2019-05-31 01:45:41 +02:00
|
|
|
BLI_STATIC_ASSERT_ALIGN(DRWCommandChunk, 16);
|
2019-11-18 16:25:59 +11:00
|
|
|
#endif
|
2019-05-09 00:38:48 +02:00
|
|
|
|
2018-05-26 22:08:56 +02:00
|
|
|
/* ------------- DRAW DEBUG ------------ */
|
|
|
|
|
|
|
|
typedef struct DRWDebugLine {
|
2019-04-17 06:17:24 +02:00
|
|
|
struct DRWDebugLine *next; /* linked list */
|
|
|
|
float pos[2][3];
|
|
|
|
float color[4];
|
2018-05-26 22:08:56 +02:00
|
|
|
} DRWDebugLine;
|
|
|
|
|
2018-07-16 20:07:13 +02:00
|
|
|
typedef struct DRWDebugSphere {
|
2019-04-17 06:17:24 +02:00
|
|
|
struct DRWDebugSphere *next; /* linked list */
|
|
|
|
float mat[4][4];
|
|
|
|
float color[4];
|
2018-07-16 20:07:13 +02:00
|
|
|
} DRWDebugSphere;
|
|
|
|
|
2018-02-28 01:16:23 +01:00
|
|
|
/* ------------- DRAW MANAGER ------------ */
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
#define DST_MAX_SLOTS 64 /* Cannot be changed without modifying RST.bound_tex_slots */
|
2018-02-28 01:16:23 +01:00
|
|
|
#define MAX_CLIP_PLANES 6 /* GL_MAX_CLIP_PLANES is at least 6 */
|
2018-05-04 14:07:00 +02:00
|
|
|
#define STENCIL_UNDEFINED 256
|
2019-05-31 01:45:41 +02:00
|
|
|
#define DRW_DRAWLIST_LEN 256
|
2018-02-28 01:16:23 +01:00
|
|
|
typedef struct DRWManager {
|
2019-04-17 06:17:24 +02:00
|
|
|
/* TODO clean up this struct a bit */
|
|
|
|
/* Cache generation */
|
|
|
|
ViewportMemoryPool *vmempool;
|
|
|
|
DRWInstanceDataList *idatalist;
|
|
|
|
/* State of the object being evaluated if already allocated. */
|
2019-05-31 01:45:41 +02:00
|
|
|
DRWResourceHandle ob_handle;
|
|
|
|
/** True if current DST.ob_state has its matching DRWObjectInfos init. */
|
|
|
|
bool ob_state_obinfo_init;
|
|
|
|
/** Handle of current object resource in object resource arrays (DRWObjectMatrices/Infos). */
|
|
|
|
DRWResourceHandle resource_handle;
|
|
|
|
/** Handle of next DRWPass to be allocated. */
|
|
|
|
DRWResourceHandle pass_handle;
|
|
|
|
|
|
|
|
/** Dupli state. NULL if not dupli. */
|
2019-04-17 06:17:24 +02:00
|
|
|
struct DupliObject *dupli_source;
|
|
|
|
struct Object *dupli_parent;
|
2019-05-07 20:56:20 +02:00
|
|
|
struct Object *dupli_origin;
|
2019-05-31 01:45:41 +02:00
|
|
|
/** Ghash containing original objects. */
|
2019-05-07 20:56:20 +02:00
|
|
|
struct GHash *dupli_ghash;
|
2019-05-31 01:45:41 +02:00
|
|
|
/** TODO(fclem) try to remove usage of this. */
|
|
|
|
DRWInstanceData *object_instance_data[MAX_INSTANCE_DATA_SIZE];
|
|
|
|
/* Array of dupli_data (one for each enabled engine) to handle duplis. */
|
|
|
|
void **dupli_datas;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
/* Rendering state */
|
|
|
|
GPUShader *shader;
|
2019-05-22 13:27:43 +02:00
|
|
|
GPUBatch *batch;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
/* Managed by `DRW_state_set`, `DRW_state_reset` */
|
|
|
|
DRWState state;
|
|
|
|
DRWState state_lock;
|
|
|
|
|
|
|
|
/* Per viewport */
|
|
|
|
GPUViewport *viewport;
|
|
|
|
struct GPUFrameBuffer *default_framebuffer;
|
|
|
|
float size[2];
|
|
|
|
float inv_size[2];
|
|
|
|
float screenvecs[2][3];
|
|
|
|
float pixsize;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
uint is_select : 1;
|
|
|
|
uint is_depth : 1;
|
|
|
|
uint is_image_render : 1;
|
|
|
|
uint is_scene_render : 1;
|
2019-05-21 12:00:48 +02:00
|
|
|
uint do_color_management : 1;
|
2019-04-17 06:17:24 +02:00
|
|
|
uint draw_background : 1;
|
|
|
|
uint draw_text : 1;
|
|
|
|
} options;
|
|
|
|
|
|
|
|
/* Current rendering context */
|
|
|
|
DRWContextState draw_ctx;
|
|
|
|
|
|
|
|
/* Convenience pointer to text_store owned by the viewport */
|
|
|
|
struct DRWTextStore **text_store_p;
|
|
|
|
|
|
|
|
ListBase enabled_engines; /* RenderEngineType */
|
2019-05-07 18:40:02 +02:00
|
|
|
void **vedata_array; /* ViewportEngineData */
|
2019-05-07 20:56:20 +02:00
|
|
|
int enabled_engine_count; /* Length of enabled_engines list. */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
bool buffer_finish_called; /* Avoid bad usage of DRW_render_instance_buffer_finish */
|
|
|
|
|
2019-05-20 18:01:42 +02:00
|
|
|
DRWView *view_default;
|
|
|
|
DRWView *view_active;
|
2019-05-21 22:11:53 +02:00
|
|
|
DRWView *view_previous;
|
2019-05-20 18:01:42 +02:00
|
|
|
uint primary_view_ct;
|
|
|
|
/** TODO(fclem) Remove this. Only here to support
|
|
|
|
* shaders without common_view_lib.glsl */
|
2019-05-21 23:56:55 +02:00
|
|
|
DRWViewUboStorage view_storage_cpy;
|
2018-03-01 03:52:54 +01:00
|
|
|
|
2018-02-28 01:16:23 +01:00
|
|
|
#ifdef USE_GPU_SELECT
|
2019-04-17 06:17:24 +02:00
|
|
|
uint select_id;
|
2018-02-28 01:16:23 +01:00
|
|
|
#endif
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* ---------- Nothing after this point is cleared after use ----------- */
|
|
|
|
|
|
|
|
/* gl_context serves as the offset for clearing only
|
|
|
|
* the top portion of the struct so DO NOT MOVE IT! */
|
2019-04-21 13:44:06 +10:00
|
|
|
/** Unique ghost context used by the draw manager. */
|
|
|
|
void *gl_context;
|
2019-04-17 06:17:24 +02:00
|
|
|
GPUContext *gpu_context;
|
2019-04-21 13:44:06 +10:00
|
|
|
/** Mutex to lock the drw manager and avoid concurrent context usage. */
|
|
|
|
TicketMutex *gl_context_mutex;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-31 01:45:41 +02:00
|
|
|
GPUDrawList *draw_list;
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/** GPU Resource State: Memory storage between drawing. */
|
|
|
|
struct {
|
|
|
|
/* High end GPUs supports up to 32 binds per shader stage.
|
|
|
|
* We only use textures during the vertex and fragment stage,
|
|
|
|
* so 2 * 32 slots is a nice limit. */
|
|
|
|
GPUTexture *bound_texs[DST_MAX_SLOTS];
|
|
|
|
uint64_t bound_tex_slots;
|
|
|
|
uint64_t bound_tex_slots_persist;
|
|
|
|
|
|
|
|
GPUUniformBuffer *bound_ubos[DST_MAX_SLOTS];
|
|
|
|
uint64_t bound_ubo_slots;
|
|
|
|
uint64_t bound_ubo_slots_persist;
|
|
|
|
} RST;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
/* TODO(fclem) optimize: use chunks. */
|
|
|
|
DRWDebugLine *lines;
|
|
|
|
DRWDebugSphere *spheres;
|
|
|
|
} debug;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
char *buffer;
|
|
|
|
uint buffer_len;
|
|
|
|
uint buffer_ofs;
|
|
|
|
} uniform_names;
|
2018-02-28 01:16:23 +01:00
|
|
|
} DRWManager;
|
|
|
|
|
2019-06-12 09:04:10 +10:00
|
|
|
extern DRWManager DST; /* TODO: get rid of this and allow multi-threaded rendering. */
|
2018-02-28 01:16:23 +01:00
|
|
|
|
|
|
|
/* --------------- FUNCTIONS ------------- */
|
|
|
|
|
|
|
|
void drw_texture_set_parameters(GPUTexture *tex, DRWTextureFlag flags);
|
|
|
|
|
|
|
|
void *drw_viewport_engine_data_ensure(void *engine_type);
|
|
|
|
|
|
|
|
void drw_state_set(DRWState state);
|
|
|
|
|
2018-05-26 22:08:56 +02:00
|
|
|
void drw_debug_draw(void);
|
|
|
|
void drw_debug_init(void);
|
|
|
|
|
2019-05-31 01:45:41 +02:00
|
|
|
eDRWCommandType command_type_get(uint64_t *command_type_bits, int index);
|
|
|
|
|
2019-05-07 23:21:16 +02:00
|
|
|
void drw_batch_cache_validate(Object *ob);
|
2018-12-08 20:10:20 +01:00
|
|
|
void drw_batch_cache_generate_requested(struct Object *ob);
|
|
|
|
|
2019-05-31 01:45:41 +02:00
|
|
|
void drw_resource_buffer_finish(ViewportMemoryPool *vmempool);
|
|
|
|
|
2019-05-11 17:45:20 +02:00
|
|
|
/* Procedural Drawing */
|
|
|
|
GPUBatch *drw_cache_procedural_points_get(void);
|
|
|
|
GPUBatch *drw_cache_procedural_lines_get(void);
|
|
|
|
GPUBatch *drw_cache_procedural_triangles_get(void);
|
|
|
|
|
2018-02-28 01:16:23 +01:00
|
|
|
#endif /* __DRAW_MANAGER_H__ */
|