diff --git a/bindings/cs/bgfx.cs b/bindings/cs/bgfx.cs index 33d6e90e8..31eee7fb4 100644 --- a/bindings/cs/bgfx.cs +++ b/bindings/cs/bgfx.cs @@ -1041,9 +1041,9 @@ public static partial class bgfx FragmentOrdering = 0x0000000000000040, /// - /// Read/Write frame buffer attachments are supported. + /// Image Read/Write is supported. /// - FramebufferRw = 0x0000000000000080, + ImageRw = 0x0000000000000080, /// /// Graphics debugger is present. @@ -1148,87 +1148,92 @@ public static partial class bgfx } [Flags] - public enum CapsFormatFlags : ushort + public enum CapsFormatFlags : uint { /// /// Texture format is not supported. /// - TextureNone = 0x0000, + TextureNone = 0x00000000, /// /// Texture format is supported. /// - Texture2d = 0x0001, + Texture2d = 0x00000001, /// /// Texture as sRGB format is supported. /// - Texture2dSrgb = 0x0002, + Texture2dSrgb = 0x00000002, /// /// Texture format is emulated. /// - Texture2dEmulated = 0x0004, + Texture2dEmulated = 0x00000004, /// /// Texture format is supported. /// - Texture3d = 0x0008, + Texture3d = 0x00000008, /// /// Texture as sRGB format is supported. /// - Texture3dSrgb = 0x0010, + Texture3dSrgb = 0x00000010, /// /// Texture format is emulated. /// - Texture3dEmulated = 0x0020, + Texture3dEmulated = 0x00000020, /// /// Texture format is supported. /// - TextureCube = 0x0040, + TextureCube = 0x00000040, /// /// Texture as sRGB format is supported. /// - TextureCubeSrgb = 0x0080, + TextureCubeSrgb = 0x00000080, /// /// Texture format is emulated. /// - TextureCubeEmulated = 0x0100, + TextureCubeEmulated = 0x00000100, /// /// Texture format can be used from vertex shader. /// - TextureVertex = 0x0200, + TextureVertex = 0x00000200, /// - /// Texture format can be used as image from compute shader. + /// Texture format can be used as image and read from. /// - TextureImage = 0x0400, + TextureImageRead = 0x00000400, + + /// + /// Texture format can be used as image and written to. + /// + TextureImageWrite = 0x00000800, /// /// Texture format can be used as frame buffer. /// - TextureFramebuffer = 0x0800, + TextureFramebuffer = 0x00001000, /// /// Texture format can be used as MSAA frame buffer. /// - TextureFramebufferMsaa = 0x1000, + TextureFramebufferMsaa = 0x00002000, /// /// Texture can be sampled as MSAA. /// - TextureMsaa = 0x2000, + TextureMsaa = 0x00004000, /// /// Texture format supports auto-generated mips. /// - TextureMipAutogen = 0x4000, + TextureMipAutogen = 0x00008000, } [Flags] diff --git a/bindings/d/types.d b/bindings/d/types.d index 37c3f6d52..8465529a7 100644 --- a/bindings/d/types.d +++ b/bindings/d/types.d @@ -354,7 +354,7 @@ enum ulong BGFX_CAPS_CONSERVATIVE_RASTER = 0x0000000000000008; /// Conservative enum ulong BGFX_CAPS_DRAW_INDIRECT = 0x0000000000000010; /// Draw indirect is supported. enum ulong BGFX_CAPS_FRAGMENT_DEPTH = 0x0000000000000020; /// Fragment depth is accessible in fragment shader. enum ulong BGFX_CAPS_FRAGMENT_ORDERING = 0x0000000000000040; /// Fragment ordering is available in fragment shader. -enum ulong BGFX_CAPS_FRAMEBUFFER_RW = 0x0000000000000080; /// Read/Write frame buffer attachments are supported. +enum ulong BGFX_CAPS_IMAGE_RW = 0x0000000000000080; /// Image Read/Write is supported. enum ulong BGFX_CAPS_GRAPHICS_DEBUGGER = 0x0000000000000100; /// Graphics debugger is present. enum ulong BGFX_CAPS_RESERVED = 0x0000000000000200; enum ulong BGFX_CAPS_HDR10 = 0x0000000000000400; /// HDR10 rendering is supported. @@ -377,22 +377,23 @@ enum ulong BGFX_CAPS_VERTEX_ATTRIB_UINT10 = 0x0000000004000000; /// Vertex attri enum ulong BGFX_CAPS_VERTEX_ID = 0x0000000008000000; /// Rendering with VertexID only is supported. enum ulong BGFX_CAPS_TEXTURE_COMPARE_ALL = 0x0000000000300000; /// All texture compare modes are supported. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_NONE = 0x0000; /// Texture format is not supported. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_2D = 0x0001; /// Texture format is supported. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB = 0x0002; /// Texture as sRGB format is supported. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_2D_EMULATED = 0x0004; /// Texture format is emulated. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_3D = 0x0008; /// Texture format is supported. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB = 0x0010; /// Texture as sRGB format is supported. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_3D_EMULATED = 0x0020; /// Texture format is emulated. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_CUBE = 0x0040; /// Texture format is supported. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB = 0x0080; /// Texture as sRGB format is supported. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_CUBE_EMULATED = 0x0100; /// Texture format is emulated. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_VERTEX = 0x0200; /// Texture format can be used from vertex shader. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_IMAGE = 0x0400; /// Texture format can be used as image from compute shader. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER = 0x0800; /// Texture format can be used as frame buffer. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA = 0x1000; /// Texture format can be used as MSAA frame buffer. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_MSAA = 0x2000; /// Texture can be sampled as MSAA. -enum ushort BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN = 0x4000; /// Texture format supports auto-generated mips. +enum uint BGFX_CAPS_FORMAT_TEXTURE_NONE = 0x00000000; /// Texture format is not supported. +enum uint BGFX_CAPS_FORMAT_TEXTURE_2D = 0x00000001; /// Texture format is supported. +enum uint BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB = 0x00000002; /// Texture as sRGB format is supported. +enum uint BGFX_CAPS_FORMAT_TEXTURE_2D_EMULATED = 0x00000004; /// Texture format is emulated. +enum uint BGFX_CAPS_FORMAT_TEXTURE_3D = 0x00000008; /// Texture format is supported. +enum uint BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB = 0x00000010; /// Texture as sRGB format is supported. +enum uint BGFX_CAPS_FORMAT_TEXTURE_3D_EMULATED = 0x00000020; /// Texture format is emulated. +enum uint BGFX_CAPS_FORMAT_TEXTURE_CUBE = 0x00000040; /// Texture format is supported. +enum uint BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB = 0x00000080; /// Texture as sRGB format is supported. +enum uint BGFX_CAPS_FORMAT_TEXTURE_CUBE_EMULATED = 0x00000100; /// Texture format is emulated. +enum uint BGFX_CAPS_FORMAT_TEXTURE_VERTEX = 0x00000200; /// Texture format can be used from vertex shader. +enum uint BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ = 0x00000400; /// Texture format can be used as image and read from. +enum uint BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE = 0x00000800; /// Texture format can be used as image and written to. +enum uint BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER = 0x00001000; /// Texture format can be used as frame buffer. +enum uint BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA = 0x00002000; /// Texture format can be used as MSAA frame buffer. +enum uint BGFX_CAPS_FORMAT_TEXTURE_MSAA = 0x00004000; /// Texture can be sampled as MSAA. +enum uint BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN = 0x00008000; /// Texture format supports auto-generated mips. enum ubyte BGFX_RESOLVE_NONE = 0x00; /// No resolve flags. enum ubyte BGFX_RESOLVE_AUTO_GEN_MIPS = 0x01; /// Auto-generate mip maps on resolve. @@ -759,8 +760,10 @@ struct bgfx_caps_t * - `BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB` - Texture as sRGB format is supported. * - `BGFX_CAPS_FORMAT_TEXTURE_CUBE_EMULATED` - Texture format is emulated. * - `BGFX_CAPS_FORMAT_TEXTURE_VERTEX` - Texture format can be used from vertex shader. - * - `BGFX_CAPS_FORMAT_TEXTURE_IMAGE` - Texture format can be used as image from compute - * shader. + * - `BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ` - Texture format can be used as image + * and read from. + * - `BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE` - Texture format can be used as image + * and written to. * - `BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER` - Texture format can be used as frame * buffer. * - `BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA` - Texture format can be used as MSAA diff --git a/examples/21-deferred/deferred.cpp b/examples/21-deferred/deferred.cpp index d2f418a31..8d87051d7 100644 --- a/examples/21-deferred/deferred.cpp +++ b/examples/21-deferred/deferred.cpp @@ -13,10 +13,11 @@ namespace { constexpr bgfx::ViewId kRenderPassGeometry = 0; -constexpr bgfx::ViewId kRenderPassLight = 1; -constexpr bgfx::ViewId kRenderPassCombine = 2; -constexpr bgfx::ViewId kRenderPassDebugLights = 3; -constexpr bgfx::ViewId kRenderPassDebugGBuffer = 4; +constexpr bgfx::ViewId kRenderPassClearUav = 1; +constexpr bgfx::ViewId kRenderPassLight = 2; +constexpr bgfx::ViewId kRenderPassCombine = 3; +constexpr bgfx::ViewId kRenderPassDebugLights = 4; +constexpr bgfx::ViewId kRenderPassDebugGBuffer = 5; static float s_texelHalf = 0.0f; @@ -230,6 +231,7 @@ public: , 1.0f , 0 , 1 + , 0 ); // Set light pass view clear state. @@ -293,10 +295,12 @@ public: m_lightTaProgram = BGFX_INVALID_HANDLE; } - if (0 != (BGFX_CAPS_FRAMEBUFFER_RW & bgfx::getCaps()->supported) ) + if (0 != (BGFX_CAPS_IMAGE_RW & bgfx::getCaps()->supported) + && 0 != (BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ & bgfx::getCaps()->formats[bgfx::TextureFormat::RGBA8]) + && 0 != (BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE & bgfx::getCaps()->formats[bgfx::TextureFormat::RGBA8]) ) { - m_lightUavProgram = loadProgram("vs_deferred_light", "fs_deferred_light_uav"); m_clearUavProgram = loadProgram("vs_deferred_light", "fs_deferred_clear_uav"); + m_lightUavProgram = loadProgram("vs_deferred_light", "fs_deferred_light_uav"); } else { @@ -310,6 +314,8 @@ public: // Load normal texture. m_textureNormal = loadTexture("textures/fieldstone-n.dds"); + m_lightBufferTex.idx = bgfx::kInvalidHandle; + m_gbufferTex[0].idx = bgfx::kInvalidHandle; m_gbufferTex[1].idx = bgfx::kInvalidHandle; m_gbufferTex[2].idx = bgfx::kInvalidHandle; @@ -352,9 +358,18 @@ public: if (bgfx::isValid(m_gbuffer) ) { bgfx::destroy(m_gbuffer); + } + + if (bgfx::isValid(m_lightBuffer) ) + { bgfx::destroy(m_lightBuffer); } + if (bgfx::isValid(m_lightBufferTex) ) + { + bgfx::destroy(m_lightBufferTex); + } + bgfx::destroy(m_ibh); bgfx::destroy(m_vbh); @@ -421,6 +436,46 @@ public: float time = (float)( (now-m_timeOffset)/freq); + ImGui::SetNextWindowPos( + ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f) + , ImGuiCond_FirstUseEver + ); + ImGui::SetNextWindowSize( + ImVec2(m_width / 5.0f, m_height / 3.0f) + , ImGuiCond_FirstUseEver + ); + ImGui::Begin("Settings" + , NULL + , 0 + ); + + ImGui::SliderInt("Num lights", &m_numLights, 1, 2048); + ImGui::Checkbox("Show G-Buffer.", &m_showGBuffer); + ImGui::Checkbox("Show light scissor.", &m_showScissorRects); + + if (bgfx::isValid(m_lightTaProgram)) + { + ImGui::Checkbox("Use texture array frame buffer.", &m_useTArray); + } + else + { + ImGui::Text("Texture array frame buffer is not supported."); + } + + if (bgfx::isValid(m_lightUavProgram)) + { + ImGui::Checkbox("Use UAV.", &m_useUav); + } + else + { + ImGui::Text("UAV is not supported."); + } + + ImGui::Checkbox("Animate mesh.", &m_animateMesh); + ImGui::SliderFloat("Anim.speed", &m_lightAnimationSpeed, 0.0f, 0.4f); + + ImGui::End(); + if (2 > m_caps->limits.maxFBAttachments) { // When multiple render targets (MRT) is not supported by GPU, @@ -486,7 +541,7 @@ public: bgfx::TextureFormat::Enum depthFormat = bgfx::isTextureValid(0, false, 1, bgfx::TextureFormat::D32F, BGFX_TEXTURE_RT | tsFlags) ? bgfx::TextureFormat::D32F - : bgfx::TextureFormat::D24S8 + : bgfx::TextureFormat::D24 ; m_gbufferTex[2] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, depthFormat, BGFX_TEXTURE_RT | tsFlags); @@ -497,18 +552,18 @@ public: if (bgfx::isValid(m_lightBuffer) ) { bgfx::destroy(m_lightBuffer); + m_lightBuffer.idx = bgfx::kInvalidHandle; + } + + if (bgfx::isValid(m_lightBufferTex)) + { + bgfx::destroy(m_lightBufferTex); + m_lightBufferTex.idx = bgfx::kInvalidHandle; } 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); + m_lightBufferTex = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_COMPUTE_WRITE | tsFlags); } else { @@ -517,46 +572,6 @@ public: } } - ImGui::SetNextWindowPos( - ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f) - , ImGuiCond_FirstUseEver - ); - ImGui::SetNextWindowSize( - ImVec2(m_width / 5.0f, m_height / 3.0f) - , ImGuiCond_FirstUseEver - ); - ImGui::Begin("Settings" - , NULL - , 0 - ); - - ImGui::SliderInt("Num lights", &m_numLights, 1, 2048); - ImGui::Checkbox("Show G-Buffer.", &m_showGBuffer); - ImGui::Checkbox("Show light scissor.", &m_showScissorRects); - - if (bgfx::isValid(m_lightTaProgram) ) - { - ImGui::Checkbox("Use texture array frame buffer.", &m_useTArray); - } - else - { - 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); - - ImGui::End(); - // Update camera. cameraUpdate(deltaTime, m_mouseState); @@ -567,13 +582,21 @@ public: float vp[16]; float invMvp[16]; { - bgfx::setViewRect(kRenderPassGeometry, 0, 0, uint16_t(m_width), uint16_t(m_height) ); - bgfx::setViewRect(kRenderPassLight, 0, 0, uint16_t(m_width), uint16_t(m_height) ); - bgfx::setViewRect(kRenderPassCombine, 0, 0, uint16_t(m_width), uint16_t(m_height) ); + bgfx::setViewRect(kRenderPassGeometry, 0, 0, uint16_t(m_width), uint16_t(m_height) ); + bgfx::setViewRect(kRenderPassClearUav, 0, 0, uint16_t(m_width), uint16_t(m_height) ); + bgfx::setViewRect(kRenderPassLight, 0, 0, uint16_t(m_width), uint16_t(m_height) ); + bgfx::setViewRect(kRenderPassCombine, 0, 0, uint16_t(m_width), uint16_t(m_height) ); bgfx::setViewRect(kRenderPassDebugLights, 0, 0, uint16_t(m_width), uint16_t(m_height) ); bgfx::setViewRect(kRenderPassDebugGBuffer, 0, 0, uint16_t(m_width), uint16_t(m_height) ); - bgfx::setViewFrameBuffer(kRenderPassLight, m_lightBuffer); + if (!m_useUav) + { + bgfx::setViewFrameBuffer(kRenderPassLight, m_lightBuffer); + } + else + { + bgfx::setViewFrameBuffer(kRenderPassLight, BGFX_INVALID_HANDLE); + } float proj[16]; bx::mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f, m_caps->homogeneousDepth); @@ -587,8 +610,9 @@ public: const bgfx::Caps* caps = bgfx::getCaps(); bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f, 0.0f, caps->homogeneousDepth); - bgfx::setViewTransform(kRenderPassLight, NULL, proj); - bgfx::setViewTransform(kRenderPassCombine, NULL, proj); + bgfx::setViewTransform(kRenderPassClearUav, NULL, proj); + bgfx::setViewTransform(kRenderPassLight, NULL, proj); + bgfx::setViewTransform(kRenderPassCombine, NULL, proj); const float aspectRatio = float(m_height)/float(m_width); const float size = 10.0f; @@ -649,11 +673,10 @@ public: 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(kRenderPassLight, m_clearUavProgram); + bgfx::setViewFrameBuffer(kRenderPassClearUav, BGFX_INVALID_HANDLE); + bgfx::setState(0); + bgfx::setImage(2, m_lightBufferTex, 0, bgfx::Access::ReadWrite, bgfx::TextureFormat::RGBA8); + bgfx::submit(kRenderPassClearUav, m_clearUavProgram); } // Draw lights into light buffer. @@ -786,6 +809,9 @@ public: else if (bgfx::isValid(m_lightUavProgram) && m_useUav) { + bgfx::setViewFrameBuffer(kRenderPassLight, BGFX_INVALID_HANDLE); + bgfx::setState(0); + bgfx::setImage(3, m_lightBufferTex, 0, bgfx::Access::ReadWrite, bgfx::TextureFormat::RGBA8); bgfx::submit(kRenderPassLight, m_lightUavProgram); } else diff --git a/examples/21-deferred/fs_deferred_clear_uav.sc b/examples/21-deferred/fs_deferred_clear_uav.sc index 78e575a85..71178688d 100644 --- a/examples/21-deferred/fs_deferred_clear_uav.sc +++ b/examples/21-deferred/fs_deferred_clear_uav.sc @@ -5,13 +5,12 @@ $input v_texcoord0 * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause */ -#include "common.sh" #include -FRAMEBUFFER_IMAGE2D_RW(s_light, rgba8, 0); +IMAGE2D_RW(i_light, rgba8, 2); void main() { ivec2 coord = ivec2(gl_FragCoord.xy); - imageStore(s_light, coord, vec4(0.0, 0.0, 0.0, 0.0)); + imageStore(i_light, coord, vec4(0.0, 0.0, 0.0, 0.0)); } diff --git a/examples/21-deferred/fs_deferred_light_uav.sc b/examples/21-deferred/fs_deferred_light_uav.sc index 9b6114599..1476a0c6a 100644 --- a/examples/21-deferred/fs_deferred_light_uav.sc +++ b/examples/21-deferred/fs_deferred_light_uav.sc @@ -11,7 +11,7 @@ $input v_texcoord0 SAMPLER2D(s_normal, 0); SAMPLER2D(s_depth, 1); -FRAMEBUFFER_IMAGE2D_RW(s_light, rgba8, 0); +IMAGE2D_RW(i_light, rgba8, 3); uniform vec4 u_lightPosRadius[1]; uniform vec4 u_lightRgbInnerR[1]; @@ -35,6 +35,6 @@ void main() 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_light, coord); - imageStore(s_light, coord, color + vec4(toGamma(lightColor.xyz), 1.0)); + vec4 color = imageLoad(i_light, coord); + imageStore(i_light, coord, color + vec4(toGamma(lightColor.xyz), 1.0)); } diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h index edfb4563c..8cca874a8 100644 --- a/include/bgfx/bgfx.h +++ b/include/bgfx/bgfx.h @@ -799,8 +799,10 @@ namespace bgfx /// - `BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB` - Texture as sRGB format is supported. /// - `BGFX_CAPS_FORMAT_TEXTURE_CUBE_EMULATED` - Texture format is emulated. /// - `BGFX_CAPS_FORMAT_TEXTURE_VERTEX` - Texture format can be used from vertex shader. - /// - `BGFX_CAPS_FORMAT_TEXTURE_IMAGE` - Texture format can be used as image from compute - /// shader. + /// - `BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ` - Texture format can be used as image + /// and read from. + /// - `BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE` - Texture format can be used as image + /// and written to. /// - `BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER` - Texture format can be used as frame /// buffer. /// - `BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA` - Texture format can be used as MSAA diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h index d7b5efcc7..80b7deb90 100644 --- a/include/bgfx/c99/bgfx.h +++ b/include/bgfx/c99/bgfx.h @@ -554,8 +554,10 @@ typedef struct bgfx_caps_s * - `BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB` - Texture as sRGB format is supported. * - `BGFX_CAPS_FORMAT_TEXTURE_CUBE_EMULATED` - Texture format is emulated. * - `BGFX_CAPS_FORMAT_TEXTURE_VERTEX` - Texture format can be used from vertex shader. - * - `BGFX_CAPS_FORMAT_TEXTURE_IMAGE` - Texture format can be used as image from compute - * shader. + * - `BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ` - Texture format can be used as image + * and read from. + * - `BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE` - Texture format can be used as image + * and written to. * - `BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER` - Texture format can be used as frame * buffer. * - `BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA` - Texture format can be used as MSAA diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h index 7af964980..9afa12f3a 100644 --- a/include/bgfx/defines.h +++ b/include/bgfx/defines.h @@ -468,7 +468,7 @@ #define BGFX_CAPS_DRAW_INDIRECT UINT64_C(0x0000000000000010) //!< Draw indirect is supported. #define BGFX_CAPS_FRAGMENT_DEPTH UINT64_C(0x0000000000000020) //!< Fragment depth is accessible in fragment shader. #define BGFX_CAPS_FRAGMENT_ORDERING UINT64_C(0x0000000000000040) //!< Fragment ordering is available in fragment shader. -#define BGFX_CAPS_FRAMEBUFFER_RW UINT64_C(0x0000000000000080) //!< Read/Write frame buffer attachments are supported. +#define BGFX_CAPS_IMAGE_RW UINT64_C(0x0000000000000080) //!< Image Read/Write is supported. #define BGFX_CAPS_GRAPHICS_DEBUGGER UINT64_C(0x0000000000000100) //!< Graphics debugger is present. #define BGFX_CAPS_RESERVED UINT64_C(0x0000000000000200) #define BGFX_CAPS_HDR10 UINT64_C(0x0000000000000400) //!< HDR10 rendering is supported. @@ -496,22 +496,23 @@ ) -#define BGFX_CAPS_FORMAT_TEXTURE_NONE UINT16_C(0x0000) //!< Texture format is not supported. -#define BGFX_CAPS_FORMAT_TEXTURE_2D UINT16_C(0x0001) //!< Texture format is supported. -#define BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB UINT16_C(0x0002) //!< Texture as sRGB format is supported. -#define BGFX_CAPS_FORMAT_TEXTURE_2D_EMULATED UINT16_C(0x0004) //!< Texture format is emulated. -#define BGFX_CAPS_FORMAT_TEXTURE_3D UINT16_C(0x0008) //!< Texture format is supported. -#define BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB UINT16_C(0x0010) //!< Texture as sRGB format is supported. -#define BGFX_CAPS_FORMAT_TEXTURE_3D_EMULATED UINT16_C(0x0020) //!< Texture format is emulated. -#define BGFX_CAPS_FORMAT_TEXTURE_CUBE UINT16_C(0x0040) //!< Texture format is supported. -#define BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB UINT16_C(0x0080) //!< Texture as sRGB format is supported. -#define BGFX_CAPS_FORMAT_TEXTURE_CUBE_EMULATED UINT16_C(0x0100) //!< Texture format is emulated. -#define BGFX_CAPS_FORMAT_TEXTURE_VERTEX UINT16_C(0x0200) //!< Texture format can be used from vertex shader. -#define BGFX_CAPS_FORMAT_TEXTURE_IMAGE UINT16_C(0x0400) //!< Texture format can be used as image from compute shader. -#define BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER UINT16_C(0x0800) //!< Texture format can be used as frame buffer. -#define BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA UINT16_C(0x1000) //!< Texture format can be used as MSAA frame buffer. -#define BGFX_CAPS_FORMAT_TEXTURE_MSAA UINT16_C(0x2000) //!< Texture can be sampled as MSAA. -#define BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN UINT16_C(0x4000) //!< Texture format supports auto-generated mips. +#define BGFX_CAPS_FORMAT_TEXTURE_NONE UINT32_C(0x00000000) //!< Texture format is not supported. +#define BGFX_CAPS_FORMAT_TEXTURE_2D UINT32_C(0x00000001) //!< Texture format is supported. +#define BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB UINT32_C(0x00000002) //!< Texture as sRGB format is supported. +#define BGFX_CAPS_FORMAT_TEXTURE_2D_EMULATED UINT32_C(0x00000004) //!< Texture format is emulated. +#define BGFX_CAPS_FORMAT_TEXTURE_3D UINT32_C(0x00000008) //!< Texture format is supported. +#define BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB UINT32_C(0x00000010) //!< Texture as sRGB format is supported. +#define BGFX_CAPS_FORMAT_TEXTURE_3D_EMULATED UINT32_C(0x00000020) //!< Texture format is emulated. +#define BGFX_CAPS_FORMAT_TEXTURE_CUBE UINT32_C(0x00000040) //!< Texture format is supported. +#define BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB UINT32_C(0x00000080) //!< Texture as sRGB format is supported. +#define BGFX_CAPS_FORMAT_TEXTURE_CUBE_EMULATED UINT32_C(0x00000100) //!< Texture format is emulated. +#define BGFX_CAPS_FORMAT_TEXTURE_VERTEX UINT32_C(0x00000200) //!< Texture format can be used from vertex shader. +#define BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ UINT32_C(0x00000400) //!< Texture format can be used as image and read from. +#define BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE UINT32_C(0x00000800) //!< Texture format can be used as image and written to. +#define BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER UINT32_C(0x00001000) //!< Texture format can be used as frame buffer. +#define BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA UINT32_C(0x00002000) //!< Texture format can be used as MSAA frame buffer. +#define BGFX_CAPS_FORMAT_TEXTURE_MSAA UINT32_C(0x00004000) //!< Texture can be sampled as MSAA. +#define BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN UINT32_C(0x00008000) //!< Texture format supports auto-generated mips. #define BGFX_RESOLVE_NONE UINT8_C(0x00) //!< No resolve flags. #define BGFX_RESOLVE_AUTO_GEN_MIPS UINT8_C(0x01) //!< Auto-generate mip maps on resolve. diff --git a/scripts/bgfx.idl b/scripts/bgfx.idl index 6d6694960..d142e324b 100644 --- a/scripts/bgfx.idl +++ b/scripts/bgfx.idl @@ -371,7 +371,7 @@ flag.Caps { bits = 64, base = 1, name = "Caps" } .DrawIndirect --- Draw indirect is supported. .FragmentDepth --- Fragment depth is accessible in fragment shader. .FragmentOrdering --- Fragment ordering is available in fragment shader. - .FramebufferRw --- Read/Write frame buffer attachments are supported. + .ImageRw --- Image Read/Write is supported. .GraphicsDebugger --- Graphics debugger is present. .Reserved .Hdr10 --- HDR10 rendering is supported. @@ -395,7 +395,7 @@ flag.Caps { bits = 64, base = 1, name = "Caps" } .TextureCompareAll { "TextureCompareReserved", "TextureCompareLequal" } --- All texture compare modes are supported. () -flag.CapsFormat { bits = 16 } +flag.CapsFormat { bits = 32 } .TextureNone --- Texture format is not supported. .Texture_2d --- Texture format is supported. .Texture_2dSrgb --- Texture as sRGB format is supported. @@ -407,7 +407,8 @@ flag.CapsFormat { bits = 16 } .TextureCubeSrgb --- Texture as sRGB format is supported. .TextureCubeEmulated --- Texture format is emulated. .TextureVertex --- Texture format can be used from vertex shader. - .TextureImage --- Texture format can be used as image from compute shader. + .TextureImageRead --- Texture format can be used as image and read from. + .TextureImageWrite --- Texture format can be used as image and written to. .TextureFramebuffer --- Texture format can be used as frame buffer. .TextureFramebufferMsaa --- Texture format can be used as MSAA frame buffer. .TextureMsaa --- Texture can be sampled as MSAA. @@ -728,8 +729,10 @@ struct.Caps --- - `BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB` - Texture as sRGB format is supported. --- - `BGFX_CAPS_FORMAT_TEXTURE_CUBE_EMULATED` - Texture format is emulated. --- - `BGFX_CAPS_FORMAT_TEXTURE_VERTEX` - Texture format can be used from vertex shader. - --- - `BGFX_CAPS_FORMAT_TEXTURE_IMAGE` - Texture format can be used as image from compute - --- shader. + --- - `BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ` - Texture format can be used as image + --- and read from. + --- - `BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE` - Texture format can be used as image + --- and written to. --- - `BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER` - Texture format can be used as frame --- buffer. --- - `BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA` - Texture format can be used as MSAA diff --git a/src/bgfx.cpp b/src/bgfx.cpp index c9cbfaa29..15a703150 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -1637,7 +1637,7 @@ namespace bgfx BX_TRACE("\t ||||+------------ Cube: x = supported / * = emulated"); BX_TRACE("\t |||||+----------- Cube: sRGB format"); BX_TRACE("\t ||||||+---------- vertex format"); - BX_TRACE("\t |||||||+--------- image"); + BX_TRACE("\t |||||||+--------- image: i = read-write / r = read / w = write"); BX_TRACE("\t ||||||||+-------- framebuffer"); BX_TRACE("\t |||||||||+------- MSAA framebuffer"); BX_TRACE("\t ||||||||||+------ MSAA texture"); @@ -1648,7 +1648,7 @@ namespace bgfx if (TextureFormat::Unknown != ii && TextureFormat::UnknownDepth != ii) { - uint16_t flags = g_caps.formats[ii]; + uint32_t flags = g_caps.formats[ii]; BX_TRACE("\t[%c%c%c%c%c%c%c%c%c%c%c%c] %s" , flags&BGFX_CAPS_FORMAT_TEXTURE_2D ? 'x' : flags&BGFX_CAPS_FORMAT_TEXTURE_2D_EMULATED ? '*' : ' ' , flags&BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB ? 'l' : ' ' @@ -1657,7 +1657,8 @@ namespace bgfx , flags&BGFX_CAPS_FORMAT_TEXTURE_CUBE ? 'x' : flags&BGFX_CAPS_FORMAT_TEXTURE_CUBE_EMULATED ? '*' : ' ' , flags&BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB ? 'l' : ' ' , flags&BGFX_CAPS_FORMAT_TEXTURE_VERTEX ? 'v' : ' ' - , flags&BGFX_CAPS_FORMAT_TEXTURE_IMAGE ? 'i' : ' ' + , (flags&BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ) && + (flags&BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE) ? 'i' : flags&BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ ? 'r' : flags&BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE ? 'w' : ' ' , flags&BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER ? 'f' : ' ' , flags&BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA ? '+' : ' ' , flags&BGFX_CAPS_FORMAT_TEXTURE_MSAA ? 'm' : ' ' diff --git a/src/bgfx_compute.sh b/src/bgfx_compute.sh index 03108e9fb..6ad797e24 100644 --- a/src/bgfx_compute.sh +++ b/src/bgfx_compute.sh @@ -10,19 +10,11 @@ #ifndef __cplusplus -#if BGFX_SHADER_LANGUAGE_GLSL -# define FRAMEBUFFER_IMAGE2D_RW_0(_name, _format) IMAGE2D_RW(_name, _format, 4) -# define FRAMEBUFFER_IMAGE2D_RW_1(_name, _format) IMAGE2D_RW(_name, _format, 5) -# define FRAMEBUFFER_IMAGE2D_RW_2(_name, _format) IMAGE2D_RW(_name, _format, 6) -# define FRAMEBUFFER_IMAGE2D_RW_3(_name, _format) IMAGE2D_RW(_name, _format, 7) +#if BGFX_SHADER_LANGUAGE_METAL || BGFX_SHADER_LANGUAGE_SPIRV +# define ANNOTATION(_format) [[spv::format_ ## _format]] #else -# define FRAMEBUFFER_IMAGE2D_RW_0(_name, _format) IMAGE2D_RW(_name, _format, 16) -# define FRAMEBUFFER_IMAGE2D_RW_1(_name, _format) IMAGE2D_RW(_name, _format, 17) -# define FRAMEBUFFER_IMAGE2D_RW_2(_name, _format) IMAGE2D_RW(_name, _format, 18) -# define FRAMEBUFFER_IMAGE2D_RW_3(_name, _format) IMAGE2D_RW(_name, _format, 19) -#endif // BGFX_SHADER_LANGUAGE_GLSL - -#define FRAMEBUFFER_IMAGE2D_RW(_name, _format, _reg) FRAMEBUFFER_IMAGE2D_RW_ ## _reg(_name, _format) +# define ANNOTATION(_format) +#endif #if BGFX_SHADER_LANGUAGE_GLSL @@ -103,7 +95,7 @@ #define UIMAGE2D_RO(_name, _format, _reg) IMAGE2D_RO(_name, _format, _reg) #define IMAGE2D_RW( _name, _format, _reg) \ - RWTexture2D<_format> _name ## Texture : REGISTER(u, _reg); \ + ANNOTATION(_format) RWTexture2D<_format> _name ## Texture : REGISTER(u, _reg); \ static BgfxRWImage2D_ ## _format _name = { _name ## Texture } #define IMAGE2D_WR( _name, _format, _reg) IMAGE2D_RW(_name, _format, _reg) @@ -117,7 +109,7 @@ #define UIMAGE2D_ARRAY_RO(_name, _format, _reg) IMAGE2D_ARRAY_RO(_name, _format, _reg) #define IMAGE2D_ARRAY_RW(_name, _format, _reg) \ - RWTexture2DArray<_format> _name ## Texture : REGISTER(u, _reg); \ + ANNOTATION(_format) RWTexture2DArray<_format> _name ## Texture : REGISTER(u, _reg); \ static BgfxRWImage2DArray_ ## _format _name = { _name ## Texture } #define UIMAGE2D_ARRAY_RW(_name, _format, _reg) IMAGE2D_ARRAY_RW(_name, _format, _reg) @@ -131,7 +123,7 @@ #define UIMAGE3D_RO(_name, _format, _reg) IMAGE3D_RO(_name, _format, _reg) #define IMAGE3D_RW( _name, _format, _reg) \ - RWTexture3D<_format> _name ## Texture : REGISTER(u, _reg); \ + ANNOTATION(_format) RWTexture3D<_format> _name ## Texture : REGISTER(u, _reg); \ static BgfxRWImage3D_ ## _format _name = { _name ## Texture } #define UIMAGE3D_RW(_name, _format, _reg) IMAGE3D_RW(_name, _format, _reg) @@ -159,7 +151,7 @@ \ struct BgfxRWImage2D_ ## _format \ { \ - RWTexture2D<_format> m_texture; \ + ANNOTATION(_format) RWTexture2D<_format> m_texture; \ }; \ \ struct BgfxROImage2DArray_ ## _format \ @@ -169,7 +161,7 @@ \ struct BgfxRWImage2DArray_ ## _format \ { \ - RWTexture2DArray<_format> m_texture; \ + ANNOTATION(_format) RWTexture2DArray<_format> m_texture; \ }; \ \ struct BgfxROImage3D_ ## _format \ @@ -179,7 +171,7 @@ \ struct BgfxRWImage3D_ ## _format \ { \ - RWTexture3D<_format> m_texture; \ + ANNOTATION(_format) RWTexture3D<_format> m_texture; \ }; \ #define __IMAGE_IMPL_A(_format, _storeComponents, _type, _loadComponents) \ diff --git a/src/bgfx_shader.sh b/src/bgfx_shader.sh index 17e56a2eb..31b37a1d4 100644 --- a/src/bgfx_shader.sh +++ b/src/bgfx_shader.sh @@ -50,9 +50,10 @@ # define bvec3 bool3 # define bvec4 bool4 - +// To be able to patch the uav registers on the DXBC SPDB Chunk (D3D11 renderer) the whitespaces around +// '_type[_reg]' are necessary. This only affects shaders with debug info (i.e., those that have the SPDB Chunk). # if BGFX_SHADER_LANGUAGE_HLSL > 4 -# define REGISTER(_type, _reg) register(_type[_reg]) +# define REGISTER(_type, _reg) register( _type[_reg] ) # else # define REGISTER(_type, _reg) register(_type ## _reg) # endif // BGFX_SHADER_LANGUAGE_HLSL diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 467700e4d..34b6c1836 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -1204,7 +1204,7 @@ namespace bgfx { namespace d3d11 | BGFX_CAPS_TEXTURE_2D_ARRAY | BGFX_CAPS_TEXTURE_CUBE_ARRAY | ((m_featureLevel >= D3D_FEATURE_LEVEL_11_1) - ? BGFX_CAPS_FRAMEBUFFER_RW + ? BGFX_CAPS_IMAGE_RW : 0) ); @@ -1388,7 +1388,7 @@ namespace bgfx { namespace d3d11 support |= 0 != (data.OutFormatSupport & (0 | D3D11_FORMAT_SUPPORT_SHADER_LOAD ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE + ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ : BGFX_CAPS_FORMAT_TEXTURE_NONE ; @@ -1430,10 +1430,10 @@ namespace bgfx { namespace d3d11 ); } - if (0 != (support & BGFX_CAPS_FORMAT_TEXTURE_IMAGE) ) + if (0 != (support & BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ) ) { // clear image flag for additional testing - support &= ~BGFX_CAPS_FORMAT_TEXTURE_IMAGE; + support &= ~BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ; data.InFormat = s_textureFormat[ii].m_fmt; hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT2, &data, sizeof(data) ); @@ -1441,9 +1441,15 @@ namespace bgfx { namespace d3d11 { support |= 0 != (data.OutFormatSupport & (0 | D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; + + support |= 0 != (data.OutFormatSupport & (0 | D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE + ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE : BGFX_CAPS_FORMAT_TEXTURE_NONE ; } @@ -1455,12 +1461,12 @@ namespace bgfx { namespace d3d11 | BGFX_CAPS_FORMAT_TEXTURE_2D | BGFX_CAPS_FORMAT_TEXTURE_3D | BGFX_CAPS_FORMAT_TEXTURE_CUBE - | BGFX_CAPS_FORMAT_TEXTURE_IMAGE | BGFX_CAPS_FORMAT_TEXTURE_VERTEX - | BGFX_CAPS_FORMAT_TEXTURE_IMAGE | BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER | BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA | BGFX_CAPS_FORMAT_TEXTURE_MSAA + | BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ + | BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE ; } } @@ -3022,8 +3028,41 @@ namespace bgfx { namespace d3d11 return _visible == (0 != _render->m_occlusion[_handle.idx]); } + void quietValidation() + { + const uint32_t maxTextureSamplers = g_caps.limits.maxTextureSamplers; + + // vertex texture fetch not supported on 9_1 through 9_3 + if (m_featureLevel > D3D_FEATURE_LEVEL_9_3) + { + m_deviceCtx->VSSetShaderResources(0, maxTextureSamplers, s_zero.m_srv); + m_deviceCtx->VSSetSamplers(0, maxTextureSamplers, s_zero.m_sampler); + } + + if (m_featureLevel > D3D_FEATURE_LEVEL_11_0) + { + m_deviceCtx->OMSetRenderTargetsAndUnorderedAccessViews( + D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL + , NULL + , NULL + , 16 + , maxTextureSamplers + , s_zero.m_uav + , NULL + ); + } + + m_deviceCtx->PSSetShaderResources(0, maxTextureSamplers, s_zero.m_srv); + m_deviceCtx->PSSetSamplers(0, maxTextureSamplers, s_zero.m_sampler); + } + void commitTextureStage() { + if (BX_ENABLED(BGFX_CONFIG_DEBUG)) + { + quietValidation(); + } + const uint32_t maxTextureSamplers = g_caps.limits.maxTextureSamplers; // vertex texture fetch not supported on 9_1 through 9_3 @@ -3033,6 +3072,19 @@ namespace bgfx { namespace d3d11 m_deviceCtx->VSSetSamplers(0, maxTextureSamplers, m_textureStage.m_sampler); } + if (m_featureLevel > D3D_FEATURE_LEVEL_11_0) + { + m_deviceCtx->OMSetRenderTargetsAndUnorderedAccessViews( + D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL + , NULL + , NULL + , 16 + , maxTextureSamplers + , m_textureStage.m_uav + , NULL + ); + } + m_deviceCtx->PSSetShaderResources(0, maxTextureSamplers, m_textureStage.m_srv); m_deviceCtx->PSSetSamplers(0, maxTextureSamplers, m_textureStage.m_sampler); } @@ -3909,6 +3961,88 @@ namespace bgfx { namespace d3d11 return find.m_found; } + static void patchUAVRegisterByteCode(DxbcInstruction& _instruction, void* _userData) + { + union { void* ptr; uint32_t offset; } cast = { _userData }; + + switch (_instruction.opcode) + { + case DxbcOpcode::DCL_UNORDERED_ACCESS_VIEW_TYPED: + { + DxbcOperand& operand = _instruction.operand[0]; + operand.regIndex[0] += 16; + + BX_ASSERT(operand.regIndex[1] == 0 && operand.regIndex[2] == 0 + , "Unexpected values"); + } + break; + case DxbcOpcode::DCL_UNORDERED_ACCESS_VIEW_RAW: + { + BX_ASSERT(false, "Unsupported UAV access"); + } + break; + case DxbcOpcode::DCL_UNORDERED_ACCESS_VIEW_STRUCTURED: + { + BX_ASSERT(false, "Unsupported UAV access"); + } + break; + case DxbcOpcode::LD_UAV_TYPED: + { + DxbcOperand& operand = _instruction.operand[2]; + operand.regIndex[0] += 16; + + BX_ASSERT(operand.regIndex[1] == 0 && operand.regIndex[2] == 0 + , "Unexpected values"); + } + break; + case DxbcOpcode::STORE_UAV_TYPED: + { + DxbcOperand& operand = _instruction.operand[0]; + operand.regIndex[0] += 16; + + BX_ASSERT(operand.regIndex[1] == 0 && operand.regIndex[2] == 0 + , "Unexpected values"); + } + break; + } + } + + static void patchUAVRegisterDebugInfo(DxbcSPDB& _spdb) + { + if (!_spdb.debugCode.empty()) + { + // 'register( u[xx] )' + char* ptr = (char*)_spdb.debugCode.data(); + while (ptr < (char*)_spdb.debugCode.data() + _spdb.debugCode.size() - 3) + { + if (*(ptr+1) == ' ' + && *(ptr+2) == 'u' + && *(ptr+3) == '[') + { + char* startPtr = ptr+4; + char* endPtr = ptr+4; + + while (*endPtr != ']') + { + endPtr++; + } + + uint32_t regNum = 0; + uint32_t regLen = endPtr - startPtr; + bx::fromString(®Num, bx::StringView(startPtr, regLen)); + + regNum += 16; + uint32_t len = bx::toString(startPtr, regLen+2, regNum); + *(startPtr + len) = ']'; + + break; + } + + ++ptr; + } + } + } + void ShaderD3D11::create(const Memory* _mem) { bx::MemoryReader reader(_mem->data, _mem->size); @@ -4029,6 +4163,33 @@ namespace bgfx { namespace d3d11 const void* code = reader.getDataPtr(); bx::skip(&reader, shaderSize+1); + const Memory* temp = NULL; + + if (!isShaderType(magic, 'C')) + { + bx::MemoryReader rd(code, shaderSize); + + DxbcContext dxbc; + bx::Error err; + read(&rd, dxbc, &err); + + bool patchShader = !dxbc.shader.aon9; + if (patchShader) + { + union { uint32_t offset; void* ptr; } cast = { 0 }; + filter(dxbc.shader, dxbc.shader, patchUAVRegisterByteCode, cast.ptr); + patchUAVRegisterDebugInfo(dxbc.spdb); + + temp = alloc(shaderSize); + bx::StaticMemoryBlockWriter wr(temp->data, temp->size); + + int32_t size = write(&wr, dxbc, &err); + dxbcHash(temp->data + 20, size - 20, temp->data + 4); + + code = temp->data; + } + } + if (isShaderType(magic, 'F') ) { m_hasDepthOp = hasDepthOp(code, shaderSize); @@ -4083,6 +4244,11 @@ namespace bgfx { namespace d3d11 BX_TRACE("\tCB size: %d", desc.ByteWidth); } + + if (NULL != temp) + { + release(temp); + } } void* DirectAccessResourceD3D11::createTexture2D(const D3D11_TEXTURE2D_DESC* _gpuDesc, const D3D11_SUBRESOURCE_DATA* _srd, ID3D11Texture2D** _gpuTexture2d) @@ -5024,23 +5190,7 @@ namespace bgfx { namespace d3d11 void FrameBufferD3D11::set() { - if (0 < m_numUav) - { - s_renderD3D11->m_deviceCtx->OMSetRenderTargetsAndUnorderedAccessViews( - m_num - , m_rtv - , m_dsv - , 16 - , m_numUav - , m_uav - , NULL - ); - } - else - { - s_renderD3D11->m_deviceCtx->OMSetRenderTargets(m_num, m_rtv, m_dsv); - } - + s_renderD3D11->m_deviceCtx->OMSetRenderTargets(m_num, m_rtv, m_dsv); m_needPresent = UINT16_MAX != m_denseIdx; s_renderD3D11->m_currentColor = m_rtv[0]; s_renderD3D11->m_currentDepthStencil = m_dsv; @@ -5622,6 +5772,7 @@ namespace bgfx { namespace d3d11 { m_textureStage.m_srv[stage] = NULL; m_textureStage.m_sampler[stage] = NULL; + m_textureStage.m_uav[stage] = NULL; } } @@ -5902,6 +6053,24 @@ namespace bgfx { namespace d3d11 { switch (bind.m_type) { + case Binding::Image: + { + TextureD3D11& texture = m_textures[bind.m_idx]; + if (Access::Read != bind.m_access) + { + m_textureStage.m_uav[stage] = 0 == bind.m_mip + ? texture.m_uav + : s_renderD3D11->getCachedUav(texture.getHandle(), bind.m_mip) + ; + } + else + { + m_textureStage.m_srv[stage] = s_renderD3D11->getCachedSrv(texture.getHandle(), bind.m_mip, true); + m_textureStage.m_sampler[stage] = s_renderD3D11->getSamplerState(uint32_t(texture.m_flags), NULL); + } + } + break; + case Binding::Texture: { TextureD3D11& texture = m_textures[bind.m_idx]; @@ -5918,6 +6087,7 @@ namespace bgfx { namespace d3d11 ; m_textureStage.m_srv[stage] = buffer.m_srv; m_textureStage.m_sampler[stage] = NULL; + m_textureStage.m_uav[stage] = NULL; } break; } @@ -5926,6 +6096,7 @@ namespace bgfx { namespace d3d11 { m_textureStage.m_srv[stage] = NULL; m_textureStage.m_sampler[stage] = NULL; + m_textureStage.m_uav[stage] = NULL; } ++changes; diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index b587fefc8..0d7a18667 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -503,7 +503,7 @@ namespace bgfx { namespace d3d12 ID3D12Resource* createCommittedResource(ID3D12Device* _device, HeapProperty::Enum _heapProperty, uint64_t _size, D3D12_RESOURCE_FLAGS _flags = D3D12_RESOURCE_FLAG_NONE) { - D3D12_RESOURCE_DESC resourceDesc; + D3D12_RESOURCE_DESC resourceDesc = {}; resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; resourceDesc.Alignment = 0; resourceDesc.Width = _size; @@ -795,7 +795,12 @@ namespace bgfx { namespace d3d12 if (SUCCEEDED(hr)) { // debug1->SetEnableGPUBasedValidation(true); -// debug1->SetEnableSynchronizedCommandQueueValidation(true); + + // https://discordapp.com/channels/590611987420020747/593519198995742733/703642988345032804 + // D3D12 Bug Number: 26131261 + // There is a bug in the D3D12 validation that causes example-21 to fail when using UAV + // Setting this function below to false avoids the bug + debug1->SetEnableSynchronizedCommandQueueValidation(false); } DX_RELEASE(debug1, 1); @@ -1157,6 +1162,7 @@ namespace bgfx { namespace d3d12 | BGFX_CAPS_ALPHA_TO_COVERAGE | BGFX_CAPS_TEXTURE_2D_ARRAY | BGFX_CAPS_TEXTURE_CUBE_ARRAY + | BGFX_CAPS_IMAGE_RW ); g_caps.limits.maxTextureSize = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; g_caps.limits.maxTextureLayers = D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; @@ -1214,7 +1220,7 @@ namespace bgfx { namespace d3d12 support |= 0 != (data.Support1 & (0 | D3D12_FORMAT_SUPPORT1_SHADER_LOAD ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE + ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ : BGFX_CAPS_FORMAT_TEXTURE_NONE ; @@ -1245,10 +1251,10 @@ namespace bgfx { namespace d3d12 BX_TRACE("CheckFeatureSupport failed with %x for format %s.", hr, getName(TextureFormat::Enum(ii) ) ); } - if (0 != (support & BGFX_CAPS_FORMAT_TEXTURE_IMAGE) ) + if (0 != (support & BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ) ) { // clear image flag for additional testing - support &= ~BGFX_CAPS_FORMAT_TEXTURE_IMAGE; + support &= ~BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ; data.Format = s_textureFormat[ii].m_fmt; hr = m_device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) ); @@ -1256,9 +1262,15 @@ namespace bgfx { namespace d3d12 { support |= 0 != (data.Support2 & (0 | D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; + + support |= 0 != (data.Support2 & (0 | D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE + ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE : BGFX_CAPS_FORMAT_TEXTURE_NONE ; } @@ -2913,7 +2925,7 @@ namespace bgfx { namespace d3d12 union { uint32_t offset; void* ptr; } cast = { 0 }; filter(dxbc.shader, dxbc.shader, patchCb0, cast.ptr); - temp = alloc(uint32_t(dxbc.shader.byteCode.size() )+1024); + temp = alloc(uint32_t(dxbc.header.size)); bx::StaticMemoryBlockWriter wr(temp->data, temp->size); int32_t size = write(&wr, dxbc, &err); @@ -2950,7 +2962,7 @@ namespace bgfx { namespace d3d12 }; filter(dxbc.shader, dxbc.shader, patchCb0, cast.ptr); - temp = alloc(uint32_t(dxbc.shader.byteCode.size() )+1024); + temp = alloc(uint32_t(dxbc.header.size)); bx::StaticMemoryBlockWriter wr(temp->data, temp->size); int32_t size = write(&wr, dxbc, &err); @@ -6491,8 +6503,8 @@ namespace bgfx { namespace d3d12 if (NULL == bindCached) { uint32_t numSet = 0; - D3D12_GPU_DESCRIPTOR_HANDLE srvHandle[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; - uint32_t samplerFlags[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; + D3D12_GPU_DESCRIPTOR_HANDLE srvHandle[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS] = {}; + uint32_t samplerFlags[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS] = {}; { for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage) { @@ -6501,6 +6513,26 @@ namespace bgfx { namespace d3d12 { switch (bind.m_type) { + case Binding::Image: + { + TextureD3D12& texture = m_textures[bind.m_idx]; + + if (Access::Read != bind.m_access) + { + texture.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + scratchBuffer.allocUav(srvHandle[stage], texture, bind.m_mip); + } + else + { + texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); + scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_mip); + samplerFlags[stage] = uint32_t(texture.m_flags); + } + + ++numSet; + } + break; + case Binding::Texture: { TextureD3D12& texture = m_textures[bind.m_idx]; diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index fe9c599a4..f05346199 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -2629,7 +2629,7 @@ namespace bgfx { namespace gl supported |= computeSupport && isImageFormatValid(fmt) - ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE + ? (BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ | BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE) : BGFX_CAPS_FORMAT_TEXTURE_NONE ; @@ -2893,7 +2893,7 @@ namespace bgfx { namespace gl | (m_occlusionQuerySupport ? BGFX_CAPS_OCCLUSION_QUERY : 0) | (m_depthTextureSupport ? BGFX_CAPS_TEXTURE_COMPARE_LEQUAL : 0) | (computeSupport ? BGFX_CAPS_COMPUTE : 0) - | (m_imageLoadStoreSupport ? BGFX_CAPS_FRAMEBUFFER_RW : 0) + | (m_imageLoadStoreSupport ? BGFX_CAPS_IMAGE_RW : 0) ; g_caps.supported |= m_glctx.getCaps(); @@ -3696,8 +3696,6 @@ namespace bgfx { namespace gl m_glctx.makeCurrent(NULL); m_currentFbo = frameBuffer.m_fbo[0]; } - - frameBuffer.set(); } GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_currentFbo) ); @@ -6847,36 +6845,6 @@ namespace bgfx { namespace gl GL_CHECK(glInvalidateFramebuffer(GL_FRAMEBUFFER, idx, buffers) ); } - void FrameBufferGL::set() - { - for(uint32_t ii = 0; ii < m_numTh; ++ii) - { - const Attachment& at = m_attachment[ii]; - - if (at.access == Access::Write) - { - continue; - } - - if (isValid(at.handle) ) - { - const TextureGL& texture = s_renderGL->m_textures[at.handle.idx]; - - if (0 != (texture.m_flags&BGFX_TEXTURE_COMPUTE_WRITE) ) - { - GL_CHECK(glBindImageTexture(ii - , texture.m_id - , at.mip - , GL_FALSE //texture.isLayered() ? GL_TRUE : GL_FALSE - , at.layer - , s_access[Access::ReadWrite] - , s_imageFormat[texture.m_textureFormat]) - ); - } - } - } - } - void OcclusionQueryGL::create() { for (uint32_t ii = 0; ii < BX_COUNTOF(m_query); ++ii) @@ -7782,6 +7750,7 @@ namespace bgfx { namespace gl viewState.setPredefined<1>(this, view, program, _render, draw); { + GLbitfield barrier = 0; for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage) { const Binding& bind = renderBind.m_bind[stage]; @@ -7795,6 +7764,21 @@ namespace bgfx { namespace gl { switch (bind.m_type) { + case Binding::Image: + { + const TextureGL& texture = m_textures[bind.m_idx]; + GL_CHECK(glBindImageTexture(stage + , texture.m_id + , bind.m_mip + , texture.isCubeMap() || texture.m_target == GL_TEXTURE_2D_ARRAY ? GL_TRUE : GL_FALSE + , 0 + , s_access[bind.m_access] + , s_imageFormat[bind.m_format]) + ); + barrier |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; + } + break; + case Binding::Texture: { TextureGL& texture = m_textures[bind.m_idx]; @@ -7821,6 +7805,11 @@ namespace bgfx { namespace gl current = bind; } + + if (0 != barrier) + { + GL_CHECK(glMemoryBarrier(barrier) ); + } } { diff --git a/src/renderer_gl.h b/src/renderer_gl.h index 4ffffc1a4..162e3ff5d 100644 --- a/src/renderer_gl.h +++ b/src/renderer_gl.h @@ -1447,7 +1447,6 @@ namespace bgfx { namespace gl uint16_t destroy(); void resolve(); void discard(uint16_t _flags); - void set(); SwapChainGL* m_swapChain; GLuint m_fbo[2]; diff --git a/src/renderer_noop.cpp b/src/renderer_noop.cpp index baf251111..530bb0001 100644 --- a/src/renderer_noop.cpp +++ b/src/renderer_noop.cpp @@ -53,7 +53,8 @@ namespace bgfx { namespace noop | BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB | BGFX_CAPS_FORMAT_TEXTURE_CUBE_EMULATED | BGFX_CAPS_FORMAT_TEXTURE_VERTEX - | BGFX_CAPS_FORMAT_TEXTURE_IMAGE + | BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ + | BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE | BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER | BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA | BGFX_CAPS_FORMAT_TEXTURE_MSAA diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index 70f84020e..de37b6bc1 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -1570,6 +1570,7 @@ VK_IMPORT_INSTANCE | BGFX_CAPS_VERTEX_ATTRIB_HALF | BGFX_CAPS_VERTEX_ATTRIB_UINT10 | BGFX_CAPS_VERTEX_ID + | BGFX_CAPS_IMAGE_RW ); g_caps.limits.maxTextureSize = m_deviceProperties.limits.maxImageDimension2D; @@ -1607,6 +1608,8 @@ VK_IMPORT_INSTANCE { VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, { BGFX_CAPS_FORMAT_TEXTURE_CUBE, BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB } }, { VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, { BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER, BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER } }, { VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 0, { BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER, BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER } }, + { VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_STORAGE_BIT, 0, { BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ, BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ } }, + { VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_STORAGE_BIT, 0, { BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE, BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE } }, }; for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) diff --git a/src/shader_dxbc.cpp b/src/shader_dxbc.cpp index 2c976e734..8a9512756 100644 --- a/src/shader_dxbc.cpp +++ b/src/shader_dxbc.cpp @@ -1851,6 +1851,9 @@ namespace bgfx #define DXBC_CHUNK_INPUT_SIGNATURE BX_MAKEFOURCC('I', 'S', 'G', 'N') #define DXBC_CHUNK_OUTPUT_SIGNATURE BX_MAKEFOURCC('O', 'S', 'G', 'N') +#define DXBC_CHUNK_SFI0 BX_MAKEFOURCC('S', 'F', 'I', '0') +#define DXBC_CHUNK_SPDB BX_MAKEFOURCC('S', 'P', 'D', 'B') + int32_t read(bx::ReaderSeekerI* _reader, DxbcContext& _dxbc, bx::Error* _err) { int32_t size = 0; @@ -1869,6 +1872,7 @@ namespace bgfx uint32_t fourcc; size += bx::read(_reader, fourcc, _err); + _dxbc.chunksFourcc[ii] = fourcc; uint32_t chunkSize; size += bx::read(_reader, chunkSize, _err); @@ -1898,11 +1902,21 @@ namespace bgfx _dxbc.shader.aon9 = true; break; + case DXBC_CHUNK_SFI0: // ? + BX_ASSERT(chunkSize == sizeof(_dxbc.sfi0.data), + "Unexpected size of SFI0 chunk"); + + size += bx::read(_reader, _dxbc.sfi0.data, _err); + break; + + case DXBC_CHUNK_SPDB: // Shader debugging info (new). + _dxbc.spdb.debugCode.resize(chunkSize); + size += bx::read(_reader, _dxbc.spdb.debugCode.data(), chunkSize, _err); + break; + case BX_MAKEFOURCC('I', 'F', 'C', 'E'): // Interface. case BX_MAKEFOURCC('R', 'D', 'E', 'F'): // Resource definition. case BX_MAKEFOURCC('S', 'D', 'G', 'B'): // Shader debugging info (old). - case BX_MAKEFOURCC('S', 'P', 'D', 'B'): // Shader debugging info (new). - case BX_MAKEFOURCC('S', 'F', 'I', '0'): // ? case BX_MAKEFOURCC('S', 'T', 'A', 'T'): // Statistics. case BX_MAKEFOURCC('P', 'C', 'S', 'G'): // Patch constant signature. case BX_MAKEFOURCC('P', 'S', 'O', '1'): // Pipeline State Object 1 @@ -1932,6 +1946,28 @@ namespace bgfx { int32_t size = 0; + uint32_t numSupportedChunks = 0; + for (uint32_t ii = 0; ii < _dxbc.header.numChunks; ++ii) + { + switch(_dxbc.chunksFourcc[ii]) + { + case DXBC_CHUNK_SHADER_EX: + case DXBC_CHUNK_SHADER: + case BX_MAKEFOURCC('I', 'S', 'G', '1'): + case DXBC_CHUNK_INPUT_SIGNATURE: + case BX_MAKEFOURCC('O', 'S', 'G', '1'): + case BX_MAKEFOURCC('O', 'S', 'G', '5'): + case DXBC_CHUNK_OUTPUT_SIGNATURE: + case DXBC_CHUNK_SFI0: + case DXBC_CHUNK_SPDB: + ++numSupportedChunks; + break; + + default: + break; + } + } + int64_t dxbcOffset = bx::seek(_writer); size += bx::write(_writer, DXBC_CHUNK_HEADER); @@ -1942,35 +1978,82 @@ namespace bgfx int64_t sizeOffset = bx::seek(_writer); size += bx::writeRep(_writer, 0, 4, _err); - uint32_t numChunks = 3; - size += bx::write(_writer, numChunks, _err); + size += bx::write(_writer, numSupportedChunks, _err); int64_t chunksOffsets = bx::seek(_writer); - size += bx::writeRep(_writer, 0, numChunks*sizeof(uint32_t), _err); + size += bx::writeRep(_writer, 0, numSupportedChunks*sizeof(uint32_t), _err); - uint32_t chunkOffset[3]; - uint32_t chunkSize[3]; + uint32_t chunkOffset[DXBC_MAX_CHUNKS] = {}; + uint32_t chunkSize[DXBC_MAX_CHUNKS] = {}; - chunkOffset[0] = uint32_t(bx::seek(_writer) - dxbcOffset); - size += write(_writer, DXBC_CHUNK_INPUT_SIGNATURE, _err); - size += write(_writer, UINT32_C(0), _err); - chunkSize[0] = write(_writer, _dxbc.inputSignature, _err); + for (uint32_t ii = 0, idx = 0; ii < _dxbc.header.numChunks; ++ii) + { + switch (_dxbc.chunksFourcc[ii]) + { + case DXBC_CHUNK_SHADER_EX: + case DXBC_CHUNK_SHADER: + chunkOffset[idx] = uint32_t(bx::seek(_writer) - dxbcOffset); + size += bx::write(_writer, _dxbc.shader.shex ? DXBC_CHUNK_SHADER_EX : DXBC_CHUNK_SHADER, _err); + size += bx::write(_writer, UINT32_C(0), _err); + chunkSize[idx] = write(_writer, _dxbc.shader, _err); + size += chunkSize[idx++]; + break; - chunkOffset[1] = uint32_t(bx::seek(_writer) - dxbcOffset); - size += write(_writer, DXBC_CHUNK_OUTPUT_SIGNATURE, _err); - size += write(_writer, UINT32_C(0), _err); - chunkSize[1] = write(_writer, _dxbc.outputSignature, _err); + case BX_MAKEFOURCC('I', 'S', 'G', '1'): + case DXBC_CHUNK_INPUT_SIGNATURE: + chunkOffset[idx] = uint32_t(bx::seek(_writer) - dxbcOffset); + size += bx::write(_writer, DXBC_CHUNK_INPUT_SIGNATURE, _err); + size += bx::write(_writer, UINT32_C(0), _err); + chunkSize[idx] = write(_writer, _dxbc.inputSignature, _err); + size += chunkSize[idx++]; + break; - chunkOffset[2] = uint32_t(bx::seek(_writer) - dxbcOffset); - size += write(_writer, _dxbc.shader.shex ? DXBC_CHUNK_SHADER_EX : DXBC_CHUNK_SHADER, _err); - size += write(_writer, UINT32_C(0), _err); - chunkSize[2] = write(_writer, _dxbc.shader, _err); + case BX_MAKEFOURCC('O', 'S', 'G', '1'): + case BX_MAKEFOURCC('O', 'S', 'G', '5'): + case DXBC_CHUNK_OUTPUT_SIGNATURE: + chunkOffset[idx] = uint32_t(bx::seek(_writer) - dxbcOffset); + size += bx::write(_writer, DXBC_CHUNK_OUTPUT_SIGNATURE, _err); + size += bx::write(_writer, UINT32_C(0), _err); + chunkSize[idx] = write(_writer, _dxbc.outputSignature, _err); + size += chunkSize[idx++]; + break; - size += 0 - + chunkSize[0] - + chunkSize[1] - + chunkSize[2] - ; + case DXBC_CHUNK_SFI0: + chunkOffset[idx] = uint32_t(bx::seek(_writer) - dxbcOffset); + size += bx::write(_writer, DXBC_CHUNK_SFI0, _err); + size += bx::write(_writer, UINT32_C(0), _err); + chunkSize[idx] = bx::write(_writer, _dxbc.sfi0.data, _err); + size += chunkSize[idx++]; + break; + + case DXBC_CHUNK_SPDB: // Shader debugging info (new). + chunkOffset[idx] = uint32_t(bx::seek(_writer) - dxbcOffset); + size += bx::write(_writer, DXBC_CHUNK_SPDB, _err); + size += bx::write(_writer, UINT32_C(0), _err); + chunkSize[idx] = bx::write(_writer, _dxbc.spdb.debugCode.data(), _dxbc.spdb.debugCode.size(), _err); + size += chunkSize[idx++]; + break; + + case BX_MAKEFOURCC('A', 'o', 'n', '9'): // Contains DX9BC for feature level 9.x (*s_4_0_level_9_*) shaders. + case BX_MAKEFOURCC('I', 'F', 'C', 'E'): // Interface. + case BX_MAKEFOURCC('R', 'D', 'E', 'F'): // Resource definition. + case BX_MAKEFOURCC('S', 'D', 'G', 'B'): // Shader debugging info (old). + case BX_MAKEFOURCC('S', 'T', 'A', 'T'): // Statistics. + case BX_MAKEFOURCC('P', 'C', 'S', 'G'): // Patch constant signature. + case BX_MAKEFOURCC('P', 'S', 'O', '1'): // Pipeline State Object 1 + case BX_MAKEFOURCC('P', 'S', 'O', '2'): // Pipeline State Object 2 + case BX_MAKEFOURCC('X', 'N', 'A', 'P'): // ? + case BX_MAKEFOURCC('X', 'N', 'A', 'S'): // ? + default: + BX_ASSERT(false, "Writing of DXBC %c%c%c%c chunk unsupported" + , ( (char*)&_dxbc.chunksFourcc[ii])[0] + , ( (char*)&_dxbc.chunksFourcc[ii])[1] + , ( (char*)&_dxbc.chunksFourcc[ii])[2] + , ( (char*)&_dxbc.chunksFourcc[ii])[3] + ); + break; + } + } int64_t eof = bx::seek(_writer); @@ -1978,9 +2061,9 @@ namespace bgfx bx::write(_writer, size, _err); bx::seek(_writer, chunksOffsets, bx::Whence::Begin); - bx::write(_writer, chunkOffset, sizeof(chunkOffset), _err); + bx::write(_writer, chunkOffset, numSupportedChunks*sizeof(chunkOffset[0]), _err); - for (uint32_t ii = 0; ii < BX_COUNTOF(chunkOffset); ++ii) + for (uint32_t ii = 0; ii < numSupportedChunks; ++ii) { bx::seek(_writer, chunkOffset[ii]+4, bx::Whence::Begin); bx::write(_writer, chunkSize[ii], _err); diff --git a/src/shader_dxbc.h b/src/shader_dxbc.h index 0b2b03527..dc56864f0 100644 --- a/src/shader_dxbc.h +++ b/src/shader_dxbc.h @@ -633,6 +633,16 @@ namespace bgfx bool aon9; }; + struct DxbcSFI0 + { + uint64_t data; + }; + + struct DxbcSPDB + { + stl::vector debugCode; + }; + int32_t read(bx::ReaderSeekerI* _reader, DxbcShader& _shader, bx::Error* _err); int32_t write(bx::WriterI* _writer, const DxbcShader& _shader, bx::Error* _err); @@ -642,6 +652,8 @@ namespace bgfx typedef void (*DxbcFilterFn)(DxbcInstruction& _instruction, void* _userData); void filter(DxbcShader& _dst, const DxbcShader& _src, DxbcFilterFn _fn, void* _userData, bx::Error* _err = NULL); +#define DXBC_MAX_CHUNKS 32 + struct DxbcContext { struct Header @@ -657,6 +669,9 @@ namespace bgfx DxbcSignature inputSignature; DxbcSignature outputSignature; DxbcShader shader; + DxbcSFI0 sfi0; + DxbcSPDB spdb; + uint32_t chunksFourcc[DXBC_MAX_CHUNKS]; }; int32_t read(bx::ReaderSeekerI* _reader, DxbcContext& _dxbc, bx::Error* _err); diff --git a/tools/shaderc/shaderc.cpp b/tools/shaderc/shaderc.cpp index 3752640ad..8cb4a6f4f 100644 --- a/tools/shaderc/shaderc.cpp +++ b/tools/shaderc/shaderc.cpp @@ -13,13 +13,13 @@ extern "C" #include } // extern "C" -#define BGFX_SHADER_BIN_VERSION 8 +#define BGFX_SHADER_BIN_VERSION 9 #define BGFX_CHUNK_MAGIC_CSH BX_MAKEFOURCC('C', 'S', 'H', BGFX_SHADER_BIN_VERSION) #define BGFX_CHUNK_MAGIC_FSH BX_MAKEFOURCC('F', 'S', 'H', BGFX_SHADER_BIN_VERSION) #define BGFX_CHUNK_MAGIC_VSH BX_MAKEFOURCC('V', 'S', 'H', BGFX_SHADER_BIN_VERSION) #define BGFX_SHADERC_VERSION_MAJOR 1 -#define BGFX_SHADERC_VERSION_MINOR 16 +#define BGFX_SHADERC_VERSION_MINOR 17 namespace bgfx { diff --git a/tools/shaderc/shaderc_spirv.cpp b/tools/shaderc/shaderc_spirv.cpp index 371f0dd94..6c950d394 100644 --- a/tools/shaderc/shaderc_spirv.cpp +++ b/tools/shaderc/shaderc_spirv.cpp @@ -1023,7 +1023,7 @@ namespace bgfx { namespace spirv } } - // Loop through the separate_images, and extract the uniform names: + // Loop through the storage_images, and extract the uniform names: for (auto &resource : resourcesrefl.storage_images) { std::string name = refl.get_name(resource.id);