Workbench Next: Workaround lack of texture views support #111402
|
@ -602,6 +602,7 @@ set(GLSL_SRC
|
|||
engines/workbench/shaders/workbench_effect_smaa_frag.glsl
|
||||
engines/workbench/shaders/workbench_effect_smaa_vert.glsl
|
||||
engines/workbench/shaders/workbench_effect_taa_frag.glsl
|
||||
engines/workbench/shaders/workbench_extract_stencil.glsl
|
||||
engines/workbench/shaders/workbench_image_lib.glsl
|
||||
engines/workbench/shaders/workbench_matcap_lib.glsl
|
||||
engines/workbench/shaders/workbench_material_lib.glsl
|
||||
|
|
|
@ -18,3 +18,9 @@ GPU_SHADER_CREATE_INFO(workbench_next_merge_depth)
|
|||
.additional_info("draw_fullscreen")
|
||||
.depth_write(DepthWrite::ANY)
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_extract_stencil)
|
||||
.fragment_out(0, Type::UINT, "out_stencil_value")
|
||||
.fragment_source("workbench_extract_stencil.glsl")
|
||||
.additional_info("draw_fullscreen")
|
||||
.do_static_compilation(true);
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
void main()
|
||||
{
|
||||
out_stencil_value = 0xFF;
|
||||
}
|
|
@ -254,7 +254,7 @@ void AntiAliasingPass::draw(Manager &manager,
|
|||
GPUTexture *color_tx)
|
||||
{
|
||||
auto draw_overlay_depth = [&](GPUTexture *target) {
|
||||
stencil_tx_ = resources.depth_tx.stencil_view();
|
||||
stencil_tx_ = resources.stencil_view.extract(manager, resources.depth_tx);
|
||||
overlay_depth_fb_.ensure(GPU_ATTACHMENT_TEXTURE(target));
|
||||
overlay_depth_fb_.bind();
|
||||
manager.submit(overlay_depth_ps_);
|
||||
|
|
|
@ -190,6 +190,8 @@ void OpaquePass::draw(Manager &manager,
|
|||
|
||||
bool needs_stencil_copy = shadow_pass && !gbuffer_in_front_ps_.is_empty();
|
||||
|
||||
Texture *depth_stencil_tx = nullptr;
|
||||
|
||||
if (needs_stencil_copy) {
|
||||
shadow_depth_stencil_tx.ensure_2d(GPU_DEPTH24_STENCIL8,
|
||||
resolution,
|
||||
|
@ -198,22 +200,24 @@ void OpaquePass::draw(Manager &manager,
|
|||
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW);
|
||||
GPU_texture_copy(shadow_depth_stencil_tx, resources.depth_tx);
|
||||
|
||||
deferred_ps_stencil_tx = shadow_depth_stencil_tx.stencil_view();
|
||||
depth_stencil_tx = shadow_depth_stencil_tx.ptr();
|
||||
|
||||
opaque_fb.ensure(GPU_ATTACHMENT_TEXTURE(deferred_ps_stencil_tx));
|
||||
opaque_fb.ensure(GPU_ATTACHMENT_TEXTURE(*depth_stencil_tx));
|
||||
opaque_fb.bind();
|
||||
GPU_framebuffer_clear_stencil(opaque_fb, 0);
|
||||
}
|
||||
else {
|
||||
shadow_depth_stencil_tx.free();
|
||||
deferred_ps_stencil_tx = resources.depth_tx.stencil_view();
|
||||
depth_stencil_tx = resources.depth_tx.ptr();
|
||||
}
|
||||
|
||||
if (shadow_pass) {
|
||||
shadow_pass->draw(
|
||||
manager, view, resources, *deferred_ps_stencil_tx, !gbuffer_in_front_ps_.is_empty());
|
||||
manager, view, resources, **depth_stencil_tx, !gbuffer_in_front_ps_.is_empty());
|
||||
}
|
||||
|
||||
deferred_ps_stencil_tx = resources.stencil_view.extract(manager, *depth_stencil_tx);
|
||||
|
||||
opaque_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(resources.color_tx));
|
||||
opaque_fb.bind();
|
||||
manager.submit(deferred_ps_, view);
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "workbench_enums.hh"
|
||||
#include "workbench_shader_shared.h"
|
||||
|
||||
#include "GPU_capabilities.h"
|
||||
|
||||
extern "C" DrawEngineType draw_engine_workbench_next;
|
||||
|
||||
namespace blender::workbench {
|
||||
|
@ -137,6 +139,56 @@ class CavityEffect {
|
|||
void load_samples_buf(int ssao_samples);
|
||||
};
|
||||
|
||||
/* Used as a temporary workaround for the lack of texture views support on Windows ARM. */
|
||||
class StencilViewWorkaround {
|
||||
private:
|
||||
Texture stencil_copy_tx_ = "stencil_copy_tx";
|
||||
GPUShader *stencil_copy_sh_ = nullptr;
|
||||
|
||||
public:
|
||||
StencilViewWorkaround()
|
||||
{
|
||||
stencil_copy_sh_ = GPU_shader_create_from_info_name("workbench_extract_stencil");
|
||||
}
|
||||
~StencilViewWorkaround()
|
||||
{
|
||||
DRW_SHADER_FREE_SAFE(stencil_copy_sh_);
|
||||
}
|
||||
|
||||
/** WARNING: Should only be called at render time.
|
||||
* When the workaround path is active,
|
||||
* the returned texture won't stay in sync with the stencil_src,
|
||||
* and will only be valid until the next time this function is called.
|
||||
* Note that the output is a binary mask,
|
||||
* any stencil value that is not 0x00 will be rendered as 0xFF. */
|
||||
GPUTexture *extract(Manager &manager, Texture &stencil_src)
|
||||
{
|
||||
if (GPU_texture_view_support()) {
|
||||
return stencil_src.stencil_view();
|
||||
}
|
||||
|
||||
int2 extent = int2(stencil_src.width(), stencil_src.height());
|
||||
stencil_copy_tx_.ensure_2d(
|
||||
GPU_R8UI, extent, GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_SHADER_READ);
|
||||
|
||||
PassSimple ps("Stencil View Workaround");
|
||||
ps.init();
|
||||
ps.clear_color(float4(0));
|
||||
ps.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_NEQUAL);
|
||||
ps.state_stencil(0x00, 0x00, 0xFF);
|
||||
ps.shader_set(stencil_copy_sh_);
|
||||
ps.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
|
||||
Framebuffer fb;
|
||||
fb.ensure(GPU_ATTACHMENT_TEXTURE(stencil_src), GPU_ATTACHMENT_TEXTURE(stencil_copy_tx_));
|
||||
fb.bind();
|
||||
|
||||
manager.submit(ps);
|
||||
|
||||
return stencil_copy_tx_;
|
||||
}
|
||||
};
|
||||
|
||||
struct SceneResources {
|
||||
static const int jitter_tx_size = 64;
|
||||
|
||||
|
@ -158,6 +210,8 @@ struct SceneResources {
|
|||
|
||||
CavityEffect cavity = {};
|
||||
|
||||
StencilViewWorkaround stencil_view;
|
||||
|
||||
void init(const SceneState &scene_state);
|
||||
void load_jitter_tx(int total_samples);
|
||||
};
|
||||
|
|
|
@ -21,8 +21,6 @@ void VolumePass::sync(SceneResources &resources)
|
|||
dummy_shadow_tx_.ensure_3d(GPU_RGBA8, int3(1), GPU_TEXTURE_USAGE_SHADER_READ, float4(1));
|
||||
dummy_volume_tx_.ensure_3d(GPU_RGBA8, int3(1), GPU_TEXTURE_USAGE_SHADER_READ, float4(0));
|
||||
dummy_coba_tx_.ensure_1d(GPU_RGBA8, 1, GPU_TEXTURE_USAGE_SHADER_READ, float4(0));
|
||||
|
||||
stencil_tx_ = resources.depth_tx.stencil_view();
|
||||
}
|
||||
|
||||
void VolumePass::object_sync_volume(Manager &manager,
|
||||
|
@ -182,6 +180,9 @@ void VolumePass::draw(Manager &manager, View &view, SceneResources &resources)
|
|||
if (!active_) {
|
||||
return;
|
||||
}
|
||||
|
||||
stencil_tx_ = resources.stencil_view.extract(manager, resources.depth_tx);
|
||||
|
||||
fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(resources.color_tx));
|
||||
fb_.bind();
|
||||
manager.submit(ps_, view);
|
||||
|
|
|
@ -53,6 +53,7 @@ bool GPU_shader_storage_buffer_objects_support(void);
|
|||
bool GPU_shader_image_load_store_support(void);
|
||||
bool GPU_shader_draw_parameters_support(void);
|
||||
bool GPU_hdr_support(void);
|
||||
bool GPU_texture_view_support();
|
||||
|
||||
bool GPU_mem_stats_supported(void);
|
||||
void GPU_mem_stats_get(int *totalmem, int *freemem);
|
||||
|
|
|
@ -187,6 +187,11 @@ bool GPU_hdr_support()
|
|||
return GCaps.hdr_viewport_support;
|
||||
}
|
||||
|
||||
bool GPU_texture_view_support()
|
||||
{
|
||||
return GCaps.texture_view_support;
|
||||
}
|
||||
|
||||
int GPU_max_shader_storage_buffer_bindings()
|
||||
{
|
||||
return GCaps.max_shader_storage_buffer_bindings;
|
||||
|
|
|
@ -49,6 +49,7 @@ struct GPUCapabilities {
|
|||
bool shader_draw_parameters_support = false;
|
||||
bool transform_feedback_support = false;
|
||||
bool hdr_viewport_support = false;
|
||||
bool texture_view_support = true;
|
||||
|
||||
/* OpenGL related workarounds. */
|
||||
bool mip_render_workaround = false;
|
||||
|
|
|
@ -563,6 +563,8 @@ void GLBackend::capabilities_init()
|
|||
GCaps.shader_storage_buffer_objects_support = epoxy_has_gl_extension(
|
||||
"GL_ARB_shader_storage_buffer_object");
|
||||
GCaps.transform_feedback_support = true;
|
||||
GCaps.texture_view_support = epoxy_gl_version() >= 43 ||
|
||||
epoxy_has_gl_extension("GL_ARB_texture_view");
|
||||
|
||||
/* GL specific capabilities. */
|
||||
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &GCaps.max_texture_3d_size);
|
||||
|
|
Loading…
Reference in New Issue