From 58563b0b1b4f343260b881e90f38ebe9072c22fc Mon Sep 17 00:00:00 2001 From: Hugo Amnov Date: Sun, 17 Feb 2019 16:50:26 +0100 Subject: [PATCH] FrameBuffer Read/Write access WIP --- examples/21-deferred/common.sh | 62 +++++++++++ examples/21-deferred/deferred.cpp | 99 ++++++++++++++---- examples/21-deferred/fs_deferred_clear_uav.sc | 17 +++ examples/21-deferred/fs_deferred_light.sc | 60 +---------- examples/21-deferred/fs_deferred_light_ta.sc | 60 +---------- examples/21-deferred/fs_deferred_light_uav.sc | 40 +++++++ .../shaders/dx11/fs_deferred_clear_uav.bin | Bin 0 -> 294 bytes .../shaders/dx11/fs_deferred_light_uav.bin | Bin 0 -> 1521 bytes .../shaders/glsl/fs_deferred_clear_uav.bin | Bin 0 -> 10862 bytes .../shaders/glsl/fs_deferred_light_uav.bin | Bin 0 -> 11539 bytes include/bgfx/defines.h | 1 + src/renderer_d3d11.cpp | 18 +++- src/renderer_d3d11.h | 3 + src/renderer_gl.cpp | 44 ++++++-- src/renderer_gl.h | 1 + 15 files changed, 258 insertions(+), 147 deletions(-) create mode 100644 examples/21-deferred/common.sh create mode 100644 examples/21-deferred/fs_deferred_clear_uav.sc create mode 100644 examples/21-deferred/fs_deferred_light_uav.sc create mode 100644 examples/runtime/shaders/dx11/fs_deferred_clear_uav.bin create mode 100644 examples/runtime/shaders/dx11/fs_deferred_light_uav.bin create mode 100644 examples/runtime/shaders/glsl/fs_deferred_clear_uav.bin create mode 100644 examples/runtime/shaders/glsl/fs_deferred_light_uav.bin diff --git a/examples/21-deferred/common.sh b/examples/21-deferred/common.sh new file mode 100644 index 000000000..03333aeeb --- /dev/null +++ b/examples/21-deferred/common.sh @@ -0,0 +1,62 @@ +/* + * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "../common/common.sh" + +vec2 blinn(vec3 _lightDir, vec3 _normal, vec3 _viewDir) +{ + float ndotl = dot(_normal, _lightDir); + vec3 reflected = _lightDir - 2.0*ndotl*_normal; // reflect(_lightDir, _normal); + float rdotv = dot(reflected, _viewDir); + return vec2(ndotl, rdotv); +} + +float fresnel(float _ndotl, float _bias, float _pow) +{ + float facing = (1.0 - _ndotl); + return max(_bias + (1.0 - _bias) * pow(facing, _pow), 0.0); +} + +vec4 lit(float _ndotl, float _rdotv, float _m) +{ + float diff = max(0.0, _ndotl); + float spec = step(0.0, _ndotl) * max(0.0, _rdotv * _m); + return vec4(1.0, diff, spec, 1.0); +} + +vec4 powRgba(vec4 _rgba, float _pow) +{ + vec4 result; + result.xyz = pow(_rgba.xyz, vec3_splat(_pow) ); + result.w = _rgba.w; + return result; +} + +vec3 calcLight(vec3 _wpos, vec3 _normal, vec3 _view, vec3 _lightPos, float _lightRadius, vec3 _lightRgb, float _lightInner) +{ + vec3 lp = _lightPos - _wpos; + float attn = 1.0 - smoothstep(_lightInner, 1.0, length(lp) / _lightRadius); + vec3 lightDir = normalize(lp); + vec2 bln = blinn(lightDir, _normal, _view); + vec4 lc = lit(bln.x, bln.y, 1.0); + vec3 rgb = _lightRgb * saturate(lc.y) * attn; + return rgb; +} + +float toClipSpaceDepth(float _depthTextureZ) +{ +#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL + return _depthTextureZ; +#else + return _depthTextureZ * 2.0 - 1.0; +#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL +} + +vec3 clipToWorld(mat4 _invViewProj, vec3 _clipPos) +{ + vec4 wpos = mul(_invViewProj, vec4(_clipPos, 1.0) ); + return wpos.xyz / wpos.w; +} + diff --git a/examples/21-deferred/deferred.cpp b/examples/21-deferred/deferred.cpp index 0ecbf287a..30933f6dd 100644 --- a/examples/21-deferred/deferred.cpp +++ b/examples/21-deferred/deferred.cpp @@ -282,6 +282,7 @@ public: m_lineProgram = loadProgram("vs_deferred_debug_line", "fs_deferred_debug_line"); m_useTArray = false; + m_useUav = false; if (0 != (BGFX_CAPS_TEXTURE_2D_ARRAY & bgfx::getCaps()->supported) ) { @@ -292,6 +293,17 @@ public: m_lightTaProgram = BGFX_INVALID_HANDLE; } + if(0 != (BGFX_CAPS_READ_WRITE_ATTACH & bgfx::getCaps()->supported)) + { + m_lightUavProgram = loadProgram("vs_deferred_light", "fs_deferred_light_uav"); + m_clearUavProgram = loadProgram("vs_deferred_light", "fs_deferred_clear_uav"); + } + else + { + m_lightUavProgram = BGFX_INVALID_HANDLE; + m_clearUavProgram = BGFX_INVALID_HANDLE; + } + // Load diffuse texture. m_textureColor = loadTexture("textures/fieldstone-rgba.dds"); @@ -423,6 +435,7 @@ public: || m_oldHeight != m_height || m_oldReset != m_reset || m_oldUseTArray != m_useTArray + || m_oldUseUav != m_useUav || !bgfx::isValid(m_gbuffer) ) { // Recreate variable size render targets when resolution changes. @@ -430,6 +443,7 @@ public: m_oldHeight = m_height; m_oldReset = m_reset; m_oldUseTArray = m_useTArray; + m_oldUseUav = m_useUav; if (bgfx::isValid(m_gbuffer) ) { @@ -440,7 +454,6 @@ public: } const uint64_t tsFlags = 0 - | BGFX_TEXTURE_RT | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT @@ -448,33 +461,48 @@ public: | BGFX_SAMPLER_V_CLAMP ; - bgfx::Attachment at[3]; + bgfx::Attachment gbufferAt[3]; - if (m_useTArray) + if(m_useTArray) { - m_gbufferTex[0] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 2, bgfx::TextureFormat::BGRA8, tsFlags); - at[0].init(m_gbufferTex[0], bgfx::Access::Write, 0); - at[1].init(m_gbufferTex[0], bgfx::Access::Write, 1); + m_gbufferTex[0] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 2, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT | tsFlags); + gbufferAt[0].init(m_gbufferTex[0], bgfx::Access::Write, 0); + gbufferAt[1].init(m_gbufferTex[0], bgfx::Access::Write, 1); } else { - m_gbufferTex[0] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::BGRA8, tsFlags); - m_gbufferTex[1] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::BGRA8, tsFlags); - at[0].init(m_gbufferTex[0]); - at[1].init(m_gbufferTex[1]); + m_gbufferTex[0] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT | tsFlags); + m_gbufferTex[1] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT | tsFlags); + gbufferAt[0].init(m_gbufferTex[0]); + gbufferAt[1].init(m_gbufferTex[1]); } - m_gbufferTex[2] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::D24S8, tsFlags); - at[2].init(m_gbufferTex[2]); + m_gbufferTex[2] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::D24S8, BGFX_TEXTURE_RT | tsFlags); + gbufferAt[2].init(m_gbufferTex[2]); - m_gbuffer = bgfx::createFrameBuffer(BX_COUNTOF(at), at, true); + m_gbuffer = bgfx::createFrameBuffer(BX_COUNTOF(gbufferAt), gbufferAt, true); - if (bgfx::isValid(m_lightBuffer) ) + if(bgfx::isValid(m_lightBuffer)) { bgfx::destroy(m_lightBuffer); } - m_lightBuffer = bgfx::createFrameBuffer(uint16_t(m_width), uint16_t(m_height), bgfx::TextureFormat::BGRA8, tsFlags); + if(m_useUav) + { + bgfx::Attachment lightAt[2]; + + bgfx::TextureHandle target = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT | tsFlags); + m_lightBufferTex = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_COMPUTE_WRITE | tsFlags); + lightAt[0].init(target); + lightAt[1].init(m_lightBufferTex, bgfx::Access::ReadWrite); + + m_lightBuffer = bgfx::createFrameBuffer(BX_COUNTOF(lightAt), lightAt, true); + } + else + { + m_lightBufferTex = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT | tsFlags); + m_lightBuffer = bgfx::createFrameBuffer(1, &m_lightBufferTex, true); + } } ImGui::SetNextWindowPos( @@ -503,6 +531,15 @@ public: ImGui::Text("Texture array frame buffer is not supported."); } + if(bgfx::isValid(m_lightUavProgram)) + { + ImGui::Checkbox("Use UAV frame buffer attachment.", &m_useUav); + } + else + { + ImGui::Text("UAV frame buffer attachment is not supported."); + } + ImGui::Checkbox("Animate mesh.", &m_animateMesh); ImGui::SliderFloat("Anim.speed", &m_lightAnimationSpeed, 0.0f, 0.4f); @@ -596,6 +633,17 @@ public: } } + // Clear UAV texture + if(m_useUav) + { + screenSpaceQuad((float)m_width, (float)m_height, s_texelHalf, m_caps->originBottomLeft); + bgfx::setState(0 + | BGFX_STATE_WRITE_RGB + | BGFX_STATE_WRITE_A + ); + bgfx::submit(RENDER_PASS_LIGHT_ID, m_clearUavProgram); + } + // Draw lights into light buffer. for (int32_t light = 0; light < m_numLights; ++light) { @@ -717,17 +765,18 @@ public: | BGFX_STATE_BLEND_ADD ); screenSpaceQuad( (float)m_width, (float)m_height, s_texelHalf, m_caps->originBottomLeft); - bgfx::submit(RENDER_PASS_LIGHT_ID - , bgfx::isValid(m_lightTaProgram) && m_useTArray - ? m_lightTaProgram - : m_lightProgram - ); + if(bgfx::isValid(m_lightTaProgram) && m_useTArray) + bgfx::submit(RENDER_PASS_LIGHT_ID, m_lightTaProgram); + else if(bgfx::isValid(m_lightUavProgram) && m_useUav) + bgfx::submit(RENDER_PASS_LIGHT_ID, m_lightUavProgram); + else + bgfx::submit(RENDER_PASS_LIGHT_ID, m_lightProgram); } } // Combine color and light buffers. - bgfx::setTexture(0, s_albedo, bgfx::getTexture(m_gbuffer, 0) ); - bgfx::setTexture(1, s_light, bgfx::getTexture(m_lightBuffer, 0) ); + bgfx::setTexture(0, s_albedo, m_gbufferTex[0]); + bgfx::setTexture(1, s_light, m_lightBufferTex); bgfx::setState(0 | BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A @@ -788,6 +837,8 @@ public: bgfx::ProgramHandle m_geomProgram; bgfx::ProgramHandle m_lightProgram; bgfx::ProgramHandle m_lightTaProgram; + bgfx::ProgramHandle m_lightUavProgram; + bgfx::ProgramHandle m_clearUavProgram; bgfx::ProgramHandle m_combineProgram; bgfx::ProgramHandle m_debugProgram; bgfx::ProgramHandle m_lineProgram; @@ -795,6 +846,7 @@ public: bgfx::TextureHandle m_textureNormal; bgfx::TextureHandle m_gbufferTex[3]; + bgfx::TextureHandle m_lightBufferTex; bgfx::FrameBufferHandle m_gbuffer; bgfx::FrameBufferHandle m_lightBuffer; @@ -810,6 +862,9 @@ public: bool m_useTArray; bool m_oldUseTArray; + bool m_useUav; + bool m_oldUseUav; + int32_t m_scrollArea; int32_t m_numLights; float m_lightAnimationSpeed; diff --git a/examples/21-deferred/fs_deferred_clear_uav.sc b/examples/21-deferred/fs_deferred_clear_uav.sc new file mode 100644 index 000000000..c7d013f3e --- /dev/null +++ b/examples/21-deferred/fs_deferred_clear_uav.sc @@ -0,0 +1,17 @@ +$input v_texcoord0 + +/* + * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "common.sh" +#include + +IMAGE2D_RW(s_lights, rgba8, 1); + +void main() +{ + ivec2 coord = ivec2(gl_FragCoord.xy); + imageStore(s_lights, coord, vec4(0.0, 0.0, 0.0, 0.0)); +} diff --git a/examples/21-deferred/fs_deferred_light.sc b/examples/21-deferred/fs_deferred_light.sc index b727f2a6b..4857c663a 100644 --- a/examples/21-deferred/fs_deferred_light.sc +++ b/examples/21-deferred/fs_deferred_light.sc @@ -5,7 +5,7 @@ $input v_texcoord0 * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause */ -#include "../common/common.sh" +#include "common.sh" SAMPLER2D(s_normal, 0); SAMPLER2D(s_depth, 1); @@ -14,61 +14,6 @@ uniform vec4 u_lightPosRadius[1]; uniform vec4 u_lightRgbInnerR[1]; uniform mat4 u_mtx; -vec2 blinn(vec3 _lightDir, vec3 _normal, vec3 _viewDir) -{ - float ndotl = dot(_normal, _lightDir); - vec3 reflected = _lightDir - 2.0*ndotl*_normal; // reflect(_lightDir, _normal); - float rdotv = dot(reflected, _viewDir); - return vec2(ndotl, rdotv); -} - -float fresnel(float _ndotl, float _bias, float _pow) -{ - float facing = (1.0 - _ndotl); - return max(_bias + (1.0 - _bias) * pow(facing, _pow), 0.0); -} - -vec4 lit(float _ndotl, float _rdotv, float _m) -{ - float diff = max(0.0, _ndotl); - float spec = step(0.0, _ndotl) * max(0.0, _rdotv * _m); - return vec4(1.0, diff, spec, 1.0); -} - -vec4 powRgba(vec4 _rgba, float _pow) -{ - vec4 result; - result.xyz = pow(_rgba.xyz, vec3_splat(_pow) ); - result.w = _rgba.w; - return result; -} - -vec3 calcLight(int _idx, vec3 _wpos, vec3 _normal, vec3 _view) -{ - vec3 lp = u_lightPosRadius[_idx].xyz - _wpos; - float attn = 1.0 - smoothstep(u_lightRgbInnerR[_idx].w, 1.0, length(lp) / u_lightPosRadius[_idx].w); - vec3 lightDir = normalize(lp); - vec2 bln = blinn(lightDir, _normal, _view); - vec4 lc = lit(bln.x, bln.y, 1.0); - vec3 rgb = u_lightRgbInnerR[_idx].xyz * saturate(lc.y) * attn; - return rgb; -} - -float toClipSpaceDepth(float _depthTextureZ) -{ -#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL - return _depthTextureZ; -#else - return _depthTextureZ * 2.0 - 1.0; -#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL -} - -vec3 clipToWorld(mat4 _invViewProj, vec3 _clipPos) -{ - vec4 wpos = mul(_invViewProj, vec4(_clipPos, 1.0) ); - return wpos.xyz / wpos.w; -} - void main() { vec3 normal = decodeNormalUint(texture2D(s_normal, v_texcoord0).xyz); @@ -84,8 +29,7 @@ void main() vec3 view = mul(u_view, vec4(wpos, 0.0) ).xyz; view = -normalize(view); - vec3 lightColor; - lightColor = calcLight(0, wpos, normal, view); + vec3 lightColor = calcLight(wpos, normal, view, u_lightPosRadius[0].xyz, u_lightPosRadius[0].w, u_lightRgbInnerR[0].xyz, u_lightRgbInnerR[0].w); gl_FragColor.xyz = toGamma(lightColor.xyz); gl_FragColor.w = 1.0; } diff --git a/examples/21-deferred/fs_deferred_light_ta.sc b/examples/21-deferred/fs_deferred_light_ta.sc index 91180c0d0..9313b655a 100644 --- a/examples/21-deferred/fs_deferred_light_ta.sc +++ b/examples/21-deferred/fs_deferred_light_ta.sc @@ -5,7 +5,7 @@ $input v_texcoord0 * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause */ -#include "../common/common.sh" +#include "common.sh" SAMPLER2DARRAY(s_normal, 0); SAMPLER2D(s_depth, 1); @@ -14,61 +14,6 @@ uniform vec4 u_lightPosRadius[1]; uniform vec4 u_lightRgbInnerR[1]; uniform mat4 u_mtx; -vec2 blinn(vec3 _lightDir, vec3 _normal, vec3 _viewDir) -{ - float ndotl = dot(_normal, _lightDir); - vec3 reflected = _lightDir - 2.0*ndotl*_normal; // reflect(_lightDir, _normal); - float rdotv = dot(reflected, _viewDir); - return vec2(ndotl, rdotv); -} - -float fresnel(float _ndotl, float _bias, float _pow) -{ - float facing = (1.0 - _ndotl); - return max(_bias + (1.0 - _bias) * pow(facing, _pow), 0.0); -} - -vec4 lit(float _ndotl, float _rdotv, float _m) -{ - float diff = max(0.0, _ndotl); - float spec = step(0.0, _ndotl) * max(0.0, _rdotv * _m); - return vec4(1.0, diff, spec, 1.0); -} - -vec4 powRgba(vec4 _rgba, float _pow) -{ - vec4 result; - result.xyz = pow(_rgba.xyz, vec3_splat(_pow) ); - result.w = _rgba.w; - return result; -} - -vec3 calcLight(int _idx, vec3 _wpos, vec3 _normal, vec3 _view) -{ - vec3 lp = u_lightPosRadius[_idx].xyz - _wpos; - float attn = 1.0 - smoothstep(u_lightRgbInnerR[_idx].w, 1.0, length(lp) / u_lightPosRadius[_idx].w); - vec3 lightDir = normalize(lp); - vec2 bln = blinn(lightDir, _normal, _view); - vec4 lc = lit(bln.x, bln.y, 1.0); - vec3 rgb = u_lightRgbInnerR[_idx].xyz * saturate(lc.y) * attn; - return rgb; -} - -float toClipSpaceDepth(float _depthTextureZ) -{ -#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL - return _depthTextureZ; -#else - return _depthTextureZ * 2.0 - 1.0; -#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL -} - -vec3 clipToWorld(mat4 _invViewProj, vec3 _clipPos) -{ - vec4 wpos = mul(_invViewProj, vec4(_clipPos, 1.0) ); - return wpos.xyz / wpos.w; -} - void main() { vec3 normal = decodeNormalUint(texture2DArray(s_normal, vec3(v_texcoord0, 1.0) ).xyz); @@ -84,8 +29,7 @@ void main() vec3 view = mul(u_view, vec4(wpos, 0.0) ).xyz; view = -normalize(view); - vec3 lightColor; - lightColor = calcLight(0, wpos, normal, view); + vec3 lightColor = calcLight(wpos, normal, view, u_lightPosRadius[0].xyz, u_lightPosRadius[0].w, u_lightRgbInnerR[0].xyz, u_lightRgbInnerR[0].w); gl_FragColor.xyz = toGamma(lightColor.xyz); gl_FragColor.w = 1.0; } diff --git a/examples/21-deferred/fs_deferred_light_uav.sc b/examples/21-deferred/fs_deferred_light_uav.sc new file mode 100644 index 000000000..a1148cec1 --- /dev/null +++ b/examples/21-deferred/fs_deferred_light_uav.sc @@ -0,0 +1,40 @@ +$input v_texcoord0 + +/* + * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "common.sh" +#include + +SAMPLER2D(s_normal, 0); +SAMPLER2D(s_depth, 1); + +IMAGE2D_RW(s_lights, rgba8, 1); + +uniform vec4 u_lightPosRadius[1]; +uniform vec4 u_lightRgbInnerR[1]; +uniform mat4 u_mtx; + +void main() +{ + vec3 normal = decodeNormalUint(texture2D(s_normal, v_texcoord0).xyz); + float deviceDepth = texture2D(s_depth, v_texcoord0).x; + float depth = toClipSpaceDepth(deviceDepth); + + vec3 clip = vec3(v_texcoord0 * 2.0 - 1.0, depth); +#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL + clip.y = -clip.y; +#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL + vec3 wpos = clipToWorld(u_mtx, clip); + + vec3 view = mul(u_view, vec4(wpos, 0.0) ).xyz; + view = -normalize(view); + + ivec2 coord = ivec2(gl_FragCoord.xy); + + vec3 lightColor = calcLight(wpos, normal, view, u_lightPosRadius[0].xyz, u_lightPosRadius[0].w, u_lightRgbInnerR[0].xyz, u_lightRgbInnerR[0].w); + vec4 color = imageLoad(s_lights, coord); + imageStore(s_lights, coord, color + vec4(toGamma(lightColor.xyz), 1.0)); +} diff --git a/examples/runtime/shaders/dx11/fs_deferred_clear_uav.bin b/examples/runtime/shaders/dx11/fs_deferred_clear_uav.bin new file mode 100644 index 0000000000000000000000000000000000000000..0cdabef5fc6185a301bbc80d08fbc8ab2820d71e GIT binary patch literal 294 zcmZ<@_F&7Gv$J6U0|7<`2A2pY=a~O*WS@L^e&*n&iK`{7+5Q5B89;K(Kw1ZgTYz{9 z5PJr@`vm}LCLrbjVhbP!0g!r-S`gp|GF%``FbNWe$p?qU2lxkjhIsn>F@(5AIQ#nt zxiG9=z1kmWF33C(0MWr7t`Q|b8f2F&5NB~PFwT)+U}1P52sTSlkbxmZfq}(HKmaHU sF+T(7ERa3Y3=FKF7$D+qq7Zrs0|VD5s9rZdh!~RtP%#>?gBZmC0I;bfT>t<8 literal 0 HcmV?d00001 diff --git a/examples/runtime/shaders/dx11/fs_deferred_light_uav.bin b/examples/runtime/shaders/dx11/fs_deferred_light_uav.bin new file mode 100644 index 0000000000000000000000000000000000000000..6991d11202bff365ed4ac5752796d04726c4dcb8 GIT binary patch literal 1521 zcmZuxy=zlZ6hH4ZX+DPbC0I}d&417kP)dhYpV7?|0w5Ng8|Lydg zd+kBF+plc5_J{qXC1Q=umAxIW)7kA+l9mH=c-S}`Jh>z(2}!iy=yZFB+Xrct5$QKt zyGMg|+OiP%JS*ovue2eX#d^L}suW~28kJC&^+=S}^LHahRAU&iD|fxT9noay8FE&Znn)l(uN(gIQ$Cx~av zjw5qCQ*UEb;&2u3a3(>FyA;TGA}>!w{CpuK^fCVHqK^3;)XxBp41C1P)iv!L4kG*| zE3$JG{-=PcD{Nz|OZ>LNj(;0c)zKKxj{0%NOxvl?8{0yVUle(D!d`1jlGHU#Kkn0@ zcVfvIE~-fkSd(|UsL4A((ed5dX5I&@A`2psp6SC5a{d4xog16-O=dezv92N@89AQG zcXb`?SJ=$4s$=fKX5x(vJw#`1tA0w~phWBfzv_ox;(;CiZw`aSG_IUS;iKP~xGHJ} zlDjaD!5oaWbNCVAuVJyNjdy`NA>yPY!g+}uF;MqtEYM$+b?FiJwP ze{K3b%s!dDSOx?J3)uW;n2xw0Cq89YHqN>H@mJO`!sH5eXg2QV)Lt395E?l{U&NRH e2P1jcd;0YEg+7vr$zr9du9sHdI`hGkru+jmqL^U- literal 0 HcmV?d00001 diff --git a/examples/runtime/shaders/glsl/fs_deferred_clear_uav.bin b/examples/runtime/shaders/glsl/fs_deferred_clear_uav.bin new file mode 100644 index 0000000000000000000000000000000000000000..38ddde3e00fe5670adc219ba8a4e6da378755d8d GIT binary patch literal 10862 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 literal 0 HcmV?d00001 diff --git a/examples/runtime/shaders/glsl/fs_deferred_light_uav.bin b/examples/runtime/shaders/glsl/fs_deferred_light_uav.bin new file mode 100644 index 0000000000000000000000000000000000000000..ddee28a5b3ce853518d045aadb79057e94c5cd17 GIT binary patch literal 11539 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 literal 0 HcmV?d00001 diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h index 3e1f01014..0ab8bea6a 100644 --- a/include/bgfx/defines.h +++ b/include/bgfx/defines.h @@ -502,6 +502,7 @@ #define BGFX_CAPS_VERTEX_ATTRIB_HALF UINT64_C(0x0000000001000000) //!< Vertex attribute half-float is supported. #define BGFX_CAPS_VERTEX_ATTRIB_UINT10 UINT64_C(0x0000000002000000) //!< Vertex attribute 10_10_10_2 is supported. #define BGFX_CAPS_VERTEX_ID UINT64_C(0x0000000004000000) //!< Rendering with VertexID only is supported. +#define BGFX_CAPS_READ_WRITE_ATTACH UINT64_C(0x0000000008000000) //!< Read/Write frame buffer attachments are supported. /// #define BGFX_CAPS_FORMAT_TEXTURE_NONE UINT16_C(0x0000) //!< Texture format is not supported. diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index dc0cda792..a6f797ed3 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -391,10 +391,12 @@ namespace bgfx { namespace d3d11 void clear() { + bx::memSet(m_uav, 0, sizeof(m_uav)); bx::memSet(m_srv, 0, sizeof(m_srv) ); bx::memSet(m_sampler, 0, sizeof(m_sampler) ); } + ID3D11UnorderedAccessView* m_uav[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; ID3D11ShaderResourceView* m_srv[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; ID3D11SamplerState* m_sampler[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; }; @@ -1178,6 +1180,9 @@ namespace bgfx { namespace d3d11 : 0) | BGFX_CAPS_TEXTURE_2D_ARRAY | BGFX_CAPS_TEXTURE_CUBE_ARRAY + | ((m_featureLevel >= D3D_FEATURE_LEVEL_11_1) + ? BGFX_CAPS_READ_WRITE_ATTACH + : 0) ); m_timerQuerySupport = m_featureLevel >= D3D_FEATURE_LEVEL_10_0; @@ -2503,7 +2508,7 @@ namespace bgfx { namespace d3d11 m_currentColor = m_backBufferColor; m_currentDepthStencil = m_backBufferDepthStencil; - m_deviceCtx->OMSetRenderTargets(1, &m_currentColor, m_currentDepthStencil); + m_deviceCtx->OMSetRenderTargetsAndUnorderedAccessViews(1, &m_currentColor, m_currentDepthStencil, 1, 0, NULL, NULL); m_needPresent |= _needPresent; } else @@ -4579,6 +4584,10 @@ namespace bgfx { namespace d3d11 { m_rtv[ii] = NULL; } + for(uint32_t ii = 0; ii < BX_COUNTOF(m_uav); ++ii) + { + m_uav[ii] = NULL; + } m_dsv = NULL; m_swapChain = NULL; @@ -4690,6 +4699,8 @@ namespace bgfx { namespace d3d11 if (0 < m_numTh) { m_num = 0; + m_numUav = 0; + for (uint32_t ii = 0; ii < m_numTh; ++ii) { const Attachment& at = m_attachment[ii]; @@ -4851,7 +4862,8 @@ namespace bgfx { namespace d3d11 } else { - BX_CHECK(false, ""); + m_uav[m_num + m_numUav] = texture.m_uav; + m_numUav++; } } } @@ -4924,7 +4936,7 @@ namespace bgfx { namespace d3d11 void FrameBufferD3D11::set() { - s_renderD3D11->m_deviceCtx->OMSetRenderTargets(m_num, m_rtv, m_dsv); + s_renderD3D11->m_deviceCtx->OMSetRenderTargetsAndUnorderedAccessViews(m_num, m_rtv, m_dsv, m_num, m_numUav, m_uav + m_num, NULL); m_needPresent = UINT16_MAX != m_denseIdx; s_renderD3D11->m_currentColor = m_rtv[0]; s_renderD3D11->m_currentDepthStencil = m_dsv; diff --git a/src/renderer_d3d11.h b/src/renderer_d3d11.h index d8c8f0a5b..3b49c88d6 100644 --- a/src/renderer_d3d11.h +++ b/src/renderer_d3d11.h @@ -330,6 +330,7 @@ namespace bgfx { namespace d3d11 , m_denseIdx(UINT16_MAX) , m_num(0) , m_numTh(0) + , m_numUav(0) , m_needPresent(false) { } @@ -345,6 +346,7 @@ namespace bgfx { namespace d3d11 HRESULT present(uint32_t _syncInterval); ID3D11RenderTargetView* m_rtv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1]; + ID3D11UnorderedAccessView* m_uav[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1]; ID3D11ShaderResourceView* m_srv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1]; ID3D11DepthStencilView* m_dsv; Dxgi::SwapChainI* m_swapChain; @@ -356,6 +358,7 @@ namespace bgfx { namespace d3d11 uint16_t m_denseIdx; uint8_t m_num; uint8_t m_numTh; + uint8_t m_numUav; bool m_needPresent; }; diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index a37a5572d..bd9eb4228 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -2434,12 +2434,18 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) ); m_atocSupport = s_extension[Extension::ARB_multisample].m_supported; m_conservativeRasterSupport = s_extension[Extension::NV_conservative_raster].m_supported; + m_imageLoadStoreSupport = false + || s_extension[Extension::ARB_shader_image_load_store].m_supported + || s_extension[Extension::EXT_shader_image_load_store].m_supported + ; + g_caps.supported |= 0 | (m_atocSupport ? BGFX_CAPS_ALPHA_TO_COVERAGE : 0) | (m_conservativeRasterSupport ? BGFX_CAPS_CONSERVATIVE_RASTER : 0) | (m_occlusionQuerySupport ? BGFX_CAPS_OCCLUSION_QUERY : 0) | (m_depthTextureSupport ? BGFX_CAPS_TEXTURE_COMPARE_LEQUAL : 0) | (computeSupport ? BGFX_CAPS_COMPUTE : 0) + | (m_imageLoadStoreSupport ? BGFX_CAPS_READ_WRITE_ATTACH : 0) ; g_caps.supported |= m_glctx.getCaps(); @@ -3244,6 +3250,8 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) ); m_glctx.makeCurrent(NULL); m_currentFbo = frameBuffer.m_fbo[0]; } + + frameBuffer.set(); } GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_currentFbo) ); @@ -3888,6 +3896,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) ); bool m_occlusionQuerySupport; bool m_atocSupport; bool m_conservativeRasterSupport; + bool m_imageLoadStoreSupport; bool m_flip; uint64_t m_hash; @@ -5936,7 +5945,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) ); attachment = GL_DEPTH_ATTACHMENT; } } - else + else if (Access::Write == at.access) { buffers[colorIdx] = attachment; ++colorIdx; @@ -5968,7 +5977,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) ); ) ); } } - else if (Access::Write == at.access) + else { if (1 < texture.m_numLayers && !texture.isCubeMap()) @@ -5995,10 +6004,6 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) ); ) ); } } - else - { - BX_CHECK(false, ""); - } needResolve |= (0 != texture.m_rbo) && (0 != texture.m_id); } @@ -6196,6 +6201,33 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) ); GL_CHECK(glInvalidateFramebuffer(GL_FRAMEBUFFER, idx, buffers) ); } + void FrameBufferGL::set() + { + for(uint32_t ii = 0; ii < m_numTh; ++ii) + { + if(m_attachment[ii].access == Access::Write) + continue; + + TextureHandle handle = m_attachment[ii].handle; + if(isValid(handle)) + { + const TextureGL& texture = s_renderGL->m_textures[handle.idx]; + + if(0 != (texture.m_flags&BGFX_TEXTURE_COMPUTE_WRITE)) + { + GL_CHECK(glBindImageTexture(ii + , texture.m_id + , m_attachment[ii].mip + , GL_FALSE //texture.isLayered() ? GL_TRUE : GL_FALSE + , m_attachment[ii].layer + , s_access[Access::ReadWrite] + , s_imageFormat[texture.m_textureFormat]) + ); + } + } + } + } + void OcclusionQueryGL::create() { for (uint32_t ii = 0; ii < BX_COUNTOF(m_query); ++ii) diff --git a/src/renderer_gl.h b/src/renderer_gl.h index 2512aa09a..6c53ff3e3 100644 --- a/src/renderer_gl.h +++ b/src/renderer_gl.h @@ -1331,6 +1331,7 @@ namespace bgfx { namespace gl uint16_t destroy(); void resolve(); void discard(uint16_t _flags); + void set(); SwapChainGL* m_swapChain; GLuint m_fbo[2];