diff --git a/bindings/bf/bgfx.bf b/bindings/bf/bgfx.bf
index 5c88429f5..207530bd8 100644
--- a/bindings/bf/bgfx.bf
+++ b/bindings/bf/bgfx.bf
@@ -4527,6 +4527,23 @@ public static class bgfx
[LinkName("bgfx_encoder_set_texture")]
public static extern void encoder_set_texture(Encoder* _this, uint8 _stage, UniformHandle _sampler, TextureHandle _handle, uint32 _flags);
+ ///
+ /// Set texture stage for draw primitive, selecting a sub-range of the
+ /// texture's array layers and mip levels.
+ ///
+ ///
+ /// Texture unit.
+ /// Program sampler.
+ /// Texture handle.
+ /// First array layer.
+ /// Number of array layers.
+ /// First (most detailed) mip level.
+ /// Number of mip levels.
+ /// Texture sampling mode. Default value UINT32_MAX uses texture sampling settings from the texture. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling.
+ ///
+ [LinkName("bgfx_encoder_set_texture_view")]
+ public static extern void encoder_set_texture_view(Encoder* _this, uint8 _stage, UniformHandle _sampler, TextureHandle _handle, uint16 _firstLayer, uint16 _numLayers, uint8 _firstMip, uint8 _numMips, uint32 _flags);
+
///
/// Submit an empty primitive for rendering. Uniforms and draw state
/// will be applied but no geometry will be submitted. Useful in cases
@@ -5173,6 +5190,23 @@ public static class bgfx
[LinkName("bgfx_set_texture")]
public static extern void set_texture(uint8 _stage, UniformHandle _sampler, TextureHandle _handle, uint32 _flags);
+ ///
+ /// Set texture stage for draw primitive, selecting a sub-range of the
+ /// texture's array layers and mip levels.
+ ///
+ ///
+ /// Texture unit.
+ /// Program sampler.
+ /// Texture handle.
+ /// First array layer.
+ /// Number of array layers.
+ /// First (most detailed) mip level.
+ /// Number of mip levels.
+ /// Texture sampling mode. Default value UINT32_MAX uses texture sampling settings from the texture. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling.
+ ///
+ [LinkName("bgfx_set_texture_view")]
+ public static extern void set_texture_view(uint8 _stage, UniformHandle _sampler, TextureHandle _handle, uint16 _firstLayer, uint16 _numLayers, uint8 _firstMip, uint8 _numMips, uint32 _flags);
+
///
/// Submit an empty primitive for rendering. Uniforms and draw state
/// will be applied but no geometry will be submitted.
diff --git a/bindings/c3/bgfx.c3 b/bindings/c3/bgfx.c3
index 5157359c5..16765ce91 100644
--- a/bindings/c3/bgfx.c3
+++ b/bindings/c3/bgfx.c3
@@ -3136,6 +3136,18 @@ extern fn void encoder_set_instance_count(Encoder* _this, uint _numInstances) @c
// _flags : `Texture sampling mode. Default value UINT32_MAX uses texture sampling settings from the texture. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling.`
extern fn void encoder_set_texture(Encoder* _this, char _stage, UniformHandle _sampler, TextureHandle _handle, uint _flags) @cname("bgfx_encoder_set_texture");
+// Set texture stage for draw primitive, selecting a sub-range of the
+// texture's array layers and mip levels.
+// _stage : `Texture unit.`
+// _sampler : `Program sampler.`
+// _handle : `Texture handle.`
+// _firstLayer : `First array layer.`
+// _numLayers : `Number of array layers.`
+// _firstMip : `First (most detailed) mip level.`
+// _numMips : `Number of mip levels.`
+// _flags : `Texture sampling mode. Default value UINT32_MAX uses texture sampling settings from the texture. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling.`
+extern fn void encoder_set_texture_view(Encoder* _this, char _stage, UniformHandle _sampler, TextureHandle _handle, ushort _firstLayer, ushort _numLayers, char _firstMip, char _numMips, uint _flags) @extern("bgfx_encoder_set_texture_view");
+
// Submit an empty primitive for rendering. Uniforms and draw state
// will be applied but no geometry will be submitted. Useful in cases
// when no other draw/compute primitive is submitted to view, but it's
@@ -3553,6 +3565,18 @@ extern fn void set_instance_count(uint _numInstances) @cname("bgfx_set_instance_
// _flags : `Texture sampling mode. Default value UINT32_MAX uses texture sampling settings from the texture. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling.`
extern fn void set_texture(char _stage, UniformHandle _sampler, TextureHandle _handle, uint _flags) @cname("bgfx_set_texture");
+// Set texture stage for draw primitive, selecting a sub-range of the
+// texture's array layers and mip levels.
+// _stage : `Texture unit.`
+// _sampler : `Program sampler.`
+// _handle : `Texture handle.`
+// _firstLayer : `First array layer.`
+// _numLayers : `Number of array layers.`
+// _firstMip : `First (most detailed) mip level.`
+// _numMips : `Number of mip levels.`
+// _flags : `Texture sampling mode. Default value UINT32_MAX uses texture sampling settings from the texture. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling.`
+extern fn void set_texture_view(char _stage, UniformHandle _sampler, TextureHandle _handle, ushort _firstLayer, ushort _numLayers, char _firstMip, char _numMips, uint _flags) @extern("bgfx_set_texture_view");
+
// Submit an empty primitive for rendering. Uniforms and draw state
// will be applied but no geometry will be submitted.
//
diff --git a/bindings/cs/bgfx.cs b/bindings/cs/bgfx.cs
index d3de03d7c..85f839b7a 100644
--- a/bindings/cs/bgfx.cs
+++ b/bindings/cs/bgfx.cs
@@ -4480,6 +4480,23 @@ public static partial class bgfx
[DllImport(DllName, EntryPoint="bgfx_encoder_set_texture", CallingConvention = CallingConvention.Cdecl)]
public static extern unsafe void encoder_set_texture(Encoder* _this, byte _stage, UniformHandle _sampler, TextureHandle _handle, uint _flags);
+ ///
+ /// Set texture stage for draw primitive, selecting a sub-range of the
+ /// texture's array layers and mip levels.
+ ///
+ ///
+ /// Texture unit.
+ /// Program sampler.
+ /// Texture handle.
+ /// First array layer.
+ /// Number of array layers.
+ /// First (most detailed) mip level.
+ /// Number of mip levels.
+ /// Texture sampling mode. Default value UINT32_MAX uses texture sampling settings from the texture. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling.
+ ///
+ [DllImport(DllName, EntryPoint="bgfx_encoder_set_texture_view", CallingConvention = CallingConvention.Cdecl)]
+ public static extern unsafe void encoder_set_texture_view(Encoder* _this, byte _stage, UniformHandle _sampler, TextureHandle _handle, ushort _firstLayer, ushort _numLayers, byte _firstMip, byte _numMips, uint _flags);
+
///
/// Submit an empty primitive for rendering. Uniforms and draw state
/// will be applied but no geometry will be submitted. Useful in cases
@@ -5126,6 +5143,23 @@ public static partial class bgfx
[DllImport(DllName, EntryPoint="bgfx_set_texture", CallingConvention = CallingConvention.Cdecl)]
public static extern unsafe void set_texture(byte _stage, UniformHandle _sampler, TextureHandle _handle, uint _flags);
+ ///
+ /// Set texture stage for draw primitive, selecting a sub-range of the
+ /// texture's array layers and mip levels.
+ ///
+ ///
+ /// Texture unit.
+ /// Program sampler.
+ /// Texture handle.
+ /// First array layer.
+ /// Number of array layers.
+ /// First (most detailed) mip level.
+ /// Number of mip levels.
+ /// Texture sampling mode. Default value UINT32_MAX uses texture sampling settings from the texture. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling.
+ ///
+ [DllImport(DllName, EntryPoint="bgfx_set_texture_view", CallingConvention = CallingConvention.Cdecl)]
+ public static extern unsafe void set_texture_view(byte _stage, UniformHandle _sampler, TextureHandle _handle, ushort _firstLayer, ushort _numLayers, byte _firstMip, byte _numMips, uint _flags);
+
///
/// Submit an empty primitive for rendering. Uniforms and draw state
/// will be applied but no geometry will be submitted.
diff --git a/bindings/d/package.d b/bindings/d/package.d
index 81c4f501d..2e44da2c5 100644
--- a/bindings/d/package.d
+++ b/bindings/d/package.d
@@ -9,7 +9,7 @@ import bindbc.common.types: c_int64, c_uint64, va_list;
import bindbc.bgfx.config;
static import bgfx.impl;
-enum uint apiVersion = 143;
+enum uint apiVersion = 144;
alias ViewID = ushort;
@@ -1772,6 +1772,26 @@ extern(C++, "bgfx") struct Encoder{
*/
{q{void}, q{setTexture}, q{ubyte stage, UniformHandle sampler, TextureHandle handle, uint flags=uint.max}, ext: `C++`},
+ /**
+ Set texture stage for draw primitive, selecting a sub-range of the
+ texture's array layers and mip levels.
+ Params:
+ stage = Texture unit.
+ sampler = Program sampler.
+ handle = Texture handle.
+ firstLayer = First array layer.
+ numLayers = Number of array layers.
+ firstMIP = First (most detailed) mip level.
+ numMIPs = Number of mip levels.
+ flags = Texture sampling mode. Default value UINT32_MAX uses
+ texture sampling settings from the texture.
+ - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap
+ mode.
+ - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic
+ sampling.
+ */
+ {q{void}, q{setTexture}, q{ubyte stage, UniformHandle sampler, TextureHandle handle, ushort firstLayer, ushort numLayers, ubyte firstMIP, ubyte numMIPs, uint flags=uint.max}, ext: `C++`},
+
/**
Submit an empty primitive for rendering. Uniforms and draw state
will be applied but no geometry will be submitted. Useful in cases
@@ -3726,6 +3746,26 @@ mixin(joinFnBinds((){
*/
{q{void}, q{setTexture}, q{ubyte stage, UniformHandle sampler, TextureHandle handle, uint flags=uint.max}, ext: `C++, "bgfx"`},
+ /**
+ * Set texture stage for draw primitive, selecting a sub-range of the
+ * texture's array layers and mip levels.
+ Params:
+ stage = Texture unit.
+ sampler = Program sampler.
+ handle = Texture handle.
+ firstLayer = First array layer.
+ numLayers = Number of array layers.
+ firstMIP = First (most detailed) mip level.
+ numMIPs = Number of mip levels.
+ flags = Texture sampling mode. Default value UINT32_MAX uses
+ texture sampling settings from the texture.
+ - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap
+ mode.
+ - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic
+ sampling.
+ */
+ {q{void}, q{setTexture}, q{ubyte stage, UniformHandle sampler, TextureHandle handle, ushort firstLayer, ushort numLayers, ubyte firstMIP, ubyte numMIPs, uint flags=uint.max}, ext: `C++, "bgfx"`},
+
/**
* Submit an empty primitive for rendering. Uniforms and draw state
* will be applied but no geometry will be submitted.
diff --git a/bindings/zig/bgfx.zig b/bindings/zig/bgfx.zig
index b6e303468..814d13ccb 100644
--- a/bindings/zig/bgfx.zig
+++ b/bindings/zig/bgfx.zig
@@ -1962,6 +1962,19 @@ pub const Init = extern struct {
pub inline fn setTexture(self: ?*Encoder, _stage: u8, _sampler: UniformHandle, _handle: TextureHandle, _flags: u32) void {
return bgfx_encoder_set_texture(self, _stage, _sampler, _handle, _flags);
}
+ /// Set texture stage for draw primitive, selecting a sub-range of the
+ /// texture's array layers and mip levels.
+ /// Texture unit.
+ /// Program sampler.
+ /// Texture handle.
+ /// First array layer.
+ /// Number of array layers.
+ /// First (most detailed) mip level.
+ /// Number of mip levels.
+ /// Texture sampling mode. Default value UINT32_MAX uses texture sampling settings from the texture. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling.
+ pub inline fn setTextureView(self: ?*Encoder, _stage: u8, _sampler: UniformHandle, _handle: TextureHandle, _firstLayer: u16, _numLayers: u16, _firstMip: u8, _numMips: u8, _flags: u32) void {
+ return bgfx_encoder_set_texture_view(self, _stage, _sampler, _handle, _firstLayer, _numLayers, _firstMip, _numMips, _flags);
+ }
/// Submit an empty primitive for rendering. Uniforms and draw state
/// will be applied but no geometry will be submitted. Useful in cases
/// when no other draw/compute primitive is submitted to view, but it's
@@ -3537,6 +3550,18 @@ extern fn bgfx_encoder_set_instance_count(self: ?*Encoder, _numInstances: u32) v
/// Texture sampling mode. Default value UINT32_MAX uses texture sampling settings from the texture. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling.
extern fn bgfx_encoder_set_texture(self: ?*Encoder, _stage: u8, _sampler: UniformHandle, _handle: TextureHandle, _flags: u32) void;
+/// Set texture stage for draw primitive, selecting a sub-range of the
+/// texture's array layers and mip levels.
+/// Texture unit.
+/// Program sampler.
+/// Texture handle.
+/// First array layer.
+/// Number of array layers.
+/// First (most detailed) mip level.
+/// Number of mip levels.
+/// Texture sampling mode. Default value UINT32_MAX uses texture sampling settings from the texture. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling.
+extern fn bgfx_encoder_set_texture_view(self: ?*Encoder, _stage: u8, _sampler: UniformHandle, _handle: TextureHandle, _firstLayer: u16, _numLayers: u16, _firstMip: u8, _numMips: u8, _flags: u32) void;
+
/// Submit an empty primitive for rendering. Uniforms and draw state
/// will be applied but no geometry will be submitted. Useful in cases
/// when no other draw/compute primitive is submitted to view, but it's
@@ -4047,6 +4072,21 @@ pub inline fn setTexture(_stage: u8, _sampler: UniformHandle, _handle: TextureHa
}
extern fn bgfx_set_texture(_stage: u8, _sampler: UniformHandle, _handle: TextureHandle, _flags: u32) void;
+/// Set texture stage for draw primitive, selecting a sub-range of the
+/// texture's array layers and mip levels.
+/// Texture unit.
+/// Program sampler.
+/// Texture handle.
+/// First array layer.
+/// Number of array layers.
+/// First (most detailed) mip level.
+/// Number of mip levels.
+/// Texture sampling mode. Default value UINT32_MAX uses texture sampling settings from the texture. - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap mode. - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic sampling.
+pub inline fn setTextureView(_stage: u8, _sampler: UniformHandle, _handle: TextureHandle, _firstLayer: u16, _numLayers: u16, _firstMip: u8, _numMips: u8, _flags: u32) void {
+ return bgfx_set_texture_view(_stage, _sampler, _handle, _firstLayer, _numLayers, _firstMip, _numMips, _flags);
+}
+extern fn bgfx_set_texture_view(_stage: u8, _sampler: UniformHandle, _handle: TextureHandle, _firstLayer: u16, _numLayers: u16, _firstMip: u8, _numMips: u8, _flags: u32) void;
+
/// Submit an empty primitive for rendering. Uniforms and draw state
/// will be applied but no geometry will be submitted.
///
diff --git a/docs/bgfx.rst b/docs/bgfx.rst
index 1c67f6454..6fd9fa0f4 100644
--- a/docs/bgfx.rst
+++ b/docs/bgfx.rst
@@ -454,7 +454,8 @@ Textures
Bind textures to texture stages for draw calls.
-.. doxygenfunction:: bgfx::setTexture
+.. doxygenfunction:: bgfx::setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint32_t _flags = UINT32_MAX)
+.. doxygenfunction:: bgfx::setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, uint32_t _flags = UINT32_MAX)
Uniforms
********
diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h
index 5c346adbd..67a4d31eb 100644
--- a/include/bgfx/bgfx.h
+++ b/include/bgfx/bgfx.h
@@ -1401,6 +1401,36 @@ namespace bgfx
, uint32_t _flags = UINT32_MAX
);
+ /// Set texture stage for draw primitive, selecting a sub-range of the
+ /// texture's array layers and mip levels.
+ ///
+ /// @param[in] _stage Texture unit.
+ /// @param[in] _sampler Program sampler.
+ /// @param[in] _handle Texture handle.
+ /// @param[in] _firstLayer First array layer.
+ /// @param[in] _numLayers Number of array layers.
+ /// @param[in] _firstMip First (most detailed) mip level.
+ /// @param[in] _numMips Number of mip levels.
+ /// @param[in] _flags Texture sampling mode. Default value UINT32_MAX uses
+ /// texture sampling settings from the texture.
+ /// - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap
+ /// mode.
+ /// - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic
+ /// sampling.
+ ///
+ /// @attention C99's equivalent binding is `bgfx_encoder_set_texture_view`.
+ ///
+ void setTexture(
+ uint8_t _stage
+ , UniformHandle _sampler
+ , TextureHandle _handle
+ , uint16_t _firstLayer
+ , uint16_t _numLayers
+ , uint8_t _firstMip
+ , uint8_t _numMips
+ , uint32_t _flags = UINT32_MAX
+ );
+
/// Submit an empty primitive for rendering. Uniforms and draw state
/// will be applied but no geometry will be submitted. Useful in cases
/// when no other draw/compute primitive is submitted to view, but it's
@@ -4358,6 +4388,36 @@ namespace bgfx
, uint32_t _flags = UINT32_MAX
);
+ /// Set texture stage for draw primitive, selecting a sub-range of the
+ /// texture's array layers and mip levels.
+ ///
+ /// @param[in] _stage Texture unit.
+ /// @param[in] _sampler Program sampler.
+ /// @param[in] _handle Texture handle.
+ /// @param[in] _firstLayer First array layer.
+ /// @param[in] _numLayers Number of array layers.
+ /// @param[in] _firstMip First (most detailed) mip level.
+ /// @param[in] _numMips Number of mip levels.
+ /// @param[in] _flags Texture sampling mode. Default value UINT32_MAX uses
+ /// texture sampling settings from the texture.
+ /// - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap
+ /// mode.
+ /// - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic
+ /// sampling.
+ ///
+ /// @attention C99's equivalent binding is `bgfx_set_texture_view`.
+ ///
+ void setTexture(
+ uint8_t _stage
+ , UniformHandle _sampler
+ , TextureHandle _handle
+ , uint16_t _firstLayer
+ , uint16_t _numLayers
+ , uint8_t _firstMip
+ , uint8_t _numMips
+ , uint32_t _flags = UINT32_MAX
+ );
+
/// Submit an empty primitive for rendering. Uniforms and draw state
/// will be applied but no geometry will be submitted.
///
diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h
index 6169ad6b9..1fb5c9f98 100644
--- a/include/bgfx/c99/bgfx.h
+++ b/include/bgfx/c99/bgfx.h
@@ -2919,6 +2919,27 @@ BGFX_C_API void bgfx_encoder_set_instance_count(bgfx_encoder_t* _this, uint32_t
*/
BGFX_C_API void bgfx_encoder_set_texture(bgfx_encoder_t* _this, uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint32_t _flags);
+/**
+ * Set texture stage for draw primitive, selecting a sub-range of the
+ * texture's array layers and mip levels.
+ *
+ * @param[in] _stage Texture unit.
+ * @param[in] _sampler Program sampler.
+ * @param[in] _handle Texture handle.
+ * @param[in] _firstLayer First array layer.
+ * @param[in] _numLayers Number of array layers.
+ * @param[in] _firstMip First (most detailed) mip level.
+ * @param[in] _numMips Number of mip levels.
+ * @param[in] _flags Texture sampling mode. Default value UINT32_MAX uses
+ * texture sampling settings from the texture.
+ * - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap
+ * mode.
+ * - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic
+ * sampling.
+ *
+ */
+BGFX_C_API void bgfx_encoder_set_texture_view(bgfx_encoder_t* _this, uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, uint32_t _flags);
+
/**
* Submit an empty primitive for rendering. Uniforms and draw state
* will be applied but no geometry will be submitted. Useful in cases
@@ -3553,6 +3574,27 @@ BGFX_C_API void bgfx_set_instance_count(uint32_t _numInstances);
*/
BGFX_C_API void bgfx_set_texture(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint32_t _flags);
+/**
+ * Set texture stage for draw primitive, selecting a sub-range of the
+ * texture's array layers and mip levels.
+ *
+ * @param[in] _stage Texture unit.
+ * @param[in] _sampler Program sampler.
+ * @param[in] _handle Texture handle.
+ * @param[in] _firstLayer First array layer.
+ * @param[in] _numLayers Number of array layers.
+ * @param[in] _firstMip First (most detailed) mip level.
+ * @param[in] _numMips Number of mip levels.
+ * @param[in] _flags Texture sampling mode. Default value UINT32_MAX uses
+ * texture sampling settings from the texture.
+ * - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap
+ * mode.
+ * - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic
+ * sampling.
+ *
+ */
+BGFX_C_API void bgfx_set_texture_view(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, uint32_t _flags);
+
/**
* Submit an empty primitive for rendering. Uniforms and draw state
* will be applied but no geometry will be submitted.
@@ -3893,6 +3935,7 @@ typedef enum bgfx_function_id
BGFX_FUNCTION_ID_ENCODER_SET_INSTANCE_DATA_FROM_DYNAMIC_VERTEX_BUFFER,
BGFX_FUNCTION_ID_ENCODER_SET_INSTANCE_COUNT,
BGFX_FUNCTION_ID_ENCODER_SET_TEXTURE,
+ BGFX_FUNCTION_ID_ENCODER_SET_TEXTURE_VIEW,
BGFX_FUNCTION_ID_ENCODER_TOUCH,
BGFX_FUNCTION_ID_ENCODER_SUBMIT,
BGFX_FUNCTION_ID_ENCODER_SUBMIT_OCCLUSION_QUERY,
@@ -3939,6 +3982,7 @@ typedef enum bgfx_function_id
BGFX_FUNCTION_ID_SET_INSTANCE_DATA_FROM_DYNAMIC_VERTEX_BUFFER,
BGFX_FUNCTION_ID_SET_INSTANCE_COUNT,
BGFX_FUNCTION_ID_SET_TEXTURE,
+ BGFX_FUNCTION_ID_SET_TEXTURE_VIEW,
BGFX_FUNCTION_ID_TOUCH,
BGFX_FUNCTION_ID_SUBMIT,
BGFX_FUNCTION_ID_SUBMIT_OCCLUSION_QUERY,
@@ -4102,6 +4146,7 @@ struct bgfx_interface_vtbl
void (*encoder_set_instance_data_from_dynamic_vertex_buffer)(bgfx_encoder_t* _this, bgfx_dynamic_vertex_buffer_handle_t _handle, uint32_t _startVertex, uint32_t _num);
void (*encoder_set_instance_count)(bgfx_encoder_t* _this, uint32_t _numInstances);
void (*encoder_set_texture)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint32_t _flags);
+ void (*encoder_set_texture_view)(bgfx_encoder_t* _this, uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, uint32_t _flags);
void (*encoder_touch)(bgfx_encoder_t* _this, bgfx_view_id_t _id);
void (*encoder_submit)(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, uint32_t _depth, uint8_t _flags);
void (*encoder_submit_occlusion_query)(bgfx_encoder_t* _this, bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_occlusion_query_handle_t _occlusionQuery, uint32_t _depth, uint8_t _flags);
@@ -4148,6 +4193,7 @@ struct bgfx_interface_vtbl
void (*set_instance_data_from_dynamic_vertex_buffer)(bgfx_dynamic_vertex_buffer_handle_t _handle, uint32_t _startVertex, uint32_t _num);
void (*set_instance_count)(uint32_t _numInstances);
void (*set_texture)(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint32_t _flags);
+ void (*set_texture_view)(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, uint32_t _flags);
void (*touch)(bgfx_view_id_t _id);
void (*submit)(bgfx_view_id_t _id, bgfx_program_handle_t _program, uint32_t _depth, uint8_t _flags);
void (*submit_occlusion_query)(bgfx_view_id_t _id, bgfx_program_handle_t _program, bgfx_occlusion_query_handle_t _occlusionQuery, uint32_t _depth, uint8_t _flags);
diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h
index faccff44c..e741a97c4 100644
--- a/include/bgfx/defines.h
+++ b/include/bgfx/defines.h
@@ -15,7 +15,7 @@
#ifndef BGFX_DEFINES_H_HEADER_GUARD
#define BGFX_DEFINES_H_HEADER_GUARD
-#define BGFX_API_VERSION UINT32_C(143)
+#define BGFX_API_VERSION UINT32_C(144)
/**
* Color RGB/alpha/depth write. When it's not specified write will be disabled.
diff --git a/scripts/bgfx.idl b/scripts/bgfx.idl
index 610e33847..855fbf962 100644
--- a/scripts/bgfx.idl
+++ b/scripts/bgfx.idl
@@ -1,7 +1,7 @@
-- vim: syntax=lua
-- bgfx interface
-version(143)
+version(144)
typedef "bool"
typedef "char"
@@ -2617,6 +2617,24 @@ func.Encoder.setTexture { section = "Draw/Textures" }
--- - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic
--- sampling.
+--- Set texture stage for draw primitive, selecting a sub-range of the
+--- texture's array layers and mip levels.
+func.Encoder.setTexture { cname = "set_texture_view", section = "Draw/Textures" }
+ "void"
+ .stage "uint8_t" --- Texture unit.
+ .sampler "UniformHandle" --- Program sampler.
+ .handle "TextureHandle" --- Texture handle.
+ .firstLayer "uint16_t" --- First array layer.
+ .numLayers "uint16_t" --- Number of array layers.
+ .firstMip "uint8_t" --- First (most detailed) mip level.
+ .numMips "uint8_t" --- Number of mip levels.
+ .flags "uint32_t" --- Texture sampling mode. Default value UINT32_MAX uses
+ { default = UINT32_MAX } --- texture sampling settings from the texture.
+ --- - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap
+ --- mode.
+ --- - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic
+ --- sampling.
+
--- Submit an empty primitive for rendering. Uniforms and draw state
--- will be applied but no geometry will be submitted. Useful in cases
--- when no other draw/compute primitive is submitted to view, but it's
@@ -3220,6 +3238,24 @@ func.setTexture { section = "Draw/Textures" }
--- - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic
--- sampling.
+--- Set texture stage for draw primitive, selecting a sub-range of the
+--- texture's array layers and mip levels.
+func.setTexture { cname = "set_texture_view", section = "Draw/Textures" }
+ "void"
+ .stage "uint8_t" --- Texture unit.
+ .sampler "UniformHandle" --- Program sampler.
+ .handle "TextureHandle" --- Texture handle.
+ .firstLayer "uint16_t" --- First array layer.
+ .numLayers "uint16_t" --- Number of array layers.
+ .firstMip "uint8_t" --- First (most detailed) mip level.
+ .numMips "uint8_t" --- Number of mip levels.
+ .flags "uint32_t" --- Texture sampling mode. Default value UINT32_MAX uses
+ { default = UINT32_MAX } --- texture sampling settings from the texture.
+ --- - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap
+ --- mode.
+ --- - `BGFX_SAMPLER_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic
+ --- sampling.
+
--- Submit an empty primitive for rendering. Uniforms and draw state
--- will be applied but no geometry will be submitted.
---
diff --git a/src/bgfx.cpp b/src/bgfx.cpp
index ae4190c1b..7c203f509 100644
--- a/src/bgfx.cpp
+++ b/src/bgfx.cpp
@@ -4183,6 +4183,24 @@ namespace bgfx
BGFX_ENCODER(setTexture(_stage, _sampler, _handle, _flags) );
}
+ void Encoder::setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, uint32_t _flags)
+ {
+ BGFX_CHECK_HANDLE("setTexture/UniformHandle", s_ctx->m_uniformHandle, _sampler);
+ BGFX_CHECK_HANDLE_INVALID_OK("setTexture/TextureHandle", s_ctx->m_textureHandle, _handle);
+ BX_ASSERT(_stage < g_caps.limits.maxTextureSamplers, "Invalid stage %d (max %d).", _stage, g_caps.limits.maxTextureSamplers);
+
+ if (isValid(_handle) )
+ {
+ const TextureRef& ref = s_ctx->m_textureRef[_handle.idx];
+ BX_ASSERT(!ref.isReadBack()
+ , "Can't sample from texture which was created with BGFX_TEXTURE_READ_BACK. This is CPU only texture."
+ );
+ BX_UNUSED(ref);
+ }
+
+ BGFX_ENCODER(setTexture(_stage, _sampler, _handle, _firstLayer, _numLayers, _firstMip, _numMips, _flags) );
+ }
+
void Encoder::touch(ViewId _id)
{
discard();
@@ -5884,6 +5902,12 @@ namespace bgfx
s_ctx->m_encoder0->setTexture(_stage, _sampler, _handle, _flags);
}
+ void setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, uint32_t _flags)
+ {
+ BGFX_CHECK_ENCODER0();
+ s_ctx->m_encoder0->setTexture(_stage, _sampler, _handle, _firstLayer, _numLayers, _firstMip, _numMips, _flags);
+ }
+
void touch(ViewId _id)
{
BGFX_CHECK_ENCODER0();
diff --git a/src/bgfx.idl.inl b/src/bgfx.idl.inl
index b28a39916..ad1e6b4a3 100644
--- a/src/bgfx.idl.inl
+++ b/src/bgfx.idl.inl
@@ -897,6 +897,14 @@ BGFX_C_API void bgfx_encoder_set_texture(bgfx_encoder_t* _this, uint8_t _stage,
This->setTexture(_stage, sampler.cpp, handle.cpp, _flags);
}
+BGFX_C_API void bgfx_encoder_set_texture_view(bgfx_encoder_t* _this, uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, uint32_t _flags)
+{
+ bgfx::Encoder* This = (bgfx::Encoder*)_this;
+ union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } sampler = { _sampler };
+ union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle = { _handle };
+ This->setTexture(_stage, sampler.cpp, handle.cpp, _firstLayer, _numLayers, _firstMip, _numMips, _flags);
+}
+
BGFX_C_API void bgfx_encoder_touch(bgfx_encoder_t* _this, bgfx_view_id_t _id)
{
bgfx::Encoder* This = (bgfx::Encoder*)_this;
@@ -1180,6 +1188,13 @@ BGFX_C_API void bgfx_set_texture(uint8_t _stage, bgfx_uniform_handle_t _sampler,
bgfx::setTexture(_stage, sampler.cpp, handle.cpp, _flags);
}
+BGFX_C_API void bgfx_set_texture_view(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, uint32_t _flags)
+{
+ union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } sampler = { _sampler };
+ union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle = { _handle };
+ bgfx::setTexture(_stage, sampler.cpp, handle.cpp, _firstLayer, _numLayers, _firstMip, _numMips, _flags);
+}
+
BGFX_C_API void bgfx_touch(bgfx_view_id_t _id)
{
bgfx::touch((bgfx::ViewId)_id);
@@ -1454,6 +1469,7 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version)
bgfx_encoder_set_instance_data_from_dynamic_vertex_buffer,
bgfx_encoder_set_instance_count,
bgfx_encoder_set_texture,
+ bgfx_encoder_set_texture_view,
bgfx_encoder_touch,
bgfx_encoder_submit,
bgfx_encoder_submit_occlusion_query,
@@ -1500,6 +1516,7 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version)
bgfx_set_instance_data_from_dynamic_vertex_buffer,
bgfx_set_instance_count,
bgfx_set_texture,
+ bgfx_set_texture_view,
bgfx_touch,
bgfx_submit,
bgfx_submit_occlusion_query,
diff --git a/src/bgfx_p.h b/src/bgfx_p.h
index 8ecde77c0..aba1a67c4 100644
--- a/src/bgfx_p.h
+++ b/src/bgfx_p.h
@@ -1799,12 +1799,93 @@ namespace bgfx
Count
};
+ void reset()
+ {
+ m_samplerFlags = BGFX_SAMPLER_NONE;
+ m_firstLayer = 0;
+ m_numLayers = UINT16_MAX;
+ m_idx = kInvalidHandle;
+ m_type = 0;
+ m_format = 0;
+ m_access = 0;
+ m_firstMip = 0;
+ m_numMips = UINT8_MAX;
+ }
+
+ void setTexture(TextureHandle _handle, uint32_t _samplerFlags, uint8_t _firstMip = 0, uint8_t _numMips = UINT8_MAX)
+ {
+ m_samplerFlags = _samplerFlags;
+ m_firstLayer = 0;
+ m_numLayers = UINT16_MAX;
+ m_idx = _handle.idx;
+ m_type = uint8_t(Binding::Texture);
+ m_format = 0;
+ m_access = 0;
+ m_firstMip = _firstMip;
+ m_numMips = _numMips;
+ }
+
+ void setTexture(TextureHandle _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, uint32_t _samplerFlags)
+ {
+ m_samplerFlags = _samplerFlags;
+ m_firstLayer = _firstLayer;
+ m_numLayers = _numLayers;
+ m_idx = _handle.idx;
+ m_type = uint8_t(Binding::Texture);
+ m_format = 0;
+ m_access = 0;
+ m_firstMip = _firstMip;
+ m_numMips = _numMips;
+ }
+
+ void setIndexBuffer(IndexBufferHandle _handle, Access::Enum _access)
+ {
+ m_samplerFlags = BGFX_SAMPLER_NONE;
+ m_firstLayer = 0;
+ m_numLayers = UINT16_MAX;
+ m_idx = _handle.idx;
+ m_type = uint8_t(Binding::IndexBuffer);
+ m_format = 0;
+ m_access = uint8_t(_access);
+ m_firstMip = 0;
+ m_numMips = UINT8_MAX;
+ }
+
+ void setBuffer(VertexBufferHandle _handle, Access::Enum _access)
+ {
+ m_samplerFlags = BGFX_SAMPLER_NONE;
+ m_firstLayer = 0;
+ m_numLayers = UINT16_MAX;
+ m_idx = _handle.idx;
+ m_type = uint8_t(Binding::VertexBuffer);
+ m_format = 0;
+ m_access = uint8_t(_access);
+ m_firstMip = 0;
+ m_numMips = UINT8_MAX;
+ }
+
+ void setImage(TextureHandle _handle, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format)
+ {
+ m_samplerFlags = BGFX_SAMPLER_NONE;
+ m_firstLayer = 0;
+ m_numLayers = UINT16_MAX;
+ m_idx = _handle.idx;
+ m_type = uint8_t(Binding::Image);
+ m_format = uint8_t(_format);
+ m_access = uint8_t(_access);
+ m_firstMip = _mip;
+ m_numMips = 1;
+ }
+
uint32_t m_samplerFlags;
+ uint16_t m_firstLayer;
+ uint16_t m_numLayers;
uint16_t m_idx;
uint8_t m_type;
uint8_t m_format;
uint8_t m_access;
- uint8_t m_mip;
+ uint8_t m_firstMip;
+ uint8_t m_numMips;
};
struct Stream
@@ -1830,12 +1911,8 @@ namespace bgfx
for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++ii)
{
Binding& bind = m_bind[ii];
- bind.m_idx = kInvalidHandle;
- bind.m_type = 0;
- bind.m_samplerFlags = 0;
- bind.m_format = 0;
- bind.m_access = 0;
- bind.m_mip = 0;
+ bind.reset();
+
}
}
};
@@ -3035,15 +3112,33 @@ namespace bgfx
void setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint32_t _flags)
{
Binding& bind = m_bind.m_bind[_stage];
- bind.m_idx = _handle.idx;
- bind.m_type = uint8_t(Binding::Texture);
- bind.m_samplerFlags = (_flags&BGFX_SAMPLER_INTERNAL_DEFAULT)
- ? BGFX_SAMPLER_INTERNAL_DEFAULT
- : _flags
- ;
- bind.m_format = 0;
- bind.m_access = 0;
- bind.m_mip = 0;
+ bind.setTexture(
+ _handle
+ , 0 != (_flags&BGFX_SAMPLER_INTERNAL_DEFAULT)
+ ? BGFX_SAMPLER_INTERNAL_DEFAULT
+ : _flags
+ );
+
+ if (isValid(_sampler) )
+ {
+ uint32_t stage = _stage;
+ setUniform(UniformType::Sampler, _sampler, &stage, 1);
+ }
+ }
+
+ void setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, uint32_t _flags)
+ {
+ Binding& bind = m_bind.m_bind[_stage];
+ bind.setTexture(
+ _handle
+ , _firstLayer
+ , _numLayers
+ , _firstMip
+ , _numMips
+ , 0 != (_flags&BGFX_SAMPLER_INTERNAL_DEFAULT)
+ ? BGFX_SAMPLER_INTERNAL_DEFAULT
+ : _flags
+ );
if (isValid(_sampler) )
{
@@ -3055,31 +3150,19 @@ namespace bgfx
void setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access)
{
Binding& bind = m_bind.m_bind[_stage];
- bind.m_idx = _handle.idx;
- bind.m_type = uint8_t(Binding::IndexBuffer);
- bind.m_format = 0;
- bind.m_access = uint8_t(_access);
- bind.m_mip = 0;
+ bind.setIndexBuffer(_handle, _access);
}
void setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access)
{
Binding& bind = m_bind.m_bind[_stage];
- bind.m_idx = _handle.idx;
- bind.m_type = uint8_t(Binding::VertexBuffer);
- bind.m_format = 0;
- bind.m_access = uint8_t(_access);
- bind.m_mip = 0;
+ bind.setBuffer(_handle, _access);
}
void setImage(uint8_t _stage, TextureHandle _handle, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format)
{
Binding& bind = m_bind.m_bind[_stage];
- bind.m_idx = _handle.idx;
- bind.m_type = uint8_t(Binding::Image);
- bind.m_format = uint8_t(_format);
- bind.m_access = uint8_t(_access);
- bind.m_mip = _mip;
+ bind.setImage(_handle, _mip, _access, _format);
}
void discard(uint8_t _flags)
diff --git a/src/glimports.h b/src/glimports.h
index e3a22ba49..c74a3e6e6 100644
--- a/src/glimports.h
+++ b/src/glimports.h
@@ -205,6 +205,7 @@ typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsi
typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
typedef void (GL_APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
typedef void (GL_APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value);
typedef void (GL_APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
@@ -407,6 +408,7 @@ GL_IMPORT______(true, PFNGLTEXSTORAGE2DPROC, glTexStorage2
GL_IMPORT______(true, PFNGLTEXSTORAGE3DPROC, glTexStorage3D);
GL_IMPORT______(false, PFNGLTEXSUBIMAGE2DPROC, glTexSubImage2D);
GL_IMPORT______(true, PFNGLTEXSUBIMAGE3DPROC, glTexSubImage3D);
+GL_IMPORT______(true, PFNGLTEXTUREVIEWPROC, glTextureView);
GL_IMPORT______(false, PFNGLUNIFORM1IPROC, glUniform1i);
GL_IMPORT______(false, PFNGLUNIFORM1IVPROC, glUniform1iv);
GL_IMPORT______(false, PFNGLUNIFORM1FPROC, glUniform1f);
@@ -534,8 +536,8 @@ GL_IMPORT_OES__(true, PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, glCompressedT
GL_IMPORT_EXT__(true, PFNGLTEXSTORAGE2DPROC, glTexStorage2D);
GL_IMPORT_EXT__(true, PFNGLTEXSTORAGE3DPROC, glTexStorage3D);
+GL_IMPORT_EXT__(true, PFNGLTEXTUREVIEWPROC, glTextureView);
GL_IMPORT______(true, PFNGLTEXIMAGE2DMULTISAMPLEPROC, glTexImage2DMultisample);
-GL_IMPORT______(true, PFNGLTEXIMAGE3DMULTISAMPLEPROC, glTexImage3DMultisample);
GL_IMPORT_EXT__(true, PFNGLFRAMEBUFFERTEXTUREPROC, glFramebufferTexture);
GL_IMPORT_EXT__(true, PFNGLFRAMEBUFFERTEXTURELAYERPROC, glFramebufferTextureLayer);
@@ -630,6 +632,7 @@ GL_IMPORT______(true, PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, glCompressedT
GL_IMPORT______(true, PFNGLTEXSTORAGE2DPROC, glTexStorage2D);
GL_IMPORT______(true, PFNGLTEXSTORAGE3DPROC, glTexStorage3D);
+GL_IMPORT______(true, PFNGLTEXTUREVIEWPROC, glTextureView);
GL_IMPORT______(true, PFNGLTEXIMAGE2DMULTISAMPLEPROC, glTexImage2DMultisample);
GL_IMPORT______(true, PFNGLTEXIMAGE3DMULTISAMPLEPROC, glTexImage3DMultisample);
diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp
index c46333935..d7522cc0d 100644
--- a/src/renderer_d3d11.cpp
+++ b/src/renderer_d3d11.cpp
@@ -3305,12 +3305,20 @@ namespace bgfx { namespace d3d11
return uav;
}
- ID3D11ShaderResourceView* getCachedSrv(TextureHandle _handle, uint8_t _mip, bool _compute = false, bool _stencil = false)
+ ID3D11ShaderResourceView* getCachedSrv(TextureHandle _handle, uint8_t _firstMip, uint8_t _numMips = 1, uint16_t _firstLayer = 0, uint16_t _numLayers = UINT16_MAX, bool _compute = false, bool _stencil = false)
{
+ const TextureD3D11& texture = m_textures[_handle.idx];
+
+ const uint8_t numMips = bx::min(_numMips, uint8_t(texture.m_numMips - _firstMip) );
+ const uint16_t numLayers = bx::min(_numLayers, uint16_t(texture.m_numLayers - _firstLayer) );
+
bx::HashMurmur2A murmur;
murmur.begin();
murmur.add(_handle);
- murmur.add(_mip);
+ murmur.add(_firstMip);
+ murmur.add(numMips);
+ murmur.add(_firstLayer);
+ murmur.add(numLayers);
murmur.add(0);
murmur.add(_compute);
murmur.add(_stencil);
@@ -3320,13 +3328,16 @@ namespace bgfx { namespace d3d11
ID3D11ShaderResourceView* srv;
if (NULL == ptr)
{
- const TextureD3D11& texture = m_textures[_handle.idx];
const uint32_t msaaQuality = bx::satSub(uint32_t( (texture.m_flags&BGFX_TEXTURE_RT_MSAA_MASK) >> BGFX_TEXTURE_RT_MSAA_SHIFT ), 1u);
const DXGI_SAMPLE_DESC& msaa = s_msaa[msaaQuality];
const bool msaaSample = 1 < msaa.Count && 0 != (texture.m_flags&BGFX_TEXTURE_MSAA_SAMPLE);
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
- desc.Format = _stencil ? DXGI_FORMAT_X24_TYPELESS_G8_UINT : texture.getSrvFormat();
+ desc.Format = _stencil
+ ? DXGI_FORMAT_X24_TYPELESS_G8_UINT
+ : texture.getSrvFormat()
+ ;
+
switch (texture.m_type)
{
case TextureD3D11::Texture2D:
@@ -3336,10 +3347,10 @@ namespace bgfx { namespace d3d11
? D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY
: D3D11_SRV_DIMENSION_TEXTURE2DARRAY
;
- desc.Texture2DArray.MostDetailedMip = _mip;
- desc.Texture2DArray.MipLevels = 1;
- desc.Texture2DArray.FirstArraySlice = 0;
- desc.Texture2DArray.ArraySize = texture.m_numLayers;
+ desc.Texture2DArray.MostDetailedMip = _firstMip;
+ desc.Texture2DArray.MipLevels = numMips;
+ desc.Texture2DArray.FirstArraySlice = _firstLayer;
+ desc.Texture2DArray.ArraySize = numLayers;
}
else
{
@@ -3347,20 +3358,21 @@ namespace bgfx { namespace d3d11
? D3D11_SRV_DIMENSION_TEXTURE2DMS
: D3D11_SRV_DIMENSION_TEXTURE2D
;
- desc.Texture2D.MostDetailedMip = _mip;
- desc.Texture2D.MipLevels = 1;
+ desc.Texture2D.MostDetailedMip = _firstMip;
+ desc.Texture2D.MipLevels = numMips;
}
break;
case TextureD3D11::TextureCube:
desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
- desc.TextureCube.MostDetailedMip = _mip;
- desc.TextureCube.MipLevels = 1;
+ desc.TextureCube.MostDetailedMip = _firstMip;
+ desc.TextureCube.MipLevels = numMips;
break;
+
case TextureD3D11::Texture3D:
desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
- desc.Texture3D.MostDetailedMip = _mip;
- desc.Texture3D.MipLevels = 1;
+ desc.Texture3D.MostDetailedMip = _firstMip;
+ desc.Texture3D.MipLevels = numMips;
break;
}
@@ -4833,19 +4845,41 @@ namespace bgfx { namespace d3d11
}
}
- void TextureD3D11::commit(uint8_t _stage, uint32_t _flags, const float _palette[][4])
+ void TextureD3D11::commit(uint8_t _stage, uint32_t _flags, const float _palette[][4], uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips)
{
TextureStage& ts = s_renderD3D11->m_textureStage;
+ const uint8_t numMips = bx::min(_numMips, uint8_t(m_numMips - _firstMip) );
+ const uint16_t numLayers = bx::min(_numLayers, uint16_t(m_numLayers - _firstLayer) );
+
+ const bool fullRange = 0 == _firstMip
+ && 0 == _firstLayer
+ && numMips == m_numMips
+ && numLayers == m_numLayers
+ ;
+
if (0 != (_flags & BGFX_SAMPLER_SAMPLE_STENCIL) )
{
ts.m_srv[_stage] = s_renderD3D11->getCachedSrv(
TextureHandle{ uint16_t(this - s_renderD3D11->m_textures) }
, 0
+ , 1
+ , 0
+ , UINT16_MAX
, false
, true
);
}
+ else if (!fullRange)
+ {
+ ts.m_srv[_stage] = s_renderD3D11->getCachedSrv(
+ TextureHandle{ uint16_t(this - s_renderD3D11->m_textures) }
+ , _firstMip
+ , numMips
+ , _firstLayer
+ , numLayers
+ );
+ }
else
{
ts.m_srv[_stage] = m_srv;
@@ -5840,14 +5874,14 @@ namespace bgfx { namespace d3d11
TextureD3D11& texture = m_textures[bind.m_idx];
if (Access::Read != bind.m_access)
{
- uav[stage] = 0 == bind.m_mip
+ uav[stage] = 0 == bind.m_firstMip
? texture.m_uav
- : s_renderD3D11->getCachedUav(texture.getHandle(), bind.m_mip)
+ : s_renderD3D11->getCachedUav(texture.getHandle(), bind.m_firstMip)
;
}
else
{
- m_textureStage.m_srv[stage] = s_renderD3D11->getCachedSrv(texture.getHandle(), bind.m_mip, true);
+ m_textureStage.m_srv[stage] = s_renderD3D11->getCachedSrv(texture.getHandle(), bind.m_firstMip, 1, 0, UINT16_MAX, true);
m_textureStage.m_sampler[stage] = s_renderD3D11->getSamplerState(uint32_t(texture.m_flags), NULL);
}
}
@@ -5856,7 +5890,7 @@ namespace bgfx { namespace d3d11
case Binding::Texture:
{
TextureD3D11& texture = m_textures[bind.m_idx];
- texture.commit(stage, bind.m_samplerFlags, _render->m_colorPalette);
+ texture.commit(stage, bind.m_samplerFlags, _render->m_colorPalette, bind.m_firstLayer, bind.m_numLayers, bind.m_firstMip, bind.m_numMips);
}
break;
@@ -6160,6 +6194,10 @@ namespace bgfx { namespace d3d11
if (current.m_idx != bind.m_idx
|| current.m_type != bind.m_type
|| current.m_samplerFlags != bind.m_samplerFlags
+ || current.m_firstLayer != bind.m_firstLayer
+ || current.m_numLayers != bind.m_numLayers
+ || current.m_firstMip != bind.m_firstMip
+ || current.m_numMips != bind.m_numMips
|| programChanged)
{
if (kInvalidHandle != bind.m_idx)
@@ -6171,14 +6209,14 @@ namespace bgfx { namespace d3d11
TextureD3D11& texture = m_textures[bind.m_idx];
if (Access::Read != bind.m_access)
{
- m_textureStage.m_uav[stage] = 0 == bind.m_mip
+ m_textureStage.m_uav[stage] = 0 == bind.m_firstMip
? texture.m_uav
- : s_renderD3D11->getCachedUav(texture.getHandle(), bind.m_mip)
+ : s_renderD3D11->getCachedUav(texture.getHandle(), bind.m_firstMip)
;
}
else
{
- m_textureStage.m_srv[stage] = s_renderD3D11->getCachedSrv(texture.getHandle(), bind.m_mip, true);
+ m_textureStage.m_srv[stage] = s_renderD3D11->getCachedSrv(texture.getHandle(), bind.m_firstMip, 1, 0, UINT16_MAX, true);
m_textureStage.m_sampler[stage] = s_renderD3D11->getSamplerState(uint32_t(texture.m_flags), NULL);
}
}
@@ -6187,7 +6225,7 @@ namespace bgfx { namespace d3d11
case Binding::Texture:
{
TextureD3D11& texture = m_textures[bind.m_idx];
- texture.commit(stage, bind.m_samplerFlags, _render->m_colorPalette);
+ texture.commit(stage, bind.m_samplerFlags, _render->m_colorPalette, bind.m_firstLayer, bind.m_numLayers, bind.m_firstMip, bind.m_numMips);
}
break;
diff --git a/src/renderer_d3d11.h b/src/renderer_d3d11.h
index d376185e5..d87a7776c 100644
--- a/src/renderer_d3d11.h
+++ b/src/renderer_d3d11.h
@@ -285,7 +285,7 @@ namespace bgfx { namespace d3d11
void destroy();
void overrideInternal(uintptr_t _ptr, uint16_t _layerIndex);
void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
- void commit(uint8_t _stage, uint32_t _flags, const float _palette[][4]);
+ void commit(uint8_t _stage, uint32_t _flags, const float _palette[][4], uint16_t _firstLayer = 0, uint16_t _numLayers = UINT16_MAX, uint8_t _firstMip = 0, uint8_t _numMips = UINT8_MAX);
void resolve(uint8_t _resolve, uint32_t _layer, uint32_t _numLayers, uint32_t _mip) const;
TextureHandle getHandle() const;
DXGI_FORMAT getSrvFormat() const;
diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp
index 2f2d4ef2c..0c1c2cc6f 100644
--- a/src/renderer_d3d12.cpp
+++ b/src/renderer_d3d12.cpp
@@ -4015,13 +4015,22 @@ namespace bgfx { namespace d3d12
return data;
}
- void ScratchBufferD3D12::allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, TextureD3D12& _texture, uint8_t _mip)
+ void ScratchBufferD3D12::allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, TextureD3D12& _texture, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips)
{
ID3D12Device* device = s_renderD3D12->m_device;
+ const uint8_t numMips = bx::min(_numMips, uint8_t(_texture.m_numMips - _firstMip) );
+ const uint16_t numLayers = bx::min(_numLayers, uint16_t(_texture.m_numLayers - _firstLayer) );
+
+ const bool fullRange = 0 == _firstMip
+ && 0 == _firstLayer
+ && numMips >= _texture.m_numMips
+ && numLayers >= _texture.m_numLayers
+ ;
+
D3D12_SHADER_RESOURCE_VIEW_DESC tmpSrvd;
D3D12_SHADER_RESOURCE_VIEW_DESC* srvd = &_texture.m_srvd;
- if (0 != _mip)
+ if (!fullRange)
{
bx::memCopy(&tmpSrvd, srvd, sizeof(tmpSrvd) );
srvd = &tmpSrvd;
@@ -4030,21 +4039,43 @@ namespace bgfx { namespace d3d12
{
default:
case D3D12_SRV_DIMENSION_TEXTURE2D:
- srvd->Texture2D.MostDetailedMip = _mip;
- srvd->Texture2D.MipLevels = 1;
- srvd->Texture2D.PlaneSlice = 0;
+ srvd->Texture2D.MostDetailedMip = _firstMip;
+ srvd->Texture2D.MipLevels = numMips;
+ srvd->Texture2D.PlaneSlice = 0;
srvd->Texture2D.ResourceMinLODClamp = 0;
break;
+ case D3D12_SRV_DIMENSION_TEXTURE2DARRAY:
+ srvd->Texture2DArray.MostDetailedMip = _firstMip;
+ srvd->Texture2DArray.MipLevels = numMips;
+ srvd->Texture2DArray.FirstArraySlice = _firstLayer;
+ srvd->Texture2DArray.ArraySize = numLayers;
+ srvd->Texture2DArray.PlaneSlice = 0;
+ srvd->Texture2DArray.ResourceMinLODClamp = 0;
+ break;
+
+ case D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY:
+ srvd->Texture2DMSArray.FirstArraySlice = _firstLayer;
+ srvd->Texture2DMSArray.ArraySize = numLayers;
+ break;
+
case D3D12_SRV_DIMENSION_TEXTURECUBE:
- srvd->TextureCube.MostDetailedMip = _mip;
- srvd->TextureCube.MipLevels = 1;
+ srvd->TextureCube.MostDetailedMip = _firstMip;
+ srvd->TextureCube.MipLevels = numMips;
srvd->TextureCube.ResourceMinLODClamp = 0;
break;
+ case D3D12_SRV_DIMENSION_TEXTURECUBEARRAY:
+ srvd->TextureCubeArray.MostDetailedMip = _firstMip;
+ srvd->TextureCubeArray.MipLevels = numMips;
+ srvd->TextureCubeArray.First2DArrayFace = _firstLayer;
+ srvd->TextureCubeArray.NumCubes = numLayers;
+ srvd->TextureCubeArray.ResourceMinLODClamp = 0;
+ break;
+
case D3D12_SRV_DIMENSION_TEXTURE3D:
- srvd->Texture3D.MostDetailedMip = _mip;
- srvd->Texture3D.MipLevels = 1;
+ srvd->Texture3D.MostDetailedMip = _firstMip;
+ srvd->Texture3D.MipLevels = numMips;
srvd->Texture3D.ResourceMinLODClamp = 0;
break;
}
@@ -5804,7 +5835,7 @@ namespace bgfx { namespace d3d12
}
else
{
- const uint32_t savedMipLevels = resourceDesc.MipLevels;
+ const uint16_t savedMipLevels = resourceDesc.MipLevels;
const D3D12_RESOURCE_FLAGS savedFlags = resourceDesc.Flags;
if (needResolve)
@@ -7293,12 +7324,12 @@ namespace bgfx { namespace d3d12
if (Access::Read != bind.m_access)
{
texture.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
- scratchBuffer.allocUav(srvHandle[stage], texture, bind.m_mip);
+ scratchBuffer.allocUav(srvHandle[stage], texture, bind.m_firstMip);
}
else
{
texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ);
- scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_mip);
+ scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_firstLayer, bind.m_numLayers, bind.m_firstMip, bind.m_numMips);
samplerFlags[stage] = uint32_t(texture.m_flags);
}
@@ -7310,7 +7341,7 @@ namespace bgfx { namespace d3d12
{
TextureD3D12& texture = m_textures[bind.m_idx];
texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ);
- scratchBuffer.allocSrv(srvHandle[stage], texture);
+ scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_firstLayer, bind.m_numLayers, bind.m_firstMip, bind.m_numMips);
samplerFlags[stage] = (0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & bind.m_samplerFlags)
? bind.m_samplerFlags
: texture.m_flags
@@ -7603,12 +7634,12 @@ namespace bgfx { namespace d3d12
if (Access::Read != bind.m_access)
{
texture.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
- scratchBuffer.allocUav(srvHandle[stage], texture, bind.m_mip);
+ scratchBuffer.allocUav(srvHandle[stage], texture, bind.m_firstMip);
}
else
{
texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ);
- scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_mip);
+ scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_firstLayer, bind.m_numLayers, bind.m_firstMip, bind.m_numMips);
samplerFlags[stage] = uint32_t(texture.m_flags);
}
@@ -7620,7 +7651,7 @@ namespace bgfx { namespace d3d12
{
TextureD3D12& texture = m_textures[bind.m_idx];
texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ);
- scratchBuffer.allocSrv(srvHandle[stage], texture);
+ scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_firstLayer, bind.m_numLayers, bind.m_firstMip, bind.m_numMips);
samplerFlags[stage] = (0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & bind.m_samplerFlags)
? bind.m_samplerFlags
: texture.m_flags
diff --git a/src/renderer_d3d12.h b/src/renderer_d3d12.h
index cdf190288..ea5c8becf 100644
--- a/src/renderer_d3d12.h
+++ b/src/renderer_d3d12.h
@@ -122,7 +122,7 @@ namespace bgfx { namespace d3d12
void* allocCbv(D3D12_GPU_VIRTUAL_ADDRESS& _gpuAddress, uint32_t _size);
- void allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct TextureD3D12& _texture, uint8_t _mip = 0);
+ void allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct TextureD3D12& _texture, uint16_t _firstLayer = 0, uint16_t _numLayers = UINT16_MAX, uint8_t _firstMip = 0, uint8_t _numMips = UINT8_MAX);
void allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct BufferD3D12& _buffer);
void allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct TextureD3D12& _texture, uint8_t _mip = 0);
diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp
index d98bdf9d5..9df640b2f 100644
--- a/src/renderer_gl.cpp
+++ b/src/renderer_gl.cpp
@@ -609,6 +609,7 @@ namespace bgfx { namespace gl
ARB_texture_stencil8,
ARB_texture_storage,
ARB_texture_swizzle,
+ ARB_texture_view,
ARB_timer_query,
ARB_uniform_buffer_object,
ARB_vertex_array_object,
@@ -666,6 +667,7 @@ namespace bgfx { namespace gl
EXT_texture_sRGB,
EXT_texture_storage,
EXT_texture_swizzle,
+ EXT_texture_view,
EXT_texture_type_2_10_10_10_REV,
EXT_timer_query,
EXT_unpack_subimage,
@@ -720,6 +722,7 @@ namespace bgfx { namespace gl
OES_texture_half_float_linear,
OES_texture_stencil8,
OES_texture_storage_multisample_2d_array,
+ OES_texture_view,
OES_vertex_array_object,
OES_vertex_half_float,
OES_vertex_type_10_10_10_2,
@@ -827,6 +830,7 @@ namespace bgfx { namespace gl
{ "ARB_texture_stencil8", false, true },
{ "ARB_texture_storage", BGFX_CONFIG_RENDERER_OPENGL >= 42, true },
{ "ARB_texture_swizzle", BGFX_CONFIG_RENDERER_OPENGL >= 33, true },
+ { "ARB_texture_view", BGFX_CONFIG_RENDERER_OPENGL >= 43, true },
{ "ARB_timer_query", BGFX_CONFIG_RENDERER_OPENGL >= 33, true },
{ "ARB_uniform_buffer_object", BGFX_CONFIG_RENDERER_OPENGL >= 31, true },
{ "ARB_vertex_array_object", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
@@ -884,6 +888,7 @@ namespace bgfx { namespace gl
{ "EXT_texture_sRGB", false, true },
{ "EXT_texture_storage", false, true },
{ "EXT_texture_swizzle", false, true },
+ { "EXT_texture_view", false, true },
{ "EXT_texture_type_2_10_10_10_REV", false, true },
{ "EXT_timer_query", BGFX_CONFIG_RENDERER_OPENGL >= 33, true },
{ "EXT_unpack_subimage", false, true },
@@ -938,6 +943,7 @@ namespace bgfx { namespace gl
{ "OES_texture_half_float_linear", false, true },
{ "OES_texture_stencil8", false, true },
{ "OES_texture_storage_multisample_2d_array", false, true },
+ { "OES_texture_view", false, true },
{ "OES_vertex_array_object", false, true },
{ "OES_vertex_half_float", false, true },
{ "OES_vertex_type_10_10_10_2", false, true },
@@ -2249,6 +2255,7 @@ namespace bgfx { namespace gl
, m_maxMsaa(0)
, m_vao(0)
, m_blitSupported(false)
+ , m_textureViewSupported(false)
, m_readBackSupported(BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) )
, m_vaoSupport(false)
, m_samplerObjectSupport(false)
@@ -2906,6 +2913,13 @@ namespace bgfx { namespace gl
m_blitSupported = NULL != glCopyImageSubData;
}
+ if (s_extension[Extension::ARB_texture_view].m_supported
+ || s_extension[Extension::EXT_texture_view].m_supported
+ || s_extension[Extension::OES_texture_view].m_supported)
+ {
+ m_textureViewSupported = NULL != glTextureView;
+ }
+
g_caps.supported |= m_blitSupported || BX_ENABLED(BGFX_GL_CONFIG_BLIT_EMULATION)
? BGFX_CAPS_TEXTURE_BLIT
: 0
@@ -4220,6 +4234,8 @@ namespace bgfx { namespace gl
{
m_samplerStateCache.invalidate();
}
+
+ m_textureViewStateCache.invalidate();
}
void setSamplerState(uint32_t _stage, uint32_t _numMips, uint32_t _flags, const float _rgba[4])
@@ -4810,6 +4826,7 @@ namespace bgfx { namespace gl
OcclusionQueryGL m_occlusionQuery;
SamplerStateCache m_samplerStateCache;
+ TextureViewStateCache m_textureViewStateCache;
UniformStateCache m_uniformStateCache;
TextVideoMem m_textVideoMem;
@@ -4827,6 +4844,7 @@ namespace bgfx { namespace gl
GLuint m_vao;
uint16_t m_maxLabelLen;
bool m_blitSupported;
+ bool m_textureViewSupported;
bool m_readBackSupported;
bool m_vaoSupport;
bool m_samplerObjectSupport;
@@ -5628,6 +5646,9 @@ namespace bgfx { namespace gl
: s_textureFormat[m_textureFormat].m_internalFmt
;
+ m_internalFmt = internalFmt;
+ m_numLayers = textureArray ? _depth : 1;
+
if (textureArray)
{
GL_CHECK(glTexStorage3D(_target
@@ -5637,6 +5658,7 @@ namespace bgfx { namespace gl
, m_height
, _depth
) );
+ m_immutableStorage = true;
}
else if (computeWrite)
{
@@ -5659,6 +5681,7 @@ namespace bgfx { namespace gl
, m_height
) );
}
+ m_immutableStorage = true;
}
setSamplerState(uint32_t(_flags), NULL);
@@ -5979,6 +6002,8 @@ namespace bgfx { namespace gl
void TextureGL::destroy()
{
+ s_renderGL->m_textureViewStateCache.invalidateWithParent(uint16_t(this - s_renderGL->m_textures) );
+
if (0 == (m_flags & BGFX_SAMPLER_INTERNAL_SHARED)
&& 0 != m_id)
{
@@ -6233,7 +6258,60 @@ namespace bgfx { namespace gl
}
}
- void TextureGL::commit(uint32_t _stage, uint32_t _flags, const float _palette[][4])
+ GLuint TextureGL::getViewId(uint8_t _firstMip, uint8_t _numMips, uint16_t _firstLayer, uint16_t _numLayers)
+ {
+ const uint8_t firstMip = bx::min(_firstMip, uint8_t(m_numMips - 1) );
+ const uint8_t numMips = bx::min(_numMips, uint8_t(m_numMips - firstMip) );
+ const uint16_t numLayers0 = uint16_t(bx::max(m_numLayers, 1) );
+ const uint16_t firstLayer = bx::min(_firstLayer, uint16_t(numLayers0 - 1) );
+ const uint16_t numLayers = bx::min(_numLayers, uint16_t(numLayers0 - firstLayer) );
+
+ const bool fullRange = 0 == firstMip
+ && numMips >= m_numMips
+ && 0 == firstLayer
+ && numLayers >= numLayers0
+ ;
+
+ if (fullRange
+ || !s_renderGL->m_textureViewSupported
+ || !m_immutableStorage
+ || GL_ZERO == m_internalFmt
+ || NULL == glTextureView)
+ {
+ return m_id;
+ }
+
+ const uint16_t parent = uint16_t(this - s_renderGL->m_textures);
+
+ const uint64_t key = 0
+ | (uint64_t(parent) << 48)
+ | (uint64_t(firstMip) << 40)
+ | (uint64_t(numMips) << 32)
+ | (uint64_t(firstLayer) << 16)
+ | (uint64_t(numLayers) << 0)
+ ;
+
+ GLuint viewId = s_renderGL->m_textureViewStateCache.find(key);
+ if (UINT32_MAX != viewId)
+ {
+ return viewId;
+ }
+
+ viewId = s_renderGL->m_textureViewStateCache.add(key, parent);
+ GL_CHECK(glTextureView(viewId
+ , m_target
+ , m_id
+ , m_internalFmt
+ , firstMip
+ , numMips
+ , firstLayer
+ , numLayers
+ ) );
+
+ return viewId;
+ }
+
+ void TextureGL::commit(uint32_t _stage, uint32_t _flags, const float _palette[][4], uint8_t _firstMip, uint8_t _numMips, uint16_t _firstLayer, uint16_t _numLayers)
{
const uint32_t flags = 0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & _flags)
? _flags
@@ -6241,8 +6319,10 @@ namespace bgfx { namespace gl
;
const uint32_t index = (flags & BGFX_SAMPLER_BORDER_COLOR_MASK) >> BGFX_SAMPLER_BORDER_COLOR_SHIFT;
+ const GLuint id = getViewId(_firstMip, _numMips, _firstLayer, _numLayers);
+
GL_CHECK(glActiveTexture(GL_TEXTURE0+_stage) );
- GL_CHECK(glBindTexture(m_target, m_id) );
+ GL_CHECK(glBindTexture(m_target, id) );
if (s_renderGL->m_samplerObjectSupport)
{
@@ -7747,7 +7827,7 @@ namespace bgfx { namespace gl
case Binding::Texture:
{
TextureGL& texture = m_textures[bind.m_idx];
- texture.commit(ii, bind.m_samplerFlags, _render->m_colorPalette);
+ texture.commit(ii, bind.m_samplerFlags, _render->m_colorPalette, bind.m_firstMip, bind.m_numMips, bind.m_firstLayer, bind.m_numLayers);
}
break;
@@ -7756,7 +7836,7 @@ namespace bgfx { namespace gl
const TextureGL& texture = m_textures[bind.m_idx];
GL_CHECK(glBindImageTexture(ii
, texture.m_id
- , bind.m_mip
+ , bind.m_firstMip
, texture.isCubeMap() || texture.m_target == GL_TEXTURE_2D_ARRAY ? GL_TRUE : GL_FALSE
, 0
, s_access[bind.m_access]
@@ -8270,13 +8350,13 @@ namespace bgfx { namespace gl
{
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])
- );
+ , texture.m_id
+ , bind.m_firstMip
+ , 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;
@@ -8284,7 +8364,7 @@ namespace bgfx { namespace gl
case Binding::Texture:
{
TextureGL& texture = m_textures[bind.m_idx];
- texture.commit(stage, bind.m_samplerFlags, _render->m_colorPalette);
+ texture.commit(stage, bind.m_samplerFlags, _render->m_colorPalette, bind.m_firstMip, bind.m_numMips, bind.m_firstLayer, bind.m_numLayers);
}
break;
diff --git a/src/renderer_gl.h b/src/renderer_gl.h
index a85dec920..5eb5760bf 100644
--- a/src/renderer_gl.h
+++ b/src/renderer_gl.h
@@ -1343,6 +1343,85 @@ namespace bgfx { namespace gl
HashMap m_hashMap;
};
+ class TextureViewStateCache
+ {
+ public:
+ GLuint add(uint64_t _key, uint16_t _parent)
+ {
+ invalidate(_key);
+
+ GLuint viewId;
+ GL_CHECK(glGenTextures(1, &viewId) );
+
+ m_hashMap.insert(stl::make_pair(_key, Data{viewId, _parent}) );
+
+ return viewId;
+ }
+
+ GLuint find(uint64_t _key)
+ {
+ HashMap::iterator it = m_hashMap.find(_key);
+ if (it != m_hashMap.end() )
+ {
+ return it->second.m_textureViewId;
+ }
+
+ return UINT32_MAX;
+ }
+
+ void invalidate(uint64_t _key)
+ {
+ HashMap::iterator it = m_hashMap.find(_key);
+ if (it != m_hashMap.end() )
+ {
+ GL_CHECK(glDeleteTextures(1, &it->second.m_textureViewId) );
+ m_hashMap.erase(it);
+ }
+ }
+
+ void invalidateWithParent(uint16_t _parent)
+ {
+ for (HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd;)
+ {
+ if (it->second.m_parent == _parent)
+ {
+ GL_CHECK(glDeleteTextures(1, &it->second.m_textureViewId) );
+ HashMap::iterator itErase = it;
+ ++it;
+ m_hashMap.erase(itErase);
+ }
+ else
+ {
+ ++it;
+ }
+ }
+ }
+
+ void invalidate()
+ {
+ for (HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
+ {
+ GL_CHECK(glDeleteTextures(1, &it->second.m_textureViewId) );
+ }
+ m_hashMap.clear();
+ }
+
+ uint32_t getCount() const
+ {
+ return uint32_t(m_hashMap.size() );
+ }
+
+ private:
+ struct Data
+ {
+ GLuint m_textureViewId;
+ uint16_t m_parent;
+ };
+
+ typedef stl::unordered_map HashMap;
+ HashMap m_hashMap;
+ };
+
struct IndexBufferGL
{
void create(uint32_t _size, void* _data, uint16_t _flags)
@@ -1445,9 +1524,11 @@ namespace bgfx { namespace gl
, m_target(GL_TEXTURE_2D)
, m_fmt(GL_ZERO)
, m_type(GL_ZERO)
+ , m_internalFmt(GL_ZERO)
, m_flags(0)
, m_currentSamplerHash(UINT32_MAX)
, m_numMips(0)
+ , m_immutableStorage(false)
{
}
@@ -1457,7 +1538,8 @@ namespace bgfx { namespace gl
void overrideInternal(uintptr_t _ptr);
void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
void setSamplerState(uint32_t _flags, const float _rgba[4]);
- void commit(uint32_t _stage, uint32_t _flags, const float _palette[][4]);
+ void commit(uint32_t _stage, uint32_t _flags, const float _palette[][4], uint8_t _firstMip, uint8_t _numMips, uint16_t _firstLayer, uint16_t _numLayers);
+ GLuint getViewId(uint8_t _firstMip, uint8_t _numMips, uint16_t _firstLayer, uint16_t _numLayers);
void resolve(uint8_t _resolve) const;
bool isCubeMap() const
@@ -1473,6 +1555,7 @@ namespace bgfx { namespace gl
GLenum m_target;
GLenum m_fmt;
GLenum m_type;
+ GLenum m_internalFmt;
uint64_t m_flags;
uint32_t m_currentSamplerHash;
uint32_t m_width;
@@ -1482,6 +1565,7 @@ namespace bgfx { namespace gl
uint8_t m_numMips;
uint8_t m_requestedFormat;
uint8_t m_textureFormat;
+ bool m_immutableStorage;
};
struct ShaderGL
diff --git a/src/renderer_mtl.cpp b/src/renderer_mtl.cpp
index 457aaac19..6139dda35 100644
--- a/src/renderer_mtl.cpp
+++ b/src/renderer_mtl.cpp
@@ -3645,6 +3645,13 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
{
MTL_RELEASE_W(m_ptrMips[ii], 0);
}
+
+ for (stl::unordered_map::iterator it = m_ptrViews.begin(), itEnd = m_ptrViews.end(); it != itEnd; ++it)
+ {
+ MTL::Texture* view = it->second;
+ MTL_RELEASE_W(view, 0);
+ }
+ m_ptrViews.clear();
}
void TextureMtl::overrideInternal(uintptr_t _ptr)
@@ -3760,11 +3767,11 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
}
}
- void TextureMtl::commit(uint8_t _stage, bool _vertex, bool _fragment, uint32_t _flags, uint8_t _mip)
+ void TextureMtl::commit(uint8_t _stage, bool _vertex, bool _fragment, uint32_t _flags, uint8_t _mip, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips)
{
if (_vertex)
{
- MTL::Texture* p = _mip != UINT8_MAX ? getTextureMipLevel(_mip) : m_ptr;
+ MTL::Texture* p = _mip != UINT8_MAX ? getTextureMipLevel(_mip) : getTextureView(_firstLayer, _numLayers, _firstMip, _numMips);
s_renderMtl->m_renderCommandEncoder->setVertexTexture(p, _stage);
s_renderMtl->m_renderCommandEncoder->setVertexSamplerState(
0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & _flags)
@@ -3776,7 +3783,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
if (_fragment)
{
- MTL::Texture* p = _mip != UINT8_MAX ? getTextureMipLevel(_mip) : m_ptr;
+ MTL::Texture* p = _mip != UINT8_MAX ? getTextureMipLevel(_mip) : getTextureView(_firstLayer, _numLayers, _firstMip, _numMips);
s_renderMtl->m_renderCommandEncoder->setFragmentTexture(p, _stage);
s_renderMtl->m_renderCommandEncoder->setFragmentSamplerState(
0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & _flags)
@@ -3787,6 +3794,55 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
}
}
+ MTL::Texture* TextureMtl::getTextureView(uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips)
+ {
+ if (NULL == m_ptr)
+ {
+ return NULL;
+ }
+
+ const uint32_t totalLayers = uint32_t(m_ptr->arrayLength() * (TextureCube == m_type ? 6 : 1) );
+
+ const uint8_t firstMip = bx::min(_firstMip, uint8_t(m_numMips - 1) );
+ const uint8_t numMips = bx::min(_numMips, uint8_t(m_numMips - firstMip) );
+ const uint32_t firstLayer = bx::min(_firstLayer, totalLayers - 1);
+ const uint32_t numLayers = bx::min(_numLayers, totalLayers - firstLayer);
+
+ const bool fullRange = 0 == firstMip
+ && 0 == firstLayer
+ && numMips >= m_numMips
+ && numLayers >= totalLayers
+ ;
+
+ if (fullRange)
+ {
+ return m_ptr;
+ }
+
+ const uint64_t key = 0
+ | uint64_t(firstMip)
+ | (uint64_t(numMips) << 8)
+ | (uint64_t(firstLayer) << 16)
+ | (uint64_t(numLayers) << 32)
+ ;
+
+ stl::unordered_map::iterator it = m_ptrViews.find(key);
+ if (it != m_ptrViews.end() )
+ {
+ return it->second;
+ }
+
+ MTL::Texture* view = m_ptr->newTextureView(
+ m_ptr->pixelFormat()
+ , TextureCube == m_type ? (MTL::TextureType)MTL::TextureType2DArray : m_ptr->textureType()
+ , NS::Range::Make(firstMip, numMips)
+ , NS::Range::Make(firstLayer, numLayers)
+ );
+ m_ptrViews[key] = view;
+
+ return view;
+ }
+
MTL::Texture* TextureMtl::getTextureMipLevel(uint8_t _mip)
{
_mip = bx::clamp(_mip, 0, m_numMips);
@@ -5090,7 +5146,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
case Binding::Image:
{
TextureMtl& texture = m_textures[bind.m_idx];
- m_computeCommandEncoder->setTexture(texture.getTextureMipLevel(bind.m_mip), stage);
+ m_computeCommandEncoder->setTexture(texture.getTextureMipLevel(bind.m_firstMip), stage);
}
break;
@@ -5509,7 +5565,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
, 0 != (bindingTypes[stage] & PipelineStateMtl::BindToVertexShader)
, 0 != (bindingTypes[stage] & PipelineStateMtl::BindToFragmentShader)
, bind.m_samplerFlags
- , bind.m_mip
+ , bind.m_firstMip
);
}
break;
@@ -5522,6 +5578,11 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
, 0 != (bindingTypes[stage] & PipelineStateMtl::BindToVertexShader)
, 0 != (bindingTypes[stage] & PipelineStateMtl::BindToFragmentShader)
, bind.m_samplerFlags
+ , UINT8_MAX
+ , bind.m_firstLayer
+ , bind.m_numLayers
+ , bind.m_firstMip
+ , bind.m_numMips
);
}
break;
diff --git a/src/renderer_mtl.h b/src/renderer_mtl.h
index 3f87afc60..6c95bca7a 100644
--- a/src/renderer_mtl.h
+++ b/src/renderer_mtl.h
@@ -500,14 +500,20 @@ namespace bgfx { namespace mtl
, bool _fragment
, uint32_t _flags = BGFX_SAMPLER_INTERNAL_DEFAULT
, uint8_t _mip = UINT8_MAX
+ , uint16_t _firstLayer = 0
+ , uint16_t _numLayers = UINT16_MAX
+ , uint8_t _firstMip = 0
+ , uint8_t _numMips = UINT8_MAX
);
MTL::Texture* getTextureMipLevel(uint8_t _mip);
+ MTL::Texture* getTextureView(uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips);
MTL::Texture* m_ptr;
MTL::Texture* m_ptrMsaa;
MTL::Texture* m_ptrStencil; // for emulating packed depth/stencil formats - only for iOS8...
MTL::Texture* m_ptrMips[14];
+ stl::unordered_map m_ptrViews;
MTL::SamplerState* m_sampler;
uint64_t m_flags;
uint32_t m_width;
diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp
index bf7b33697..ea68b212d 100644
--- a/src/renderer_vk.cpp
+++ b/src/renderer_vk.cpp
@@ -3750,19 +3750,26 @@ VK_IMPORT_DEVICE
return sampler;
}
- VkImageView getCachedImageView(TextureHandle _handle, uint32_t _mip, uint32_t _numMips, VkImageViewType _type, bool _stencil = false)
+ VkImageView getCachedImageView(TextureHandle _handle, uint32_t _mip, uint32_t _numMips, VkImageViewType _type, bool _stencil = false, uint32_t _firstLayer = 0, uint32_t _numLayers = UINT32_MAX)
{
const TextureVK& texture = m_textures[_handle.idx];
_stencil = _stencil && !!(texture.m_aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT);
+ const uint32_t firstLayer = bx::min(_firstLayer, texture.m_numSides);
+ const uint32_t numLayers = bx::min(_numLayers, texture.m_numSides - firstLayer);
+ const uint32_t firstMip = bx::min(_mip, texture.m_numMips);
+ const uint32_t numMips = bx::min(_numMips, texture.m_numMips - firstMip);
+
bx::HashMurmur2A hash;
hash.begin();
hash.add(_handle.idx);
- hash.add(_mip);
- hash.add(_numMips);
+ hash.add(firstMip);
+ hash.add(numMips);
hash.add(_type);
hash.add(_stencil);
+ hash.add(firstLayer);
+ hash.add(numLayers);
uint32_t hashKey = hash.end();
VkImageView* viewCached = m_imageViewCache.find(hashKey);
@@ -3778,7 +3785,7 @@ VK_IMPORT_DEVICE
;
VkImageView view;
- VK_CHECK(texture.createView(0, texture.m_numSides, _mip, _numMips, _type, aspectMask, false, &view) );
+ VK_CHECK(texture.createView(firstLayer, numLayers, firstMip, numMips, _type, aspectMask, false, &view) );
m_imageViewCache.add(hashKey, view, _handle.idx);
return view;
@@ -4149,8 +4156,8 @@ VK_IMPORT_DEVICE
imageInfo[imageCount].sampler = VK_NULL_HANDLE;
imageInfo[imageCount].imageView = getCachedImageView(
{ bind.m_idx }
- , bind.m_mip
- , 1
+ , bind.m_firstMip
+ , bind.m_numMips
, type
);
wds[wdsCount].pImageInfo = &imageInfo[imageCount];
@@ -4210,10 +4217,12 @@ VK_IMPORT_DEVICE
imageInfo[imageCount].sampler = sampler;
imageInfo[imageCount].imageView = getCachedImageView(
{ bind.m_idx }
- , 0
- , texture.m_numMips
+ , bind.m_firstMip
+ , bind.m_numMips
, type
, sampleStencil
+ , bind.m_firstLayer
+ , bind.m_numLayers
);
wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
diff --git a/src/renderer_webgpu.cpp b/src/renderer_webgpu.cpp
index f07508024..2c049bbff 100644
--- a/src/renderer_webgpu.cpp
+++ b/src/renderer_webgpu.cpp
@@ -1976,12 +1976,7 @@ WGPU_IMPORT
RenderBind renderBind;
renderBind.clear();
Binding& bind = renderBind.m_bind[0];
- bind.m_idx = _blitter.m_texture.idx;
- bind.m_type = uint8_t(Binding::Texture);
- bind.m_samplerFlags = uint32_t(texture.m_flags & BGFX_SAMPLER_BITS_MASK);
- bind.m_format = 0;
- bind.m_access = 0;
- bind.m_mip = 0;
+ bind.setTexture(_blitter.m_texture, uint32_t(texture.m_flags & BGFX_SAMPLER_BITS_MASK) );
const Stream stream =
{
@@ -3055,8 +3050,8 @@ WGPU_IMPORT
.size = 0,
.sampler = NULL,
.textureView = _isCompute
- ? texture.getTextureView(bind.m_mip, 1, Binding::Image == bind.m_type)
- : texture.getTextureView(0, UINT8_MAX, false)
+ ? texture.getTextureView(bind.m_firstMip, bind.m_numMips, Binding::Image == bind.m_type)
+ : texture.getTextureView(bind.m_firstMip, bind.m_numMips, false, bind.m_firstLayer, bind.m_numLayers)
,
};
@@ -4243,6 +4238,8 @@ retry:
void TextureWGPU::destroy()
{
+ s_renderWGPU->m_textureViewStateCache.invalidateWithParent(uint16_t(this - s_renderWGPU->m_textures) );
+
wgpuDestroy(m_texture);
wgpuDestroy(m_textureResolve);
}
@@ -4357,7 +4354,7 @@ retry:
return sampler;
}
- WGPUTextureView TextureWGPU::getTextureView(uint8_t _baseMipLevel, uint8_t _mipLevelCount, bool _storage, bool _array) const
+ WGPUTextureView TextureWGPU::getTextureView(uint8_t _baseMipLevel, uint8_t _mipLevelCount, bool _storage, uint16_t _baseArrayLayer, uint16_t _arrayLayerCount) const
{
bx::HashMurmur3 murmur;
murmur.begin();
@@ -4365,7 +4362,8 @@ retry:
murmur.add(_baseMipLevel);
murmur.add(_mipLevelCount);
murmur.add(_storage);
- murmur.add(_array);
+ murmur.add(_baseArrayLayer);
+ murmur.add(_arrayLayerCount);
const uint32_t hash = murmur.end();
WGPUTextureView textureView = s_renderWGPU->m_textureViewStateCache.find(hash);
@@ -4373,13 +4371,12 @@ retry:
if (NULL == textureView)
{
WGPUTextureViewDimension tvd = m_viewDimension;
- uint32_t arrayLayerCount = WGPU_ARRAY_LAYER_COUNT_UNDEFINED;
+ const uint32_t arrayLayerCount = UINT16_MAX == _arrayLayerCount
+ ? WGPU_ARRAY_LAYER_COUNT_UNDEFINED
+ : _arrayLayerCount
+ ;
- if (_array)
- {
- tvd = WGPUTextureViewDimension_2DArray;
- }
- else if (_storage)
+ if (_storage)
{
if (WGPUTextureViewDimension_Cube == tvd)
{
@@ -4395,16 +4392,17 @@ retry:
.dimension = tvd,
.baseMipLevel = _baseMipLevel,
.mipLevelCount = UINT8_MAX == _mipLevelCount ? WGPU_MIP_LEVEL_COUNT_UNDEFINED : _mipLevelCount,
- .baseArrayLayer = 0,
+ .baseArrayLayer = _baseArrayLayer,
.arrayLayerCount = arrayLayerCount,
.aspect = WGPUTextureAspect_All,
- .usage = WGPUTextureUsage_TextureBinding
+ .usage = 0
+ | WGPUTextureUsage_TextureBinding
| (_storage ? WGPUTextureUsage_StorageBinding : 0)
,
};
textureView = WGPU_CHECK(wgpuTextureCreateView(m_texture, &textureViewDesc) );
- s_renderWGPU->m_textureViewStateCache.add(hash, textureView);
+ s_renderWGPU->m_textureViewStateCache.add(hash, textureView, uint16_t(this - s_renderWGPU->m_textures) );
}
return textureView;
@@ -5475,22 +5473,19 @@ m_resolution.formatColor = TextureFormat::BGRA8;
for (uint32_t ii = 0; ii < 4; ++ii)
{
Binding& bind = renderBind.m_bind[ii];
- bind.m_type = Binding::Image;
- bind.m_access = Access::Write;
- bind.m_idx = _textureHandle.idx;
- bind.m_mip = uint8_t(bx::min(topMip + 1 + ii, uint32_t(_texture.m_numMips - 1) ) );
+ bind.setImage(_textureHandle, uint8_t(bx::min(topMip + 1 + ii, uint32_t(_texture.m_numMips - 1) ) ), Access::Write, TextureFormat::Enum(0) );
}
{
- Binding& bind = renderBind.m_bind[4];
- bind.m_type = Binding::Texture;
- bind.m_idx = _textureHandle.idx;
- bind.m_mip = uint8_t(topMip);
- bind.m_samplerFlags = 0
+ Binding& bind = renderBind.m_bind[4];
+ bind.setTexture(
+ _textureHandle
+ , 0
| BGFX_SAMPLER_U_CLAMP
| BGFX_SAMPLER_V_CLAMP
| BGFX_SAMPLER_W_CLAMP
- ;
+ , uint8_t(topMip)
+ );
}
ComputePipeline* computePipeline = getPipeline(prog, renderBind);
diff --git a/src/renderer_webgpu.h b/src/renderer_webgpu.h
index 0bf9c3b7a..9150034c5 100644
--- a/src/renderer_webgpu.h
+++ b/src/renderer_webgpu.h
@@ -391,10 +391,10 @@ namespace bgfx { namespace wgpu
class StateCacheT
{
public:
- void add(uint64_t _key, Ty _value)
+ void add(uint64_t _key, Ty _value, uint16_t _parent = UINT16_MAX)
{
invalidate(_key);
- m_hashMap.insert(stl::make_pair(_key, _value) );
+ m_hashMap.insert(stl::make_pair(_key, Data{_value, _parent}) );
}
Ty find(uint64_t _key)
@@ -402,7 +402,7 @@ namespace bgfx { namespace wgpu
typename HashMap::iterator it = m_hashMap.find(_key);
if (it != m_hashMap.end() )
{
- return it->second;
+ return it->second.m_value;
}
return 0;
@@ -413,16 +413,34 @@ namespace bgfx { namespace wgpu
typename HashMap::iterator it = m_hashMap.find(_key);
if (it != m_hashMap.end() )
{
- wgpuRelease(it->second);
+ wgpuRelease(it->second.m_value);
m_hashMap.erase(it);
}
}
+ void invalidateWithParent(uint16_t _parent)
+ {
+ for (typename HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd;)
+ {
+ if (it->second.m_parent == _parent)
+ {
+ wgpuRelease(it->second.m_value);
+ typename HashMap::iterator itErase = it;
+ ++it;
+ m_hashMap.erase(itErase);
+ }
+ else
+ {
+ ++it;
+ }
+ }
+ }
+
void invalidate()
{
for (typename HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
{
- wgpuRelease(it->second);
+ wgpuRelease(it->second.m_value);
}
m_hashMap.clear();
@@ -434,7 +452,13 @@ namespace bgfx { namespace wgpu
}
private:
- typedef stl::unordered_map HashMap;
+ struct Data
+ {
+ Ty m_value;
+ uint16_t m_parent;
+ };
+
+ typedef stl::unordered_map HashMap;
HashMap m_hashMap;
};
@@ -687,7 +711,7 @@ namespace bgfx { namespace wgpu
void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
WGPUSampler getSamplerState(uint32_t _samplerFlags) const;
- WGPUTextureView getTextureView(uint8_t _baseMipLevel, uint8_t _mipLevelCount, bool _storage, bool _array = false) const;
+ WGPUTextureView getTextureView(uint8_t _baseMipLevel, uint8_t _mipLevelCount, bool _storage, uint16_t _baseArrayLayer = 0, uint16_t _arrayLayerCount = UINT16_MAX) const;
WGPUTexture m_texture;
WGPUTexture m_textureResolve;