DRW: Refactor to support draw call batching

Reviewers: brecht

Differential Revision: D4997
This commit is contained in:
2019-05-31 01:45:41 +02:00
parent 41299bce93
commit 3a08153d7a
57 changed files with 2299 additions and 1272 deletions

View File

@@ -1,4 +1,5 @@
#define COMMON_VIEW_LIB
#define DRW_RESOURCE_CHUNK_LEN 512
/* keep in sync with DRWManager.view_data */
layout(std140) uniform viewBlock
@@ -23,8 +24,74 @@ layout(std140) uniform viewBlock
_world_clip_planes_calc_clip_distance(p, clipPlanes)
#endif
uniform int resourceChunk;
#ifdef GPU_VERTEX_SHADER
# ifdef GL_ARB_shader_draw_parameters
# define baseInstance gl_BaseInstanceARB
# else /* no ARB_shader_draw_parameters */
uniform int baseInstance;
# endif
# ifdef IN_PLACE_INSTANCES
/* When drawing instances of an object at the same position. */
# define instanceId 0
# elif defined(GPU_CRAPPY_AMD_DRIVER)
/* NOTE: This does contain the baseInstance ofset */
in int _instanceId;
# define instanceId (_instanceId - baseInstance)
# else
# define instanceId gl_InstanceID
# endif
# define resource_id (baseInstance + instanceId)
/* Use this to declare and pass the value if
* the fragment shader uses the resource_id. */
# define RESOURCE_ID_VARYING flat out int resourceIDFrag;
# define RESOURCE_ID_VARYING_GEOM flat out int resourceIDGeom;
# define PASS_RESOURCE_ID resourceIDFrag = resource_id;
# define PASS_RESOURCE_ID_GEOM resourceIDGeom = resource_id;
#endif
/* If used in a fragment / geometry shader, we pass
* resource_id as varying. */
#ifdef GPU_GEOMETRY_SHADER
# define RESOURCE_ID_VARYING \
flat out int resourceIDFrag; \
flat in int resourceIDGeom[];
# define resource_id resourceIDGeom
# define PASS_RESOURCE_ID(i) resourceIDFrag = resource_id[i];
#endif
#ifdef GPU_FRAGMENT_SHADER
flat in int resourceIDFrag;
# define resource_id resourceIDFrag
#endif
#ifndef GPU_INTEL
struct ObjectMatrices {
mat4 drw_modelMatrix;
mat4 drw_modelMatrixInverse;
};
layout(std140) uniform modelBlock
{
ObjectMatrices drw_matrices[DRW_RESOURCE_CHUNK_LEN];
};
# define ModelMatrix (drw_matrices[resource_id].drw_modelMatrix)
# define ModelMatrixInverse (drw_matrices[resource_id].drw_modelMatrixInverse)
#else /* GPU_INTEL */
/* Intel GPU seems to suffer performance impact when the model matrix is in UBO storage.
* So for now we just force using the legacy path. */
uniform mat4 ModelMatrix;
uniform mat4 ModelMatrixInverse;
#endif
#define resource_handle (resourceChunk * DRW_RESOURCE_CHUNK_LEN + resource_id)
/** Transform shortcuts. */
/* Rule of thumb: Try to reuse world positions and normals because converting though viewspace

View File

@@ -1,18 +1,11 @@
uniform mat4 ViewProjectionMatrix;
uniform float sphere_size;
uniform ivec3 grid_resolution;
uniform vec3 corner;
uniform vec3 increment_x;
uniform vec3 increment_y;
uniform vec3 increment_z;
uniform vec3 screen_vecs[2];
uniform int call_id; /* we don't want the builtin callId which would be 0. */
uniform int baseId;
flat out uint finalId;
flat out int objectId;
void main()
{
@@ -29,7 +22,8 @@ void main()
gl_Position = ViewProjectionMatrix * vec4(ws_cell_location, 1.0);
gl_PointSize = 2.0f;
finalId = uint(baseId + call_id);
/* ID 0 is nothing (background) */
objectId = resource_handle + 1;
#ifdef USE_WORLD_CLIP_PLANES
world_clip_planes_calc_clip_distance(ws_cell_location);

View File

@@ -7,30 +7,9 @@ uniform usampler2D outlineId;
uniform sampler2D outlineDepth;
uniform sampler2D sceneDepth;
uniform int idOffsets[4];
uniform float alphaOcclu;
uniform vec2 viewportSize;
vec4 convert_id_to_color(int id)
{
if (id == 0) {
return vec4(0.0);
}
if (id < idOffsets[1]) {
return colorActive;
}
else if (id < idOffsets[2]) {
return colorSelect;
}
else if (id < idOffsets[3]) {
return colorDupliSelect;
}
else {
return colorTransform;
}
}
void main()
{
ivec2 texel = ivec2(gl_FragCoord.xy);
@@ -85,7 +64,24 @@ void main()
const float epsilon = 3.0 / 8388608.0;
bool occluded = (ref_depth > scene_depth + epsilon);
FragColor = convert_id_to_color(int(ref_id));
/* WATCH: Keep in sync with outlineId of the prepass. */
uint color_id = ref_id >> 14u;
if (ref_id == 0u) {
FragColor = vec4(0.0);
}
else if (color_id == 1u) {
FragColor = colorSelect;
}
else if (color_id == 2u) {
FragColor = colorDupliSelect;
}
else if (color_id == 3u) {
FragColor = colorActive;
}
else {
FragColor = colorTransform;
}
FragColor.a *= (occluded) ? alphaOcclu : 1.0;
FragColor.a = (outline) ? FragColor.a : 0.0;
}

View File

@@ -1,10 +1,18 @@
uniform int callId;
uniform int baseId;
/* Should be 2 bits only [0..3]. */
uniform int outlineId;
flat in int objectId;
/* using uint because 16bit uint can contain more ids than int. */
out uint outId;
/* Replace top 2 bits (of the 16bit output) by outlineId.
* This leaves 16K different IDs to create outlines between objects.
* SHIFT = (32 - (16 - 2)) */
#define SHIFT 18u
void main()
{
outId = uint(baseId + callId);
outId = (uint(outlineId) << 14u) | ((uint(objectId) << SHIFT) >> SHIFT);
}

View File

@@ -2,12 +2,15 @@
layout(lines_adjacency) in;
layout(line_strip, max_vertices = 2) out;
in vec4 pPos[];
in vec3 vPos[];
in int objectId_g[];
flat out int objectId;
void vert_from_gl_in(int v)
{
gl_Position = pPos[v];
gl_Position = gl_in[v].gl_Position;
objectId = objectId_g[v];
#ifdef USE_WORLD_CLIP_PLANES
world_clip_planes_set_clip_distance(gl_in[v].gl_ClipDistance);
#endif

View File

@@ -1,16 +1,27 @@
in vec3 pos;
out vec4 pPos;
#ifdef USE_GEOM
out vec3 vPos;
out int objectId_g;
# define objectId objectId_g
#else
flat out int objectId;
#endif
void main()
{
vec3 world_pos = point_object_to_world(pos);
#ifdef USE_GEOM
vPos = point_world_to_view(world_pos);
pPos = point_world_to_ndc(world_pos);
#endif
gl_Position = point_world_to_ndc(world_pos);
/* Small bias to always be on top of the geom. */
pPos.z -= 1e-3;
gl_Position.z -= 1e-3;
/* ID 0 is nothing (background) */
objectId = resource_handle + 1;
#ifdef USE_WORLD_CLIP_PLANES
world_clip_planes_calc_clip_distance(world_pos);