diff --git a/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_data.inc b/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_data.inc index 22efc2476600913a5433211ff70168440d43e253..27d7c15e0cadc8aa8585b74ebfa987032eb74359 100644 --- a/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_data.inc +++ b/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_data.inc @@ -23,6 +23,7 @@ struct DualLayerReprojectionSubdivideParameters float subdivision_threshold; float interpupillary_distance; uint layer_offset; + uint cell_border; }; #endif \ No newline at end of file diff --git a/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_subdivide.comp b/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_subdivide.comp index bdb8c39f704bc6fa046d38bb8ad257e464d4c732..d731c53ab137a3aeeb007377a2125086b2b96dcb 100644 --- a/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_subdivide.comp +++ b/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_subdivide.comp @@ -34,20 +34,41 @@ float linear_depth(mat4 projection_matrix, float log_depth) void main() { - ivec2 coord = ivec2(gl_GlobalInvocationID.xy); - - float layer_depth = texelFetch(sampler_layer_depth, coord + ivec2(parameters.layer_offset, 0), 0).x; - float layer_linear_depth = linear_depth(transform.projection, layer_depth); - layer_integer_depth_min = 0xFFFFFFFF; layer_integer_depth_max = 0x0; barrier(); - uint layer_integer_depth = floatBitsToUint(-layer_linear_depth); + ivec2 cell_coord = ivec2(gl_WorkGroupID.xy); + ivec2 cell_size = ivec2(gl_WorkGroupSize.xy); + ivec2 local_coord = ivec2(gl_LocalInvocationID.xy); - atomicMin(layer_integer_depth_min, layer_integer_depth); - atomicMax(layer_integer_depth_max, layer_integer_depth); + // TODO: Improve access patern and distribute the work load better over warps of work group + for(int offset_x = local_coord.x - int(parameters.cell_border); offset_x < cell_size.x + int(parameters.cell_border); offset_x += cell_size.x) + { + for(int offset_y = local_coord.y - int(parameters.cell_border); offset_y < cell_size.y + int(parameters.cell_border); offset_y += cell_size.y) + { + ivec2 image_coord = cell_coord * cell_size + ivec2(offset_x, offset_y); + ivec2 image_size = ivec2(textureSize(sampler_layer_depth, 0).xy); + + if(image_coord.x < 0 || image_coord.x >= image_size.x) + { + continue; + } + + if(image_coord.y < 0 || image_coord.y >= image_size.y) + { + continue; + } + + float layer_depth = texelFetch(sampler_layer_depth, image_coord + ivec2(parameters.layer_offset, 0), 0).x; + float layer_linear_depth = linear_depth(transform.projection, layer_depth); + uint layer_integer_depth = floatBitsToUint(-layer_linear_depth); + + atomicMin(layer_integer_depth_min, layer_integer_depth); + atomicMax(layer_integer_depth_max, layer_integer_depth); + } + } barrier(); @@ -61,6 +82,8 @@ void main() if(layer_parallax_delta > parameters.subdivision_threshold) { + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + vec4 layer_encoded_depth = imageLoad(image_layer_encoded_depth, coord + ivec2(parameters.layer_offset, 0)); layer_encoded_depth.x = 1.0; diff --git a/src/strategy/dual_layer_reprojection.cpp b/src/strategy/dual_layer_reprojection.cpp index fc8d588d5964fea7e1dd784af7e89dfaeb158961..bd0f071135daa562f6792a2094aae01d4fd752de 100644 --- a/src/strategy/dual_layer_reprojection.cpp +++ b/src/strategy/dual_layer_reprojection.cpp @@ -203,6 +203,7 @@ bool DualLayerReprojection::on_interface() ImGui::SliderFloat("Layer Slope Threshold", &this->layer_slope_threshold, 0.0f, 2.0f); ImGui::SliderFloat("Reproject Slope Threshold", &this->reproject_slope_threshold, 0.0f, 1.0f); ImGui::SliderFloat("Subdivision Threshold", &this->subdivision_threshold, 0.0, 1.0f); + ImGui::SliderInt("Subdivide Cell Border", (int32_t*)&this->subdivide_cell_border, 0, 8); ImGui::SliderFloat("Debug Value", &this->debug_value, 0.0, 1.0f); ImGui::Checkbox("Wireframe", &this->wireframe); ImGui::Checkbox("Performance View", &this->performance_view); @@ -1189,6 +1190,7 @@ void DualLayerReprojection::process_layer_subdivide_pass(VkCommandBuffer command parameters.subdivision_threshold = this->subdivision_threshold; parameters.interpupillary_distance = this->get_headset()->get_interpupillary_distance(); parameters.layer_offset = 0; + parameters.cell_border = this->subdivide_cell_border; if (this->get_headset()->is_remote() && index == 1) { diff --git a/src/strategy/dual_layer_reprojection.hpp b/src/strategy/dual_layer_reprojection.hpp index 37584a01f8ce6090f368f7cbecf8d9cc670ca3b5..23a631657955cfb7123d712ceb211f595810ab54 100644 --- a/src/strategy/dual_layer_reprojection.hpp +++ b/src/strategy/dual_layer_reprojection.hpp @@ -87,6 +87,7 @@ private: float layer_slope_threshold = 0.0f; float reproject_slope_threshold = 0.05f; float subdivision_threshold = 0.01f; + uint32_t subdivide_cell_border = 0; float debug_value = 0.0f; bool wireframe = false; bool performance_view = false;