DRW: Refactor to support draw call batching
Reviewers: brecht Differential Revision: D4997
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user