Compare commits
2 Commits
temp-nodes
...
arcpatch-D
Author | SHA1 | Date | |
---|---|---|---|
d1c8699f83 | |||
![]() |
4d18250a2a |
@@ -477,9 +477,11 @@ set(GLSL_SRC
|
|||||||
engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl
|
engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl
|
||||||
engines/workbench/shaders/workbench_prepass_vert.glsl
|
engines/workbench/shaders/workbench_prepass_vert.glsl
|
||||||
engines/workbench/shaders/workbench_shadow_caps_geom.glsl
|
engines/workbench/shaders/workbench_shadow_caps_geom.glsl
|
||||||
|
engines/workbench/shaders/workbench_shadow_caps_vert_no_geom.glsl
|
||||||
engines/workbench/shaders/workbench_shadow_debug_frag.glsl
|
engines/workbench/shaders/workbench_shadow_debug_frag.glsl
|
||||||
engines/workbench/shaders/workbench_shadow_geom.glsl
|
engines/workbench/shaders/workbench_shadow_geom.glsl
|
||||||
engines/workbench/shaders/workbench_shadow_vert.glsl
|
engines/workbench/shaders/workbench_shadow_vert.glsl
|
||||||
|
engines/workbench/shaders/workbench_shadow_vert_no_geom.glsl
|
||||||
engines/workbench/shaders/workbench_transparent_accum_frag.glsl
|
engines/workbench/shaders/workbench_transparent_accum_frag.glsl
|
||||||
engines/workbench/shaders/workbench_transparent_resolve_frag.glsl
|
engines/workbench/shaders/workbench_transparent_resolve_frag.glsl
|
||||||
engines/workbench/shaders/workbench_volume_frag.glsl
|
engines/workbench/shaders/workbench_volume_frag.glsl
|
||||||
|
@@ -13,12 +13,17 @@ GPU_SHADER_INTERFACE_INFO(workbench_shadow_iface, "vData")
|
|||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(workbench_shadow_common)
|
GPU_SHADER_CREATE_INFO(workbench_shadow_common)
|
||||||
.vertex_in(0, Type::VEC3, "pos")
|
.vertex_in(0, Type::VEC3, "pos")
|
||||||
.vertex_out(workbench_shadow_iface)
|
|
||||||
.push_constant(Type::FLOAT, "lightDistance")
|
.push_constant(Type::FLOAT, "lightDistance")
|
||||||
.push_constant(Type::VEC3, "lightDirection")
|
.push_constant(Type::VEC3, "lightDirection")
|
||||||
.vertex_source("workbench_shadow_vert.glsl")
|
|
||||||
.additional_info("draw_mesh");
|
.additional_info("draw_mesh");
|
||||||
|
|
||||||
|
/* `workbench_shadow_vert.glsl` only used by geometry shader path.
|
||||||
|
* Vertex output iface not needed by non-geometry shader variants,
|
||||||
|
* as only gl_Position is returned. */
|
||||||
|
GPU_SHADER_CREATE_INFO(workbench_shadow_common_geom)
|
||||||
|
.vertex_out(workbench_shadow_iface)
|
||||||
|
.vertex_source("workbench_shadow_vert.glsl");
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
@@ -26,13 +31,25 @@ GPU_SHADER_CREATE_INFO(workbench_shadow_common)
|
|||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(workbench_shadow_manifold)
|
GPU_SHADER_CREATE_INFO(workbench_shadow_manifold)
|
||||||
|
.additional_info("workbench_shadow_common_geom")
|
||||||
.geometry_layout(PrimitiveIn::LINES_ADJACENCY, PrimitiveOut::TRIANGLE_STRIP, 4, 1)
|
.geometry_layout(PrimitiveIn::LINES_ADJACENCY, PrimitiveOut::TRIANGLE_STRIP, 4, 1)
|
||||||
.geometry_source("workbench_shadow_geom.glsl");
|
.geometry_source("workbench_shadow_geom.glsl");
|
||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(workbench_shadow_no_manifold)
|
GPU_SHADER_CREATE_INFO(workbench_shadow_no_manifold)
|
||||||
|
.additional_info("workbench_shadow_common_geom")
|
||||||
.geometry_layout(PrimitiveIn::LINES_ADJACENCY, PrimitiveOut::TRIANGLE_STRIP, 4, 2)
|
.geometry_layout(PrimitiveIn::LINES_ADJACENCY, PrimitiveOut::TRIANGLE_STRIP, 4, 2)
|
||||||
.geometry_source("workbench_shadow_geom.glsl");
|
.geometry_source("workbench_shadow_geom.glsl");
|
||||||
|
|
||||||
|
GPU_SHADER_CREATE_INFO(workbench_shadow_manifold_no_geom)
|
||||||
|
.vertex_source("workbench_shadow_vert_no_geom.glsl")
|
||||||
|
/* Inject SSBO vertex fetch declaration using 2 output triangles. */
|
||||||
|
.define("VAR_MANIFOLD", "\n#pragma USE_SSBO_VERTEX_FETCH(TriangleList, 6)");
|
||||||
|
|
||||||
|
GPU_SHADER_CREATE_INFO(workbench_shadow_no_manifold_no_geom)
|
||||||
|
.vertex_source("workbench_shadow_vert_no_geom.glsl")
|
||||||
|
/* Inject SSBO vertex fetch declaration using 4 output triangles. */
|
||||||
|
.define("VAR_NO_MANIFOLD", "\n#pragma USE_SSBO_VERTEX_FETCH(TriangleList, 12)");
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
@@ -40,9 +57,13 @@ GPU_SHADER_CREATE_INFO(workbench_shadow_no_manifold)
|
|||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(workbench_shadow_caps)
|
GPU_SHADER_CREATE_INFO(workbench_shadow_caps)
|
||||||
|
.additional_info("workbench_shadow_common_geom")
|
||||||
.geometry_layout(PrimitiveIn::TRIANGLES, PrimitiveOut::TRIANGLE_STRIP, 3, 2)
|
.geometry_layout(PrimitiveIn::TRIANGLES, PrimitiveOut::TRIANGLE_STRIP, 3, 2)
|
||||||
.geometry_source("workbench_shadow_caps_geom.glsl");
|
.geometry_source("workbench_shadow_caps_geom.glsl");
|
||||||
|
|
||||||
|
GPU_SHADER_CREATE_INFO(workbench_shadow_caps_no_geom)
|
||||||
|
.vertex_source("workbench_shadow_caps_vert_no_geom.glsl");
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@@ -0,0 +1,105 @@
|
|||||||
|
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||||
|
#pragma USE_SSBO_VERTEX_FETCH(TriangleList, 6)
|
||||||
|
|
||||||
|
#ifdef DOUBLE_MANIFOLD
|
||||||
|
# define vert_len 6 /* Triangle Strip with 6 verts = 4 triangles = 12 verts*/
|
||||||
|
# define emit_triangle_count 2
|
||||||
|
#else
|
||||||
|
# define vert_len 6 /* Triangle Strip with 6 verts = 4 triangles = 12 verts*/
|
||||||
|
# define emit_triangle_count 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct VertexData {
|
||||||
|
vec3 pos; /* local position */
|
||||||
|
vec4 frontPosition; /* final ndc position */
|
||||||
|
vec4 backPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Input geometry triangle list. */
|
||||||
|
VertexData vData[3] = {};
|
||||||
|
|
||||||
|
#define DISCARD_VERTEX \
|
||||||
|
gl_Position = vec4(0.0); \
|
||||||
|
return;
|
||||||
|
|
||||||
|
vec4 get_pos(int v, bool backface)
|
||||||
|
{
|
||||||
|
return (backface) ? vData[v].backPosition : vData[v].frontPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
void emit_cap(const bool front, bool reversed, int triangle_vertex_id)
|
||||||
|
{
|
||||||
|
/* Inverse. */
|
||||||
|
ivec2 idx = (reversed) ? ivec2(2, 1) : ivec2(1, 2);
|
||||||
|
|
||||||
|
/* Output position depending on vertex ID. */
|
||||||
|
switch (triangle_vertex_id) {
|
||||||
|
case 0: {
|
||||||
|
gl_Position = (front) ? vData[0].frontPosition : vData[0].backPosition;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case 1: {
|
||||||
|
gl_Position = (front) ? vData[idx.x].frontPosition : vData[idx.y].backPosition;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case 2: {
|
||||||
|
gl_Position = (front) ? vData[idx.y].frontPosition : vData[idx.x].backPosition;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply depth bias. Prevents Z-fighting artifacts when fast-math is enabled. */
|
||||||
|
gl_Position.z += 0.00005;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
/* Output Data indexing. */
|
||||||
|
int input_prim_index = int(gl_VertexID / 6);
|
||||||
|
int output_vertex_id = gl_VertexID % 6;
|
||||||
|
int output_triangle_id = output_vertex_id / 3;
|
||||||
|
|
||||||
|
/* Source primitive data location derived from output primitive. */
|
||||||
|
int input_base_vertex_id = input_prim_index * 3;
|
||||||
|
|
||||||
|
/* In data is triangles - Should be guaranteed. */
|
||||||
|
/* Read input position data. */
|
||||||
|
vData[0].pos = vertex_fetch_attribute(input_base_vertex_id + 0, pos, vec3);
|
||||||
|
vData[1].pos = vertex_fetch_attribute(input_base_vertex_id + 1, pos, vec3);
|
||||||
|
vData[2].pos = vertex_fetch_attribute(input_base_vertex_id + 2, pos, vec3);
|
||||||
|
|
||||||
|
/* Calculate front/back Positions. */
|
||||||
|
vData[0].frontPosition = point_object_to_ndc(vData[0].pos);
|
||||||
|
vData[0].backPosition = point_object_to_ndc(vData[0].pos + lightDirection * lightDistance);
|
||||||
|
|
||||||
|
vData[1].frontPosition = point_object_to_ndc(vData[1].pos);
|
||||||
|
vData[1].backPosition = point_object_to_ndc(vData[1].pos + lightDirection * lightDistance);
|
||||||
|
|
||||||
|
vData[2].frontPosition = point_object_to_ndc(vData[2].pos);
|
||||||
|
vData[2].backPosition = point_object_to_ndc(vData[2].pos + lightDirection * lightDistance);
|
||||||
|
|
||||||
|
/* Geometry shader equivalent calc. */
|
||||||
|
vec3 v10 = vData[0].pos - vData[1].pos;
|
||||||
|
vec3 v12 = vData[2].pos - vData[1].pos;
|
||||||
|
|
||||||
|
vec3 n = cross(v12, v10);
|
||||||
|
float facing = dot(n, lightDirection);
|
||||||
|
|
||||||
|
bool backface = facing > 0.0;
|
||||||
|
|
||||||
|
#ifdef DOUBLE_MANIFOLD
|
||||||
|
/* In case of non manifold geom, we only increase/decrease
|
||||||
|
* the stencil buffer by one but do every faces as they were facing the light. */
|
||||||
|
bool invert = backface;
|
||||||
|
const bool is_manifold = false;
|
||||||
|
#else
|
||||||
|
const bool invert = false;
|
||||||
|
const bool is_manifold = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!is_manifold || !backface) {
|
||||||
|
bool do_front = (output_triangle_id==0)?true:false;
|
||||||
|
emit_cap(do_front, invert, output_vertex_id%3);
|
||||||
|
} else {
|
||||||
|
DISCARD_VERTEX
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,160 @@
|
|||||||
|
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||||
|
|
||||||
|
/* Two variants, split pass, generates either 2 triangles or 6 triangles depending on input
|
||||||
|
* geometry manifold type */
|
||||||
|
|
||||||
|
#ifdef DOUBLE_MANIFOLD
|
||||||
|
# define vert_len 12 /* Triangle Strip with 6 verts = 4 triangles = 12 verts*/
|
||||||
|
# define emit_triangle_count 4
|
||||||
|
#else
|
||||||
|
# define vert_len 6 /* Triang;e Strip with 4 verts = 2 triangles = 6 verts*/
|
||||||
|
# define emit_triangle_count 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DEGENERATE_TRIS_WORKAROUND
|
||||||
|
#define DEGENERATE_TRIS_AREA_THRESHOLD 4e-15
|
||||||
|
|
||||||
|
#define len_sqr(a) dot(a, a)
|
||||||
|
|
||||||
|
struct VertexData {
|
||||||
|
vec3 pos; /* local position */
|
||||||
|
vec4 frontPosition; /* final ndc position */
|
||||||
|
vec4 backPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DISCARD_VERTEX \
|
||||||
|
gl_Position = vec4(0.0); \
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Extra positions for primary triangle */
|
||||||
|
VertexData vData[4];
|
||||||
|
|
||||||
|
void extrude_edge(bool invert, int output_vertex_id)
|
||||||
|
{
|
||||||
|
/* Reverse order if backfacing the light. */
|
||||||
|
ivec2 idx = (invert) ? ivec2(1, 2) : ivec2(2, 1);
|
||||||
|
|
||||||
|
/* Either outputs first or second quad, depending on double manifold status. */
|
||||||
|
int triangle_vertex_id = output_vertex_id % 6;
|
||||||
|
|
||||||
|
switch (triangle_vertex_id) {
|
||||||
|
case 0:
|
||||||
|
gl_Position = vData[idx.x].frontPosition;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
case 4:
|
||||||
|
gl_Position = vData[idx.y].frontPosition;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
gl_Position = vData[idx.x].backPosition;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
gl_Position = vData[idx.y].backPosition;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply depth bias. Prevents Z-fighting artifacts when fast-math is enabled. */
|
||||||
|
gl_Position.z += 0.00005;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
/* Output Data indexing. */
|
||||||
|
#ifdef DOUBLE_MANIFOLD
|
||||||
|
int input_prim_index = int(gl_VertexID / 12);
|
||||||
|
int output_vertex_id = gl_VertexID % 12;
|
||||||
|
int output_quad_id = (output_vertex_id >= 6) ? 1 : 0;
|
||||||
|
#else
|
||||||
|
int input_prim_index = int(gl_VertexID / 6);
|
||||||
|
int output_vertex_id = gl_VertexID % 6;
|
||||||
|
int output_quad_id = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Source primitive data location derived from output primitive. */
|
||||||
|
int input_base_vertex_id = (input_prim_index * 4);
|
||||||
|
|
||||||
|
/* IN DATA is lines_adjacency - Should be guaranteed. */
|
||||||
|
/* Read input position data. */
|
||||||
|
vData[0].pos = vertex_fetch_attribute(input_base_vertex_id + 0, pos, vec3);
|
||||||
|
vData[1].pos = vertex_fetch_attribute(input_base_vertex_id + 1, pos, vec3);
|
||||||
|
vData[2].pos = vertex_fetch_attribute(input_base_vertex_id + 2, pos, vec3);
|
||||||
|
vData[3].pos = vertex_fetch_attribute(input_base_vertex_id + 3, pos, vec3);
|
||||||
|
|
||||||
|
/* Calculate front/back Positions. */
|
||||||
|
vData[0].frontPosition = point_object_to_ndc(vData[0].pos);
|
||||||
|
vData[0].backPosition = point_object_to_ndc(vData[0].pos + lightDirection * lightDistance);
|
||||||
|
|
||||||
|
vData[1].frontPosition = point_object_to_ndc(vData[1].pos);
|
||||||
|
vData[1].backPosition = point_object_to_ndc(vData[1].pos + lightDirection * lightDistance);
|
||||||
|
|
||||||
|
vData[2].frontPosition = point_object_to_ndc(vData[2].pos);
|
||||||
|
vData[2].backPosition = point_object_to_ndc(vData[2].pos + lightDirection * lightDistance);
|
||||||
|
|
||||||
|
vData[3].frontPosition = point_object_to_ndc(vData[3].pos);
|
||||||
|
vData[3].backPosition = point_object_to_ndc(vData[3].pos + lightDirection * lightDistance);
|
||||||
|
|
||||||
|
/* Geometry shader equivalent path. */
|
||||||
|
vec3 v10 = vData[0].pos - vData[1].pos;
|
||||||
|
vec3 v12 = vData[2].pos - vData[1].pos;
|
||||||
|
vec3 v13 = vData[3].pos - vData[1].pos;
|
||||||
|
vec3 n1 = cross(v12, v10);
|
||||||
|
vec3 n2 = cross(v13, v12);
|
||||||
|
|
||||||
|
#ifdef DEGENERATE_TRIS_WORKAROUND
|
||||||
|
/* Check if area is null. */
|
||||||
|
vec2 faces_area = vec2(len_sqr(n1), len_sqr(n2));
|
||||||
|
bvec2 degen_faces = lessThan(abs(faces_area), vec2(DEGENERATE_TRIS_AREA_THRESHOLD));
|
||||||
|
|
||||||
|
/* Both triangles are degenerate, abort. */
|
||||||
|
if (all(degen_faces)) {
|
||||||
|
DISCARD_VERTEX
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec2 facing = vec2(dot(n1, lightDirection), dot(n2, lightDirection));
|
||||||
|
|
||||||
|
/* WATCH: maybe unpredictable in some cases. */
|
||||||
|
bool is_manifold = any(notEqual(vData[0].pos, vData[3].pos));
|
||||||
|
|
||||||
|
bvec2 backface = greaterThan(facing, vec2(0.0));
|
||||||
|
|
||||||
|
#ifdef DEGENERATE_TRIS_WORKAROUND
|
||||||
|
# ifndef DOUBLE_MANIFOLD
|
||||||
|
/* If the mesh is known to be manifold and we don't use double count,
|
||||||
|
* only create an quad if the we encounter a facing geom. */
|
||||||
|
if ((degen_faces.x && backface.y) || (degen_faces.y && backface.x)) {
|
||||||
|
DISCARD_VERTEX
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* If one of the 2 triangles is degenerate, replace edge by a non-manifold one. */
|
||||||
|
backface.x = (degen_faces.x) ? !backface.y : backface.x;
|
||||||
|
backface.y = (degen_faces.y) ? !backface.x : backface.y;
|
||||||
|
is_manifold = (any(degen_faces)) ? false : is_manifold;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If both faces face the same direction it's not an outline edge. */
|
||||||
|
if (backface.x == backface.y) {
|
||||||
|
DISCARD_VERTEX
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output correct output vertex depending on */
|
||||||
|
if (output_vertex_id < 6) {
|
||||||
|
/* Always output if first 6 vertices. */
|
||||||
|
extrude_edge(backface.x, output_vertex_id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#ifdef DOUBLE_MANIFOLD
|
||||||
|
/* If part of double manifold, only output this vertex if correctly contributing */
|
||||||
|
if (is_manifold) {
|
||||||
|
extrude_edge(backface.x, output_vertex_id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DISCARD_VERTEX
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
DISCARD_VERTEX
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
@@ -75,9 +75,9 @@ void ShaderCreateInfo::finalize()
|
|||||||
if (info.early_fragment_test_) {
|
if (info.early_fragment_test_) {
|
||||||
early_fragment_test_ = true;
|
early_fragment_test_ = true;
|
||||||
}
|
}
|
||||||
/* Override depth-write with additional info if this specifies a writing mode
|
/* Modify depth write if has been changed from default.
|
||||||
* other than the default. */
|
* `UNCHANGED` implies gl_FragDepth is not used at all. */
|
||||||
if (info.depth_write_ != DepthWrite::NONE) {
|
if (info.depth_write_ != DepthWrite::UNCHANGED) {
|
||||||
depth_write_ = info.depth_write_;
|
depth_write_ = info.depth_write_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,6 +343,13 @@ void gpu_shader_create_info_init()
|
|||||||
overlay_motion_path_line = overlay_motion_path_line_no_geom;
|
overlay_motion_path_line = overlay_motion_path_line_no_geom;
|
||||||
overlay_motion_path_line_clipped = overlay_motion_path_line_clipped_no_geom;
|
overlay_motion_path_line_clipped = overlay_motion_path_line_clipped_no_geom;
|
||||||
|
|
||||||
|
/* Workbench shadows.
|
||||||
|
* Note: Updates additional-info used by workbench shadow permutations.
|
||||||
|
* Must be prepared prior to permutation preparation. */
|
||||||
|
workbench_shadow_manifold = workbench_shadow_manifold_no_geom;
|
||||||
|
workbench_shadow_no_manifold = workbench_shadow_no_manifold_no_geom;
|
||||||
|
workbench_shadow_caps = workbench_shadow_caps_no_geom;
|
||||||
|
|
||||||
/* Conservative rasterization. */
|
/* Conservative rasterization. */
|
||||||
basic_depth_mesh_conservative = basic_depth_mesh_conservative_no_geom;
|
basic_depth_mesh_conservative = basic_depth_mesh_conservative_no_geom;
|
||||||
basic_depth_mesh_conservative_clipped = basic_depth_mesh_conservative_no_geom_clipped;
|
basic_depth_mesh_conservative_clipped = basic_depth_mesh_conservative_no_geom_clipped;
|
||||||
|
@@ -189,8 +189,8 @@ ENUM_OPERATORS(BuiltinBits, BuiltinBits::USE_DEBUG_PRINT);
|
|||||||
* https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_conservative_depth.txt
|
* https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_conservative_depth.txt
|
||||||
*/
|
*/
|
||||||
enum class DepthWrite {
|
enum class DepthWrite {
|
||||||
/* NONE specified as default to indicate gl_FragDepth is not used. */
|
/* UNCHANGED specified as default to indicate gl_FragDepth is not used. */
|
||||||
NONE = 0,
|
UNCHANGED = 0,
|
||||||
ANY,
|
ANY,
|
||||||
GREATER,
|
GREATER,
|
||||||
LESS,
|
LESS,
|
||||||
@@ -344,7 +344,7 @@ struct ShaderCreateInfo {
|
|||||||
/** If true, force the use of the GL shader introspection for resource location. */
|
/** If true, force the use of the GL shader introspection for resource location. */
|
||||||
bool legacy_resource_location_ = false;
|
bool legacy_resource_location_ = false;
|
||||||
/** Allow optimization when fragment shader writes to `gl_FragDepth`. */
|
/** Allow optimization when fragment shader writes to `gl_FragDepth`. */
|
||||||
DepthWrite depth_write_ = DepthWrite::NONE;
|
DepthWrite depth_write_ = DepthWrite::UNCHANGED;
|
||||||
/** GPU Backend compatibility flag. Temporary requirement until Metal enablement is fully
|
/** GPU Backend compatibility flag. Temporary requirement until Metal enablement is fully
|
||||||
* complete. */
|
* complete. */
|
||||||
bool metal_backend_only_ = false;
|
bool metal_backend_only_ = false;
|
||||||
|
@@ -24,19 +24,19 @@ GPU_SHADER_CREATE_INFO(depth_2d_update_float)
|
|||||||
.metal_backend_only(true)
|
.metal_backend_only(true)
|
||||||
.fragment_source("depth_2d_update_float_frag.glsl")
|
.fragment_source("depth_2d_update_float_frag.glsl")
|
||||||
.additional_info("depth_2d_update_info_base")
|
.additional_info("depth_2d_update_info_base")
|
||||||
// .do_static_compilation(true)
|
.do_static_compilation(true)
|
||||||
.depth_write(DepthWrite::ANY);
|
.depth_write(DepthWrite::ANY);
|
||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(depth_2d_update_int24)
|
GPU_SHADER_CREATE_INFO(depth_2d_update_int24)
|
||||||
.metal_backend_only(true)
|
.metal_backend_only(true)
|
||||||
.fragment_source("depth_2d_update_int24_frag.glsl")
|
.fragment_source("depth_2d_update_int24_frag.glsl")
|
||||||
.additional_info("depth_2d_update_info_base")
|
.additional_info("depth_2d_update_info_base")
|
||||||
// .do_static_compilation(true)
|
.do_static_compilation(true)
|
||||||
.depth_write(DepthWrite::ANY);
|
.depth_write(DepthWrite::ANY);
|
||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(depth_2d_update_int32)
|
GPU_SHADER_CREATE_INFO(depth_2d_update_int32)
|
||||||
.metal_backend_only(true)
|
.metal_backend_only(true)
|
||||||
.fragment_source("depth_2d_update_int32_frag.glsl")
|
.fragment_source("depth_2d_update_int32_frag.glsl")
|
||||||
.additional_info("depth_2d_update_info_base")
|
.additional_info("depth_2d_update_info_base")
|
||||||
// .do_static_compilation(true)
|
.do_static_compilation(true)
|
||||||
.depth_write(DepthWrite::ANY);
|
.depth_write(DepthWrite::ANY);
|
||||||
|
@@ -472,21 +472,6 @@ id<MTLRenderCommandEncoder> MTLBatch::bind(uint v_first, uint v_count, uint i_fi
|
|||||||
this->elem ? @"(indexed)" : @"",
|
this->elem ? @"(indexed)" : @"",
|
||||||
active_shader_->get_interface()->get_name()]];
|
active_shader_->get_interface()->get_name()]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure Context Render Pipeline State is fully setup and ready to execute the draw. */
|
|
||||||
MTLPrimitiveType mtl_prim_type = gpu_prim_type_to_metal(this->prim_type);
|
|
||||||
if (!ctx->ensure_render_pipeline_state(mtl_prim_type)) {
|
|
||||||
printf("FAILED TO ENSURE RENDER PIPELINE STATE");
|
|
||||||
BLI_assert(false);
|
|
||||||
|
|
||||||
if (G.debug & G_DEBUG_GPU) {
|
|
||||||
[rec popDebugGroup];
|
|
||||||
}
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Bind Vertex Buffers and Index Buffers **/
|
|
||||||
|
|
||||||
/* SSBO Vertex Fetch Buffer bindings. */
|
/* SSBO Vertex Fetch Buffer bindings. */
|
||||||
if (uses_ssbo_fetch) {
|
if (uses_ssbo_fetch) {
|
||||||
|
|
||||||
@@ -514,7 +499,7 @@ id<MTLRenderCommandEncoder> MTLBatch::bind(uint v_first, uint v_count, uint i_fi
|
|||||||
}
|
}
|
||||||
rps.bind_vertex_buffer(idx_buffer, 0, MTL_SSBO_VERTEX_FETCH_IBO_INDEX);
|
rps.bind_vertex_buffer(idx_buffer, 0, MTL_SSBO_VERTEX_FETCH_IBO_INDEX);
|
||||||
|
|
||||||
/* Ensure all attributes are set */
|
/* Ensure all attributes are set. */
|
||||||
active_shader_->ssbo_vertex_fetch_bind_attributes_end(rec);
|
active_shader_->ssbo_vertex_fetch_bind_attributes_end(rec);
|
||||||
|
|
||||||
/* Bind NULL Buffers for unused vertex data slots. */
|
/* Bind NULL Buffers for unused vertex data slots. */
|
||||||
@@ -529,7 +514,7 @@ id<MTLRenderCommandEncoder> MTLBatch::bind(uint v_first, uint v_count, uint i_fi
|
|||||||
/* Flag whether Indexed rendering is used or not. */
|
/* Flag whether Indexed rendering is used or not. */
|
||||||
int &uniform_ssbo_use_indexed = active_shader_->uni_ssbo_uses_indexed_rendering;
|
int &uniform_ssbo_use_indexed = active_shader_->uni_ssbo_uses_indexed_rendering;
|
||||||
BLI_assert(uniform_ssbo_use_indexed != -1);
|
BLI_assert(uniform_ssbo_use_indexed != -1);
|
||||||
int uses_indexed_rendering = (mtl_elem != NULL) ? 1 : 0;
|
int uses_indexed_rendering = (mtl_elem != nullptr) ? 1 : 0;
|
||||||
active_shader_->uniform_int(uniform_ssbo_use_indexed, 1, 1, &uses_indexed_rendering);
|
active_shader_->uniform_int(uniform_ssbo_use_indexed, 1, 1, &uses_indexed_rendering);
|
||||||
|
|
||||||
/* Set SSBO-fetch-mode status uniforms. */
|
/* Set SSBO-fetch-mode status uniforms. */
|
||||||
@@ -547,6 +532,19 @@ id<MTLRenderCommandEncoder> MTLBatch::bind(uint v_first, uint v_count, uint i_fi
|
|||||||
(const int *)(&v_count));
|
(const int *)(&v_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ensure Context Render Pipeline State is fully setup and ready to execute the draw.
|
||||||
|
* This should happen after all other final rendeirng setup is complete. */
|
||||||
|
MTLPrimitiveType mtl_prim_type = gpu_prim_type_to_metal(this->prim_type);
|
||||||
|
if (!ctx->ensure_render_pipeline_state(mtl_prim_type)) {
|
||||||
|
printf("FAILED TO ENSURE RENDER PIPELINE STATE");
|
||||||
|
BLI_assert(false);
|
||||||
|
|
||||||
|
if (G.debug & G_DEBUG_GPU) {
|
||||||
|
[rec popDebugGroup];
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
/* Bind Vertex Buffers. */
|
/* Bind Vertex Buffers. */
|
||||||
for (int i = 0; i < num_buffers; i++) {
|
for (int i = 0; i < num_buffers; i++) {
|
||||||
MTLVertBuf *buf_at_index = buffers[i];
|
MTLVertBuf *buf_at_index = buffers[i];
|
||||||
@@ -755,6 +753,10 @@ void MTLBatch::draw_advanced(int v_first, int v_count, int i_first, int i_count)
|
|||||||
mtl_vertex_count_fits_primitive_type(
|
mtl_vertex_count_fits_primitive_type(
|
||||||
output_num_verts, active_shader_->get_ssbo_vertex_fetch_output_prim_type()),
|
output_num_verts, active_shader_->get_ssbo_vertex_fetch_output_prim_type()),
|
||||||
"Output Vertex count is not compatible with the requested output vertex primitive type");
|
"Output Vertex count is not compatible with the requested output vertex primitive type");
|
||||||
|
|
||||||
|
/* Set depth stencil state (requires knowledge of primitive type). */
|
||||||
|
ctx->ensure_depth_stencil_state(active_shader_->get_ssbo_vertex_fetch_output_prim_type());
|
||||||
|
|
||||||
[rec drawPrimitives:active_shader_->get_ssbo_vertex_fetch_output_prim_type()
|
[rec drawPrimitives:active_shader_->get_ssbo_vertex_fetch_output_prim_type()
|
||||||
vertexStart:0
|
vertexStart:0
|
||||||
vertexCount:output_num_verts
|
vertexCount:output_num_verts
|
||||||
|
@@ -675,7 +675,7 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info)
|
|||||||
|
|
||||||
/* NOTE(Metal): FragDepth output mode specified in create-info 'DepthWrite depth_write_'.
|
/* NOTE(Metal): FragDepth output mode specified in create-info 'DepthWrite depth_write_'.
|
||||||
* If parsing without create-info, manual extraction will be required. */
|
* If parsing without create-info, manual extraction will be required. */
|
||||||
msl_iface.uses_gl_FragDepth = (info->depth_write_ != DepthWrite::NONE) &&
|
msl_iface.uses_gl_FragDepth = (info->depth_write_ != DepthWrite::UNCHANGED) &&
|
||||||
shd_builder_->glsl_fragment_source_.find("gl_FragDepth") !=
|
shd_builder_->glsl_fragment_source_.find("gl_FragDepth") !=
|
||||||
std::string::npos;
|
std::string::npos;
|
||||||
msl_iface.depth_write = info->depth_write_;
|
msl_iface.depth_write = info->depth_write_;
|
||||||
|
@@ -282,27 +282,25 @@ void MTLStateManager::set_stencil_test(const eGPUStencilTest test, const eGPUSte
|
|||||||
context_, MTLStencilOperationKeep, MTLStencilOperationKeep, MTLStencilOperationReplace);
|
context_, MTLStencilOperationKeep, MTLStencilOperationKeep, MTLStencilOperationReplace);
|
||||||
break;
|
break;
|
||||||
case GPU_STENCIL_OP_COUNT_DEPTH_PASS:
|
case GPU_STENCIL_OP_COUNT_DEPTH_PASS:
|
||||||
/* Winding inversed due to flipped Y coordinate system in Metal. */
|
|
||||||
mtl_stencil_set_op_separate(context_,
|
mtl_stencil_set_op_separate(context_,
|
||||||
GPU_CULL_FRONT,
|
GPU_CULL_BACK,
|
||||||
MTLStencilOperationKeep,
|
MTLStencilOperationKeep,
|
||||||
MTLStencilOperationKeep,
|
MTLStencilOperationKeep,
|
||||||
MTLStencilOperationIncrementWrap);
|
MTLStencilOperationIncrementWrap);
|
||||||
mtl_stencil_set_op_separate(context_,
|
mtl_stencil_set_op_separate(context_,
|
||||||
GPU_CULL_BACK,
|
GPU_CULL_FRONT,
|
||||||
MTLStencilOperationKeep,
|
MTLStencilOperationKeep,
|
||||||
MTLStencilOperationKeep,
|
MTLStencilOperationKeep,
|
||||||
MTLStencilOperationDecrementWrap);
|
MTLStencilOperationDecrementWrap);
|
||||||
break;
|
break;
|
||||||
case GPU_STENCIL_OP_COUNT_DEPTH_FAIL:
|
case GPU_STENCIL_OP_COUNT_DEPTH_FAIL:
|
||||||
/* Winding inversed due to flipped Y coordinate system in Metal. */
|
|
||||||
mtl_stencil_set_op_separate(context_,
|
mtl_stencil_set_op_separate(context_,
|
||||||
GPU_CULL_FRONT,
|
GPU_CULL_BACK,
|
||||||
MTLStencilOperationKeep,
|
MTLStencilOperationKeep,
|
||||||
MTLStencilOperationDecrementWrap,
|
MTLStencilOperationDecrementWrap,
|
||||||
MTLStencilOperationKeep);
|
MTLStencilOperationKeep);
|
||||||
mtl_stencil_set_op_separate(context_,
|
mtl_stencil_set_op_separate(context_,
|
||||||
GPU_CULL_BACK,
|
GPU_CULL_FRONT,
|
||||||
MTLStencilOperationKeep,
|
MTLStencilOperationKeep,
|
||||||
MTLStencilOperationIncrementWrap,
|
MTLStencilOperationIncrementWrap,
|
||||||
MTLStencilOperationKeep);
|
MTLStencilOperationKeep);
|
||||||
|
Reference in New Issue
Block a user