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);