mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-10-30 20:55:30 +00:00
Added clear texture API. (#3836)
This commit is contained in:
@@ -3906,6 +3906,20 @@ public static class bgfx
|
||||
[LinkName("bgfx_update_texture_cube")]
|
||||
public static extern void update_texture_cube(TextureHandle _handle, uint16 _layer, uint8 _side, uint8 _mip, uint16 _x, uint16 _y, uint16 _width, uint16 _height, Memory* _mem, uint16 _pitch);
|
||||
|
||||
/// <summary>
|
||||
/// Clear a texture subresource range to zero.
|
||||
///
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="_handle">Texture handle.</param>
|
||||
/// <param name="_mip">First mip level.</param>
|
||||
/// <param name="_numMips">Number of mip levels.</param>
|
||||
/// <param name="_layer">First array layer (or 3D depth slice base).</param>
|
||||
/// <param name="_numLayers">Number of layers.</param>
|
||||
///
|
||||
[LinkName("bgfx_clear_texture")]
|
||||
public static extern void clear_texture(TextureHandle _handle, uint8 _mip, uint8 _numMips, uint16 _layer, uint16 _numLayers);
|
||||
|
||||
/// <summary>
|
||||
/// Read back texture content.
|
||||
///
|
||||
|
||||
@@ -2823,6 +2823,15 @@ extern fn void update_texture_3d(TextureHandle _handle, char _mip, ushort _x, us
|
||||
// _pitch : `Pitch of input image (bytes). When _pitch is set to UINT16_MAX, it will be calculated internally based on _width.`
|
||||
extern fn void update_texture_cube(TextureHandle _handle, ushort _layer, char _side, char _mip, ushort _x, ushort _y, ushort _width, ushort _height, Memory* _mem, ushort _pitch) @cname("bgfx_update_texture_cube");
|
||||
|
||||
// Clear a texture subresource range to zero.
|
||||
//
|
||||
// _handle : `Texture handle.`
|
||||
// _mip : `First mip level.`
|
||||
// _numMips : `Number of mip levels.`
|
||||
// _layer : `First array layer (or 3D depth slice base).`
|
||||
// _numLayers : `Number of layers.`
|
||||
extern fn void clear_texture(TextureHandle _handle, char _mip, char _numMips, ushort _layer, ushort _numLayers) @cname("bgfx_clear_texture");
|
||||
|
||||
// Read back texture content.
|
||||
//
|
||||
// @attention Texture must be created with `BGFX_TEXTURE_READ_BACK` flag.
|
||||
|
||||
@@ -3856,6 +3856,20 @@ public static partial class bgfx
|
||||
[DllImport(DllName, EntryPoint="bgfx_update_texture_cube", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern unsafe void update_texture_cube(TextureHandle _handle, ushort _layer, byte _side, byte _mip, ushort _x, ushort _y, ushort _width, ushort _height, Memory* _mem, ushort _pitch);
|
||||
|
||||
/// <summary>
|
||||
/// Clear a texture subresource range to zero.
|
||||
///
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="_handle">Texture handle.</param>
|
||||
/// <param name="_mip">First mip level.</param>
|
||||
/// <param name="_numMips">Number of mip levels.</param>
|
||||
/// <param name="_layer">First array layer (or 3D depth slice base).</param>
|
||||
/// <param name="_numLayers">Number of layers.</param>
|
||||
///
|
||||
[DllImport(DllName, EntryPoint="bgfx_clear_texture", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern unsafe void clear_texture(TextureHandle _handle, byte _mip, byte _numMips, ushort _layer, ushort _numLayers);
|
||||
|
||||
/// <summary>
|
||||
/// Read back texture content.
|
||||
///
|
||||
|
||||
+13
-1
@@ -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 = 150;
|
||||
enum uint apiVersion = 151;
|
||||
|
||||
alias ViewID = ushort;
|
||||
|
||||
@@ -3038,6 +3038,18 @@ mixin(joinFnBinds((){
|
||||
*/
|
||||
{q{void}, q{updateTextureCube}, q{TextureHandle handle, ushort layer, ubyte side, ubyte mip, ushort x, ushort y, ushort width, ushort height, const(Memory)* mem, ushort pitch=ushort.max}, ext: `C++, "bgfx"`},
|
||||
|
||||
/**
|
||||
* Clear a texture subresource range to zero.
|
||||
*
|
||||
Params:
|
||||
handle = Texture handle.
|
||||
mip = First mip level.
|
||||
numMIPs = Number of mip levels.
|
||||
layer = First array layer (or 3D depth slice base).
|
||||
numLayers = Number of layers.
|
||||
*/
|
||||
{q{void}, q{clear}, q{TextureHandle handle, ubyte mip=0, ubyte numMIPs=ubyte.max, ushort layer=0, ushort numLayers=ushort.max}, ext: `C++, "bgfx"`},
|
||||
|
||||
/**
|
||||
* Read back texture content.
|
||||
*
|
||||
|
||||
@@ -3060,6 +3060,18 @@ pub inline fn updateTextureCube(_handle: TextureHandle, _layer: u16, _side: u8,
|
||||
}
|
||||
extern fn bgfx_update_texture_cube(_handle: TextureHandle, _layer: u16, _side: u8, _mip: u8, _x: u16, _y: u16, _width: u16, _height: u16, _mem: [*c]const Memory, _pitch: u16) void;
|
||||
|
||||
/// Clear a texture subresource range to zero.
|
||||
///
|
||||
/// <param name="_handle">Texture handle.</param>
|
||||
/// <param name="_mip">First mip level.</param>
|
||||
/// <param name="_numMips">Number of mip levels.</param>
|
||||
/// <param name="_layer">First array layer (or 3D depth slice base).</param>
|
||||
/// <param name="_numLayers">Number of layers.</param>
|
||||
pub inline fn clearTexture(_handle: TextureHandle, _mip: u8, _numMips: u8, _layer: u16, _numLayers: u16) void {
|
||||
return bgfx_clear_texture(_handle, _mip, _numMips, _layer, _numLayers);
|
||||
}
|
||||
extern fn bgfx_clear_texture(_handle: TextureHandle, _mip: u8, _numMips: u8, _layer: u16, _numLayers: u16) void;
|
||||
|
||||
/// Read back texture content.
|
||||
///
|
||||
/// @attention Texture must be created with `BGFX_TEXTURE_READ_BACK` flag.
|
||||
|
||||
@@ -631,6 +631,7 @@ Textures
|
||||
.. doxygenfunction:: bgfx::updateTexture2D
|
||||
.. doxygenfunction:: bgfx::updateTexture3D
|
||||
.. doxygenfunction:: bgfx::updateTextureCube
|
||||
.. doxygenfunction:: bgfx::clear
|
||||
.. doxygenfunction:: bgfx::readTexture
|
||||
.. doxygenfunction:: bgfx::getDirectAccessPtr
|
||||
.. doxygenfunction:: bgfx::destroy(TextureHandle _handle)
|
||||
|
||||
@@ -232,6 +232,7 @@ bgfx::TextureHandle loadTextureWithUpdate(const char* _filePath, uint64_t _flags
|
||||
}
|
||||
|
||||
static const uint16_t kTextureSide = 512;
|
||||
static const uint32_t kClearCubeAfterAllocations = 1024;
|
||||
static const uint32_t kTexture2dSize = 256;
|
||||
|
||||
class ExampleUpdate : public entry::AppI
|
||||
@@ -471,6 +472,7 @@ public:
|
||||
|
||||
m_hit = 0;
|
||||
m_miss = 0;
|
||||
m_lastClearHit = 0;
|
||||
|
||||
imguiCreate();
|
||||
|
||||
@@ -629,6 +631,15 @@ public:
|
||||
|
||||
if (bx::getNow() > m_updateTime)
|
||||
{
|
||||
if (m_hit - m_lastClearHit >= kClearCubeAfterAllocations)
|
||||
{
|
||||
bgfx::clear(m_textureCube[0]);
|
||||
bgfx::clear(m_textureCube[1]);
|
||||
m_cube.reset(kTextureSide);
|
||||
m_quads.clear();
|
||||
m_lastClearHit = m_hit;
|
||||
}
|
||||
|
||||
PackCube face;
|
||||
|
||||
uint16_t bw = bx::max<uint16_t>(1, m_rng.gen()%(kTextureSide/4) );
|
||||
@@ -1082,6 +1093,7 @@ public:
|
||||
|
||||
uint32_t m_hit;
|
||||
uint32_t m_miss;
|
||||
uint32_t m_lastClearHit;
|
||||
|
||||
uint8_t m_rr;
|
||||
uint8_t m_gg;
|
||||
|
||||
@@ -3315,6 +3315,24 @@ namespace bgfx
|
||||
, uint16_t _pitch = UINT16_MAX
|
||||
);
|
||||
|
||||
/// Clear a texture subresource range to zero.
|
||||
///
|
||||
/// @param[in] _handle Texture handle.
|
||||
/// @param[in] _mip First mip level.
|
||||
/// @param[in] _numMips Number of mip levels.
|
||||
/// @param[in] _layer First array layer (or 3D depth slice base).
|
||||
/// @param[in] _numLayers Number of layers.
|
||||
///
|
||||
/// @attention C99's equivalent binding is `bgfx_clear_texture`.
|
||||
///
|
||||
void clear(
|
||||
TextureHandle _handle
|
||||
, uint8_t _mip = 0
|
||||
, uint8_t _numMips = UINT8_MAX
|
||||
, uint16_t _layer = 0
|
||||
, uint16_t _numLayers = UINT16_MAX
|
||||
);
|
||||
|
||||
/// Read back texture content.
|
||||
///
|
||||
/// @param[in] _handle Texture handle.
|
||||
|
||||
@@ -2220,6 +2220,18 @@ BGFX_C_API void bgfx_update_texture_3d(bgfx_texture_handle_t _handle, uint8_t _m
|
||||
*/
|
||||
BGFX_C_API void bgfx_update_texture_cube(bgfx_texture_handle_t _handle, uint16_t _layer, uint8_t _side, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const bgfx_memory_t* _mem, uint16_t _pitch);
|
||||
|
||||
/**
|
||||
* Clear a texture subresource range to zero.
|
||||
*
|
||||
* @param[in] _handle Texture handle.
|
||||
* @param[in] _mip First mip level.
|
||||
* @param[in] _numMips Number of mip levels.
|
||||
* @param[in] _layer First array layer (or 3D depth slice base).
|
||||
* @param[in] _numLayers Number of layers.
|
||||
*
|
||||
*/
|
||||
BGFX_C_API void bgfx_clear_texture(bgfx_texture_handle_t _handle, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers);
|
||||
|
||||
/**
|
||||
* Read back texture content.
|
||||
*
|
||||
@@ -4063,6 +4075,7 @@ typedef enum bgfx_function_id
|
||||
BGFX_FUNCTION_ID_UPDATE_TEXTURE_2D,
|
||||
BGFX_FUNCTION_ID_UPDATE_TEXTURE_3D,
|
||||
BGFX_FUNCTION_ID_UPDATE_TEXTURE_CUBE,
|
||||
BGFX_FUNCTION_ID_CLEAR_TEXTURE,
|
||||
BGFX_FUNCTION_ID_READ_TEXTURE,
|
||||
BGFX_FUNCTION_ID_SET_TEXTURE_NAME,
|
||||
BGFX_FUNCTION_ID_GET_DIRECT_ACCESS_PTR,
|
||||
@@ -4277,6 +4290,7 @@ struct bgfx_interface_vtbl
|
||||
void (*update_texture_2d)(bgfx_texture_handle_t _handle, uint16_t _layer, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const bgfx_memory_t* _mem, uint16_t _pitch);
|
||||
void (*update_texture_3d)(bgfx_texture_handle_t _handle, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _z, uint16_t _width, uint16_t _height, uint16_t _depth, const bgfx_memory_t* _mem);
|
||||
void (*update_texture_cube)(bgfx_texture_handle_t _handle, uint16_t _layer, uint8_t _side, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const bgfx_memory_t* _mem, uint16_t _pitch);
|
||||
void (*clear_texture)(bgfx_texture_handle_t _handle, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers);
|
||||
uint32_t (*read_texture)(bgfx_texture_handle_t _handle, void* _data, uint16_t _layer, uint8_t _mip);
|
||||
void (*set_texture_name)(bgfx_texture_handle_t _handle, const char* _name, int32_t _len);
|
||||
void* (*get_direct_access_ptr)(bgfx_texture_handle_t _handle);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifndef BGFX_DEFINES_H_HEADER_GUARD
|
||||
#define BGFX_DEFINES_H_HEADER_GUARD
|
||||
|
||||
#define BGFX_API_VERSION UINT32_C(150)
|
||||
#define BGFX_API_VERSION UINT32_C(151)
|
||||
|
||||
/**
|
||||
* Color RGB/alpha/depth write. When it's not specified write will be disabled.
|
||||
|
||||
+15
-1
@@ -1,7 +1,7 @@
|
||||
-- vim: syntax=lua
|
||||
-- bgfx interface
|
||||
|
||||
version(150)
|
||||
version(151)
|
||||
|
||||
typedef "bool"
|
||||
typedef "char"
|
||||
@@ -2023,6 +2023,20 @@ func.updateTextureCube { section = "Textures" }
|
||||
--- UINT16_MAX, it will be calculated internally based on _width.
|
||||
{ default = UINT16_MAX }
|
||||
|
||||
--- Clear a texture subresource range to zero.
|
||||
---
|
||||
func.clear { cname = "clear_texture", section = "Textures" }
|
||||
"void"
|
||||
.handle "TextureHandle" --- Texture handle.
|
||||
.mip "uint8_t" --- First mip level.
|
||||
{ default = 0 }
|
||||
.numMips "uint8_t" --- Number of mip levels.
|
||||
{ default = UINT8_MAX }
|
||||
.layer "uint16_t" --- First array layer (or 3D depth slice base).
|
||||
{ default = 0 }
|
||||
.numLayers "uint16_t" --- Number of layers.
|
||||
{ default = UINT16_MAX }
|
||||
|
||||
--- Read back texture content.
|
||||
---
|
||||
--- @attention Texture must be created with `BGFX_TEXTURE_READ_BACK` flag.
|
||||
|
||||
@@ -3722,6 +3722,31 @@ namespace bgfx
|
||||
}
|
||||
break;
|
||||
|
||||
case CommandBuffer::ClearTexture:
|
||||
{
|
||||
BGFX_PROFILER_SCOPE("ClearTexture", kColorResource);
|
||||
|
||||
TextureHandle handle;
|
||||
_cmdbuf.read(handle);
|
||||
|
||||
uint8_t mip;
|
||||
_cmdbuf.read(mip);
|
||||
|
||||
uint8_t numMips;
|
||||
_cmdbuf.read(numMips);
|
||||
|
||||
uint16_t layer;
|
||||
_cmdbuf.read(layer);
|
||||
|
||||
uint16_t numLayers;
|
||||
_cmdbuf.read(numLayers);
|
||||
|
||||
flushTextureUpdateBatch(_cmdbuf);
|
||||
|
||||
m_renderCtx->clearTexture(handle, mip, numMips, layer, numLayers);
|
||||
}
|
||||
break;
|
||||
|
||||
case CommandBuffer::ReadTexture:
|
||||
{
|
||||
BGFX_PROFILER_SCOPE("ReadTexture", kColorResource);
|
||||
@@ -5838,6 +5863,32 @@ namespace bgfx
|
||||
return s_ctx->readTexture(_handle, _data, _layer, _mip);
|
||||
}
|
||||
|
||||
void clear(TextureHandle _handle, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers)
|
||||
{
|
||||
BGFX_CHECK_HANDLE("clearTexture", s_ctx->m_textureHandle, _handle);
|
||||
|
||||
const TextureRef& ref = s_ctx->m_textureRef[_handle.idx];
|
||||
|
||||
BX_ASSERT(!ref.isDepth()
|
||||
, "Texture (handle %d, '%S') has a depth/stencil format and can't be cleared; use a view depth clear instead."
|
||||
, _handle.idx
|
||||
, &ref.m_name
|
||||
);
|
||||
BX_ASSERT(!bimg::isCompressed(bimg::TextureFormat::Enum(ref.m_format) )
|
||||
, "Texture (handle %d, '%S', %s) is compressed and can't be cleared."
|
||||
, _handle.idx
|
||||
, &ref.m_name
|
||||
, bimg::getName(bimg::TextureFormat::Enum(ref.m_format) )
|
||||
);
|
||||
BX_ASSERT( (ref.m_flags & BGFX_TEXTURE_RT_MSAA_MASK) <= BGFX_TEXTURE_RT
|
||||
, "Texture (handle %d, '%S') is multisampled and can't be cleared; use a view clear instead."
|
||||
, _handle.idx
|
||||
, &ref.m_name
|
||||
);
|
||||
|
||||
s_ctx->clearTexture(_handle, _mip, _numMips, _layer, _numLayers);
|
||||
}
|
||||
|
||||
FrameBufferHandle createFrameBuffer(uint16_t _width, uint16_t _height, TextureFormat::Enum _format, uint64_t _textureFlags)
|
||||
{
|
||||
_textureFlags |= _textureFlags&BGFX_TEXTURE_RT_MSAA_MASK ? 0 : BGFX_TEXTURE_RT;
|
||||
|
||||
@@ -516,6 +516,12 @@ BGFX_C_API void bgfx_update_texture_cube(bgfx_texture_handle_t _handle, uint16_t
|
||||
bgfx::updateTextureCube(handle.cpp, _layer, _side, _mip, _x, _y, _width, _height, (const bgfx::Memory*)_mem, _pitch);
|
||||
}
|
||||
|
||||
BGFX_C_API void bgfx_clear_texture(bgfx_texture_handle_t _handle, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers)
|
||||
{
|
||||
union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle = { _handle };
|
||||
bgfx::clear(handle.cpp, _mip, _numMips, _layer, _numLayers);
|
||||
}
|
||||
|
||||
BGFX_C_API uint32_t bgfx_read_texture(bgfx_texture_handle_t _handle, void* _data, uint16_t _layer, uint8_t _mip)
|
||||
{
|
||||
union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle = { _handle };
|
||||
@@ -1427,6 +1433,7 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version)
|
||||
bgfx_update_texture_2d,
|
||||
bgfx_update_texture_3d,
|
||||
bgfx_update_texture_cube,
|
||||
bgfx_clear_texture,
|
||||
bgfx_read_texture,
|
||||
bgfx_set_texture_name,
|
||||
bgfx_get_direct_access_ptr,
|
||||
|
||||
@@ -643,6 +643,21 @@ namespace bgfx
|
||||
release( (const Memory*)_mem);
|
||||
}
|
||||
|
||||
static constexpr uint32_t kTextureZeroInitBudget = 64<<10;
|
||||
|
||||
inline constexpr uint32_t textureZeroInitTileDim(uint32_t _bpp, uint32_t _budget = kTextureZeroInitBudget)
|
||||
{
|
||||
uint32_t dim = 512;
|
||||
|
||||
while (dim > 1
|
||||
&& uint64_t(dim)*dim*_bpp/8 > _budget)
|
||||
{
|
||||
dim >>= 1;
|
||||
}
|
||||
|
||||
return dim;
|
||||
}
|
||||
|
||||
static_assert(BGFX_STENCIL_NONE == BGFX_STENCIL_FUNC_RMASK_MASK, "");
|
||||
|
||||
inline constexpr uint64_t packStencil(uint32_t _fstencil, uint32_t _bstencil)
|
||||
@@ -1057,6 +1072,7 @@ namespace bgfx
|
||||
CreateProgram,
|
||||
CreateTexture,
|
||||
UpdateTexture,
|
||||
ClearTexture,
|
||||
ResizeTexture,
|
||||
CreateFrameBuffer,
|
||||
CreateUniform,
|
||||
@@ -4186,6 +4202,7 @@ namespace bgfx
|
||||
virtual void destroyProgram(ProgramHandle _handle) = 0;
|
||||
virtual void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) = 0;
|
||||
virtual void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) = 0;
|
||||
virtual void clearTexture(TextureHandle _handle, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers) = 0;
|
||||
virtual void readTexture(TextureHandle _handle, void* _data, uint16_t _layer, uint8_t _mip) = 0;
|
||||
virtual void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips, uint16_t _numLayers) = 0;
|
||||
virtual void overrideInternal(TextureHandle _handle, uintptr_t _ptr, uint16_t _layerIndex) = 0;
|
||||
@@ -5880,6 +5897,18 @@ namespace bgfx
|
||||
cmdbuf.write(_mem);
|
||||
}
|
||||
|
||||
BGFX_API_FUNC(void clearTexture(TextureHandle _handle, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers) )
|
||||
{
|
||||
BGFX_MUTEX_SCOPE(m_resourceApiLock);
|
||||
|
||||
CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::ClearTexture);
|
||||
cmdbuf.write(_handle);
|
||||
cmdbuf.write(_mip);
|
||||
cmdbuf.write(_numMips);
|
||||
cmdbuf.write(_layer);
|
||||
cmdbuf.write(_numLayers);
|
||||
}
|
||||
|
||||
BGFX_API_FUNC(FrameBufferHandle createFrameBuffer(uint8_t _num, const Attachment* _attachment, bool _destroyTextures) )
|
||||
{
|
||||
BGFX_MUTEX_SCOPE(m_resourceApiLock);
|
||||
|
||||
@@ -207,6 +207,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 PFNGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);
|
||||
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);
|
||||
@@ -412,6 +413,7 @@ GL_IMPORT______(true, PFNGLTEXSTORAGE2DPROC, glTexStorage2
|
||||
GL_IMPORT______(true, PFNGLTEXSTORAGE3DPROC, glTexStorage3D);
|
||||
GL_IMPORT______(false, PFNGLTEXSUBIMAGE2DPROC, glTexSubImage2D);
|
||||
GL_IMPORT______(true, PFNGLTEXSUBIMAGE3DPROC, glTexSubImage3D);
|
||||
GL_IMPORT______(true, PFNGLCLEARTEXSUBIMAGEPROC, glClearTexSubImage);
|
||||
GL_IMPORT______(true, PFNGLTEXTUREVIEWPROC, glTextureView);
|
||||
GL_IMPORT______(false, PFNGLUNIFORM1IPROC, glUniform1i);
|
||||
GL_IMPORT______(false, PFNGLUNIFORM1IVPROC, glUniform1iv);
|
||||
@@ -542,6 +544,7 @@ GL_IMPORT_OES__(true, PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, glCompressedT
|
||||
|
||||
GL_IMPORT_EXT__(true, PFNGLTEXSTORAGE2DPROC, glTexStorage2D);
|
||||
GL_IMPORT_EXT__(true, PFNGLTEXSTORAGE3DPROC, glTexStorage3D);
|
||||
GL_IMPORT_EXT__(true, PFNGLCLEARTEXSUBIMAGEPROC, glClearTexSubImage);
|
||||
GL_IMPORT_EXT__(true, PFNGLTEXTUREVIEWPROC, glTextureView);
|
||||
GL_IMPORT______(true, PFNGLTEXIMAGE2DMULTISAMPLEPROC, glTexImage2DMultisample);
|
||||
|
||||
@@ -638,6 +641,7 @@ GL_IMPORT______(true, PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, glCompressedT
|
||||
|
||||
GL_IMPORT______(true, PFNGLTEXSTORAGE2DPROC, glTexStorage2D);
|
||||
GL_IMPORT______(true, PFNGLTEXSTORAGE3DPROC, glTexStorage3D);
|
||||
GL_IMPORT______(true, PFNGLCLEARTEXSUBIMAGEPROC, glClearTexSubImage);
|
||||
GL_IMPORT______(true, PFNGLTEXTUREVIEWPROC, glTextureView);
|
||||
GL_IMPORT______(true, PFNGLTEXIMAGE2DMULTISAMPLEPROC, glTexImage2DMultisample);
|
||||
GL_IMPORT______(true, PFNGLTEXIMAGE3DMULTISAMPLEPROC, glTexImage3DMultisample);
|
||||
|
||||
@@ -707,6 +707,8 @@ namespace bgfx { namespace d3d11
|
||||
int WINAPI d3d11Annotation_EndEvent();
|
||||
void WINAPI d3d11Annotation_SetMarker(DWORD _color, LPCWSTR _name);
|
||||
|
||||
struct TextureD3D11;
|
||||
|
||||
struct RendererContextD3D11 : public RendererContextI
|
||||
{
|
||||
RendererContextD3D11()
|
||||
@@ -1778,6 +1780,8 @@ namespace bgfx { namespace d3d11
|
||||
m_deviceCtx->ClearState();
|
||||
m_deviceCtx->Flush();
|
||||
|
||||
m_zeroInitTileCache.invalidate();
|
||||
|
||||
invalidateCache();
|
||||
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii)
|
||||
@@ -1934,6 +1938,11 @@ namespace bgfx { namespace d3d11
|
||||
m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _pitch, _mem);
|
||||
}
|
||||
|
||||
void clearTexture(TextureHandle _handle, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers) override
|
||||
{
|
||||
m_textures[_handle.idx].clear(_mip, _numMips, _layer, _numLayers);
|
||||
}
|
||||
|
||||
void readTexture(TextureHandle _handle, void* _data, uint16_t _layer, uint8_t _mip) override
|
||||
{
|
||||
const TextureD3D11& texture = m_textures[_handle.idx];
|
||||
@@ -3800,6 +3809,7 @@ namespace bgfx { namespace d3d11
|
||||
StateCacheT<ID3D11RasterizerState*> m_rasterizerStateCache;
|
||||
StateCacheT<ID3D11SamplerState*> m_samplerStateCache;
|
||||
StateCacheLru<IUnknown*, 1024> m_srvUavLru;
|
||||
StateCacheLru<IUnknown*, 16> m_zeroInitTileCache;
|
||||
|
||||
TextVideoMem m_textVideoMem;
|
||||
|
||||
@@ -4413,6 +4423,137 @@ namespace bgfx { namespace d3d11
|
||||
}
|
||||
}
|
||||
|
||||
static ID3D11Texture2D* zeroInitTile(DXGI_FORMAT _fmt, uint32_t _tileDim, uint32_t _blockW, uint32_t _blockH, uint32_t _blockSize)
|
||||
{
|
||||
if (IUnknown** cached = s_renderD3D11->m_zeroInitTileCache.find(uint64_t(_fmt) ) )
|
||||
{
|
||||
return static_cast<ID3D11Texture2D*>(*cached);
|
||||
}
|
||||
|
||||
const uint32_t rowPitch = (_tileDim / _blockW) * _blockSize;
|
||||
const uint32_t numRows = _tileDim / _blockH;
|
||||
uint8_t zeros[kTextureZeroInitBudget] = {};
|
||||
BX_ASSERT(rowPitch * numRows <= sizeof(zeros), "Zero-init tile exceeds budget.");
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
bx::memSet(&desc, 0, sizeof(desc) );
|
||||
desc.Width = _tileDim;
|
||||
desc.Height = _tileDim;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = _fmt;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
D3D11_SUBRESOURCE_DATA srd = { zeros, rowPitch, 0 };
|
||||
|
||||
ID3D11Texture2D* tile = NULL;
|
||||
s_renderD3D11->m_device->CreateTexture2D(&desc, &srd, &tile);
|
||||
|
||||
if (NULL != tile)
|
||||
{
|
||||
s_renderD3D11->m_zeroInitTileCache.add(uint64_t(_fmt), tile, 0);
|
||||
}
|
||||
|
||||
return tile;
|
||||
}
|
||||
|
||||
void TextureD3D11::clear(uint8_t _baseMip, uint8_t _numMips, uint16_t _baseLayer, uint16_t _numLayers)
|
||||
{
|
||||
const bimg::TextureFormat::Enum tf = bimg::TextureFormat::Enum(m_textureFormat);
|
||||
|
||||
ID3D11Device* device = s_renderD3D11->m_device;
|
||||
ID3D11DeviceContext* ctx = s_renderD3D11->m_deviceCtx;
|
||||
|
||||
const DXGI_FORMAT fmt = (0 != (m_flags & BGFX_TEXTURE_SRGB) )
|
||||
? s_textureFormat[m_textureFormat].m_fmtSrgb
|
||||
: s_textureFormat[m_textureFormat].m_fmt
|
||||
;
|
||||
const uint32_t numMips = m_numMips;
|
||||
const uint32_t numSides = m_numLayers * (TextureD3D11::TextureCube == m_type ? 6 : 1);
|
||||
const bool is3D = TextureD3D11::Texture3D == m_type;
|
||||
const bool rtColor = 0 != (m_flags & BGFX_TEXTURE_RT_MASK);
|
||||
|
||||
const uint32_t mipBeg = bx::min<uint32_t>(_baseMip, numMips);
|
||||
const uint32_t mipEnd = (UINT8_MAX == _numMips) ? numMips : bx::min<uint32_t>(numMips, uint32_t(_baseMip) + _numMips);
|
||||
const uint32_t sideBeg = is3D ? 0 : bx::min<uint32_t>(_baseLayer, numSides);
|
||||
const uint32_t sideEnd = is3D ? 1 : ( (UINT16_MAX == _numLayers) ? numSides : bx::min<uint32_t>(numSides, uint32_t(_baseLayer) + _numLayers) );
|
||||
|
||||
if (rtColor && !is3D)
|
||||
{
|
||||
const float black[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
for (uint32_t side = sideBeg; side < sideEnd; ++side)
|
||||
{
|
||||
for (uint32_t mip = mipBeg; mip < mipEnd; ++mip)
|
||||
{
|
||||
D3D11_RENDER_TARGET_VIEW_DESC rtvd;
|
||||
bx::memSet(&rtvd, 0, sizeof(rtvd) );
|
||||
rtvd.Format = fmt;
|
||||
if (1 < numSides)
|
||||
{
|
||||
rtvd.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
|
||||
rtvd.Texture2DArray.MipSlice = mip;
|
||||
rtvd.Texture2DArray.FirstArraySlice = side;
|
||||
rtvd.Texture2DArray.ArraySize = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rtvd.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
rtvd.Texture2D.MipSlice = mip;
|
||||
}
|
||||
|
||||
ID3D11RenderTargetView* rtv = NULL;
|
||||
if (SUCCEEDED(device->CreateRenderTargetView(m_ptr, &rtvd, &rtv) )
|
||||
&& NULL != rtv)
|
||||
{
|
||||
ctx->ClearRenderTargetView(rtv, black);
|
||||
DX_RELEASE(rtv, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const bimg::ImageBlockInfo& bi = bimg::getBlockInfo(tf);
|
||||
const uint32_t blockW = bx::max<uint32_t>(1, bi.blockWidth);
|
||||
const uint32_t blockH = bx::max<uint32_t>(1, bi.blockHeight);
|
||||
const uint32_t blockSize = bi.blockSize;
|
||||
const uint32_t tileDim = textureZeroInitTileDim(bimg::getBitsPerPixel(tf) );
|
||||
|
||||
ID3D11Texture2D* tile = zeroInitTile(fmt, tileDim, blockW, blockH, blockSize);
|
||||
if (NULL == tile)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t side = sideBeg; side < sideEnd; ++side)
|
||||
{
|
||||
for (uint32_t mip = mipBeg; mip < mipEnd; ++mip)
|
||||
{
|
||||
const uint32_t mipW = bx::max<uint32_t>(1, m_width >> mip);
|
||||
const uint32_t mipH = bx::max<uint32_t>(1, m_height >> mip);
|
||||
const uint32_t mipD = is3D ? bx::max<uint32_t>(1, m_depth >> mip) : 1;
|
||||
const uint32_t dstSub = is3D ? mip : (mip + side * numMips);
|
||||
|
||||
for (uint32_t zz = 0; zz < mipD; ++zz)
|
||||
{
|
||||
for (uint32_t yy = 0; yy < mipH; yy += tileDim)
|
||||
{
|
||||
const uint32_t bh = bx::min<uint32_t>(tileDim, mipH - yy);
|
||||
for (uint32_t xx = 0; xx < mipW; xx += tileDim)
|
||||
{
|
||||
const uint32_t bw = bx::min<uint32_t>(tileDim, mipW - xx);
|
||||
D3D11_BOX box;
|
||||
box.left = 0; box.top = 0; box.front = 0;
|
||||
box.right = bw; box.bottom = bh; box.back = 1;
|
||||
ctx->CopySubresourceRegion(m_ptr, dstSub, xx, yy, zz, tile, 0, &box);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void* TextureD3D11::create(const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external)
|
||||
{
|
||||
void* directAccessPtr = NULL;
|
||||
|
||||
@@ -288,6 +288,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 clear(uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers);
|
||||
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;
|
||||
|
||||
+124
-1
@@ -759,6 +759,8 @@ namespace bgfx { namespace d3d12
|
||||
}
|
||||
#endif // BGFX_CONFIG_DEBUG_ANNOTATION && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT)
|
||||
|
||||
struct TextureD3D12;
|
||||
|
||||
struct RendererContextD3D12 : public RendererContextI
|
||||
{
|
||||
RendererContextD3D12()
|
||||
@@ -780,6 +782,7 @@ namespace bgfx { namespace d3d12
|
||||
, m_directAccessSupport(false)
|
||||
, m_variableRateShadingSupport(false)
|
||||
, m_mipGen(NULL)
|
||||
, m_zeroInitBuffer(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -2028,6 +2031,8 @@ namespace bgfx { namespace d3d12
|
||||
m_cmd.finish();
|
||||
m_batch.destroy();
|
||||
|
||||
DX_RELEASE(m_zeroInitBuffer, 0);
|
||||
|
||||
preReset();
|
||||
|
||||
m_gpuTimer.shutdown();
|
||||
@@ -2259,6 +2264,11 @@ namespace bgfx { namespace d3d12
|
||||
m_textures[_handle.idx].update(m_commandList, _side, _mip, _rect, _z, _depth, _pitch, _mem);
|
||||
}
|
||||
|
||||
void clearTexture(TextureHandle _handle, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers) override
|
||||
{
|
||||
m_textures[_handle.idx].clear(m_commandList, _mip, _numMips, _layer, _numLayers);
|
||||
}
|
||||
|
||||
void readTexture(TextureHandle _handle, void* _data, uint16_t _layer, uint8_t _mip) override
|
||||
{
|
||||
const TextureD3D12& texture = m_textures[_handle.idx];
|
||||
@@ -4089,6 +4099,7 @@ namespace bgfx { namespace d3d12
|
||||
bool m_variableRateShadingSupport;
|
||||
|
||||
const MipGen* m_mipGen;
|
||||
ID3D12Resource* m_zeroInitBuffer;
|
||||
|
||||
void generateMips(ID3D12GraphicsCommandList* _commandList, TextureD3D12& _texture);
|
||||
};
|
||||
@@ -6451,6 +6462,117 @@ namespace bgfx { namespace d3d12
|
||||
m_ptr = (ID3D12Resource*)_ptr;
|
||||
}
|
||||
|
||||
void TextureD3D12::clear(ID3D12GraphicsCommandList* _commandList, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers)
|
||||
{
|
||||
const D3D12_RESOURCE_STATES saved = setState(_commandList, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
|
||||
const bimg::TextureFormat::Enum tf = bimg::TextureFormat::Enum(m_textureFormat);
|
||||
|
||||
ID3D12Resource* zeroBuffer = s_renderD3D12->m_zeroInitBuffer;
|
||||
|
||||
if (NULL == zeroBuffer)
|
||||
{
|
||||
zeroBuffer = createCommittedResource(s_renderD3D12->m_device, HeapProperty::Upload, kTextureZeroInitBudget);
|
||||
|
||||
void* ptr = NULL;
|
||||
D3D12_RANGE readRange = { 0, 0 };
|
||||
|
||||
if (SUCCEEDED(zeroBuffer->Map(0, &readRange, &ptr) ) )
|
||||
{
|
||||
bx::memSet(ptr, 0, kTextureZeroInitBudget);
|
||||
zeroBuffer->Unmap(0, NULL);
|
||||
}
|
||||
|
||||
s_renderD3D12->m_zeroInitBuffer = zeroBuffer;
|
||||
}
|
||||
|
||||
if (NULL == zeroBuffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const DXGI_FORMAT fmt = s_textureFormat[m_textureFormat].m_fmt;
|
||||
const uint32_t bpp = bimg::getBitsPerPixel(tf);
|
||||
const uint32_t numMips = m_numMips;
|
||||
const bool is3D = TextureD3D12::Texture3D == m_type;
|
||||
const uint32_t numSides = m_numLayers * (TextureD3D12::TextureCube == m_type ? 6 : 1);
|
||||
uint32_t tile = 512;
|
||||
|
||||
while (tile > 1
|
||||
&& bx::strideAlign(tile*bpp/8, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT)*tile > kTextureZeroInitBudget)
|
||||
{
|
||||
tile >>= 1;
|
||||
}
|
||||
|
||||
const uint32_t mipBeg = bx::min<uint32_t>(_mip, numMips);
|
||||
const uint32_t mipEnd = (UINT8_MAX == _numMips)
|
||||
? numMips
|
||||
: bx::min<uint32_t>(numMips, uint32_t(_mip) + _numMips)
|
||||
;
|
||||
const uint32_t sideBeg = is3D
|
||||
? 0
|
||||
: bx::min<uint32_t>(_layer, numSides)
|
||||
;
|
||||
const uint32_t sideEnd = is3D
|
||||
? 1
|
||||
: ( (UINT16_MAX == _numLayers)
|
||||
? numSides
|
||||
: bx::min<uint32_t>(numSides, uint32_t(_layer) + _numLayers) )
|
||||
;
|
||||
|
||||
for (uint32_t side = sideBeg; side < sideEnd; ++side)
|
||||
{
|
||||
for (uint32_t mip = mipBeg; mip < mipEnd; ++mip)
|
||||
{
|
||||
const uint32_t mipW = bx::max<uint32_t>(1, m_width >> mip);
|
||||
const uint32_t mipH = bx::max<uint32_t>(1, m_height >> mip);
|
||||
const uint32_t mipD = is3D ? bx::max<uint32_t>(1, m_depth >> mip) : 1;
|
||||
const uint32_t dstSub = is3D ? mip : (mip + side * numMips);
|
||||
|
||||
for (uint32_t zz = 0; zz < mipD; ++zz)
|
||||
{
|
||||
for (uint32_t yy = 0; yy < mipH; yy += tile)
|
||||
{
|
||||
const uint32_t th = bx::min<uint32_t>(tile, mipH - yy);
|
||||
for (uint32_t xx = 0; xx < mipW; xx += tile)
|
||||
{
|
||||
const uint32_t tw = bx::min<uint32_t>(tile, mipW - xx);
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION src =
|
||||
{
|
||||
.pResource = zeroBuffer,
|
||||
.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
|
||||
.PlacedFootprint =
|
||||
{
|
||||
.Offset = 0,
|
||||
.Footprint =
|
||||
{
|
||||
.Format = fmt,
|
||||
.Width = tw,
|
||||
.Height = th,
|
||||
.Depth = 1,
|
||||
.RowPitch = bx::strideAlign(tw * bpp / 8, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION dst =
|
||||
{
|
||||
.pResource = m_ptr,
|
||||
.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||
.SubresourceIndex = dstSub,
|
||||
};
|
||||
|
||||
_commandList->CopyTextureRegion(&dst, xx, yy, zz, &src, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setState(_commandList, saved);
|
||||
}
|
||||
|
||||
void TextureD3D12::update(ID3D12GraphicsCommandList* _commandList, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem)
|
||||
{
|
||||
if (0 != (m_flags & BGFX_TEXTURE_INTERNAL_VIDEO_DECODE_DST) )
|
||||
@@ -7614,7 +7736,7 @@ namespace bgfx { namespace d3d12
|
||||
Rect viewScissorRect;
|
||||
viewScissorRect.clear();
|
||||
|
||||
const uint32_t maxComputeBindings = g_caps.limits.maxComputeBindings;
|
||||
const uint8_t maxComputeBindings = bx::narrowCast<uint8_t>(g_caps.limits.maxComputeBindings);
|
||||
|
||||
uint32_t statsNumPrimsSubmitted[BX_COUNTOF(s_primInfo)] = {};
|
||||
uint32_t statsNumPrimsRendered[BX_COUNTOF(s_primInfo)] = {};
|
||||
@@ -7767,6 +7889,7 @@ namespace bgfx { namespace d3d12
|
||||
restoreScissor = false;
|
||||
|
||||
const Clear& clr = renderView.m_clear;
|
||||
|
||||
if (BGFX_CLEAR_NONE != clr.m_flags)
|
||||
{
|
||||
Rect clearRect = rect;
|
||||
|
||||
@@ -374,6 +374,7 @@ namespace bgfx { namespace d3d12
|
||||
void* create(const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external);
|
||||
void destroy();
|
||||
void overrideInternal(uintptr_t _ptr);
|
||||
void clear(ID3D12GraphicsCommandList* _commandList, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers);
|
||||
void update(ID3D12GraphicsCommandList* _commandList, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
|
||||
void resolve(ID3D12GraphicsCommandList* _commandList, uint8_t _resolve, uint32_t _layer, uint32_t _numLayers, uint32_t _mip);
|
||||
D3D12_RESOURCE_STATES setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state);
|
||||
|
||||
@@ -3462,6 +3462,11 @@ namespace bgfx { namespace gl
|
||||
m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _pitch, _mem);
|
||||
}
|
||||
|
||||
void clearTexture(TextureHandle _handle, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers) override
|
||||
{
|
||||
m_textures[_handle.idx].clear(_mip, _numMips, _layer, _numLayers);
|
||||
}
|
||||
|
||||
void readTexture(TextureHandle _handle, void* _data, uint16_t _layer, uint8_t _mip) override
|
||||
{
|
||||
if (m_readBackSupported)
|
||||
@@ -5840,6 +5845,37 @@ namespace bgfx { namespace gl
|
||||
return true;
|
||||
}
|
||||
|
||||
void TextureGL::clear(uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers)
|
||||
{
|
||||
if (NULL == glClearTexSubImage)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is3D = GL_TEXTURE_3D == m_target;
|
||||
const uint32_t numSides = m_numLayers * (isCubeMap() ? 6 : 1);
|
||||
|
||||
const uint8_t mipBeg = bx::min<uint8_t>(_mip, m_numMips);
|
||||
const uint8_t mipEnd = (UINT8_MAX == _numMips)
|
||||
? m_numMips
|
||||
: bx::min<uint8_t>(m_numMips, uint8_t(_mip + _numMips) )
|
||||
;
|
||||
|
||||
for (uint8_t lod = mipBeg; lod < mipEnd; ++lod)
|
||||
{
|
||||
const GLsizei mipW = GLsizei(bx::max<uint32_t>(1, m_width >> lod) );
|
||||
const GLsizei mipH = GLsizei(bx::max<uint32_t>(1, m_height >> lod) );
|
||||
|
||||
const GLint zoffset = is3D ? 0 : GLint(_layer);
|
||||
const GLsizei depth = is3D
|
||||
? GLsizei(bx::max<uint32_t>(1, m_depth >> lod) )
|
||||
: GLsizei( (UINT16_MAX == _numLayers) ? numSides - _layer : _numLayers)
|
||||
;
|
||||
|
||||
GL_CHECK(glClearTexSubImage(m_id, lod, 0, 0, zoffset, mipW, mipH, depth, m_fmt, m_type, NULL) );
|
||||
}
|
||||
}
|
||||
|
||||
void TextureGL::create(const Memory* _mem, uint64_t _flags, uint8_t _skip)
|
||||
{
|
||||
bimg::ImageContainer imageContainer;
|
||||
|
||||
@@ -1433,6 +1433,7 @@ namespace bgfx { namespace gl
|
||||
void destroy();
|
||||
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 clear(uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers);
|
||||
void setSamplerState(uint32_t _flags, const float _rgba[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);
|
||||
|
||||
+56
-2
@@ -1384,6 +1384,11 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
|
||||
m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _pitch, _mem);
|
||||
}
|
||||
|
||||
void clearTexture(TextureHandle _handle, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers) override
|
||||
{
|
||||
m_textures[_handle.idx].clear(_mip, _numMips, _layer, _numLayers);
|
||||
}
|
||||
|
||||
static MTL::PixelFormat getSwapChainPixelFormat(SwapChainMtl* _swapChain)
|
||||
{
|
||||
return NULL != _swapChain
|
||||
@@ -3656,6 +3661,55 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
|
||||
BufferMtl::create(_size, _data, _flags, stride, true);
|
||||
}
|
||||
|
||||
void TextureMtl::clear(uint8_t _baseMip, uint8_t _numMipsArg, uint16_t _baseLayer, uint16_t _numLayersArg)
|
||||
{
|
||||
const bimg::TextureFormat::Enum tf = bimg::TextureFormat::Enum(m_textureFormat);
|
||||
if (NULL == m_ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t bpp = bimg::getBitsPerPixel(tf);
|
||||
const bool is3D = MTL::TextureType3D == m_ptr->textureType();
|
||||
const bool isCube = TextureMtl::TextureCube == m_type;
|
||||
const uint32_t numMips = m_numMips;
|
||||
const uint32_t numSides = uint32_t(m_ptr->arrayLength() ) * (isCube ? 6 : 1);
|
||||
|
||||
const uint32_t mipBeg = bx::min<uint32_t>(_baseMip, numMips);
|
||||
const uint32_t mipEnd = (UINT8_MAX == _numMipsArg) ? numMips : bx::min<uint32_t>(numMips, uint32_t(_baseMip) + _numMipsArg);
|
||||
const uint32_t sideBeg = is3D ? 0 : bx::min<uint32_t>(_baseLayer, numSides);
|
||||
const uint32_t sideEnd = is3D ? 1 : ( (UINT16_MAX == _numLayersArg) ? numSides : bx::min<uint32_t>(numSides, uint32_t(_baseLayer) + _numLayersArg) );
|
||||
|
||||
const uint32_t tile = textureZeroInitTileDim(bpp);
|
||||
const uint32_t zeroPitch = tile * bpp / 8;
|
||||
uint8_t zeros[kTextureZeroInitBudget] = {};
|
||||
BX_ASSERT(zeroPitch * tile <= sizeof(zeros), "Zero-init tile exceeds budget.");
|
||||
|
||||
for (uint32_t side = sideBeg; side < sideEnd; ++side)
|
||||
{
|
||||
for (uint32_t lod = mipBeg; lod < mipEnd; ++lod)
|
||||
{
|
||||
const uint32_t mipW = bx::max<uint32_t>(1, m_width >> lod);
|
||||
const uint32_t mipH = bx::max<uint32_t>(1, m_height >> lod);
|
||||
const uint32_t mipD = is3D ? bx::max<uint32_t>(1, m_depth >> lod) : 1;
|
||||
|
||||
for (uint32_t zz = 0; zz < mipD; ++zz)
|
||||
{
|
||||
for (uint32_t yy = 0; yy < mipH; yy += tile)
|
||||
{
|
||||
const uint32_t th = bx::min<uint32_t>(tile, mipH - yy);
|
||||
for (uint32_t xx = 0; xx < mipW; xx += tile)
|
||||
{
|
||||
const uint32_t tw = bx::min<uint32_t>(tile, mipW - xx);
|
||||
MTL::Region region(xx, yy, zz, tw, th, 1);
|
||||
m_ptr->replaceRegion(region, lod, side, zeros, tw * bpp / 8, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextureMtl::create(const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external)
|
||||
{
|
||||
m_sampler = s_renderMtl->getSamplerState(uint32_t(_flags) );
|
||||
@@ -5175,8 +5229,8 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
|
||||
const uint64_t primType = 0;
|
||||
uint8_t primIndex = uint8_t(primType>>BGFX_STATE_PT_SHIFT);
|
||||
PrimInfo prim = s_primInfo[primIndex];
|
||||
const uint32_t maxComputeBindings = g_caps.limits.maxComputeBindings;
|
||||
const uint32_t maxTextureSamplers = g_caps.limits.maxTextureSamplers;
|
||||
const uint8_t maxComputeBindings = bx::narrowCast<uint8_t>(g_caps.limits.maxComputeBindings);
|
||||
const uint8_t maxTextureSamplers = bx::narrowCast<uint8_t>(g_caps.limits.maxTextureSamplers);
|
||||
|
||||
MTL::RenderCommandEncoder* rce = NULL;
|
||||
PipelineStateMtl* currentPso = NULL;
|
||||
|
||||
@@ -449,6 +449,8 @@ namespace bgfx { namespace mtl
|
||||
, const Memory* _mem
|
||||
);
|
||||
|
||||
void clear(uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers);
|
||||
|
||||
void commit(
|
||||
uint8_t _stage
|
||||
, bool _vertex
|
||||
|
||||
@@ -174,6 +174,10 @@ namespace bgfx { namespace noop
|
||||
{
|
||||
}
|
||||
|
||||
void clearTexture(TextureHandle /*_handle*/, uint8_t /*_mip*/, uint8_t /*_numMips*/, uint16_t /*_layer*/, uint16_t /*_numLayers*/) override
|
||||
{
|
||||
}
|
||||
|
||||
void readTexture(TextureHandle /*_handle*/, void* /*_data*/, uint16_t /*_layer*/, uint8_t /*_mip*/) override
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1220,6 +1220,8 @@ VK_IMPORT_DEVICE
|
||||
);
|
||||
}
|
||||
|
||||
struct TextureVK;
|
||||
|
||||
struct RendererContextVK : public RendererContextI
|
||||
{
|
||||
RendererContextVK()
|
||||
@@ -2613,6 +2615,11 @@ VK_IMPORT_DEVICE
|
||||
m_textures[_handle.idx].update(m_commandBuffer, _side, _mip, _rect, _z, _depth, _pitch, _mem);
|
||||
}
|
||||
|
||||
void clearTexture(TextureHandle _handle, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers) override
|
||||
{
|
||||
m_textures[_handle.idx].clear(m_commandBuffer, _mip, _numMips, _layer, _numLayers);
|
||||
}
|
||||
|
||||
void readTexture(TextureHandle _handle, void* _data, uint16_t _layer, uint8_t _mip) override
|
||||
{
|
||||
TextureVK& texture = m_textures[_handle.idx];
|
||||
@@ -7389,6 +7396,44 @@ VK_DESTROY
|
||||
}
|
||||
}
|
||||
|
||||
void TextureVK::clear(VkCommandBuffer _commandBuffer, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers)
|
||||
{
|
||||
const VkImageLayout saved = m_currentImageLayout;
|
||||
setState(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
const VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 0.0f } };
|
||||
|
||||
VkImageSubresourceRange range =
|
||||
{
|
||||
.aspectMask = m_aspectFlags,
|
||||
.baseMipLevel = _mip,
|
||||
.levelCount = (UINT8_MAX == _numMips)
|
||||
? VK_REMAINING_MIP_LEVELS
|
||||
: _numMips
|
||||
,
|
||||
.baseArrayLayer = _layer,
|
||||
.layerCount = (UINT16_MAX == _numLayers)
|
||||
? VK_REMAINING_ARRAY_LAYERS
|
||||
: _numLayers
|
||||
,
|
||||
};
|
||||
|
||||
vkCmdClearColorImage(
|
||||
_commandBuffer
|
||||
, m_textureImage
|
||||
, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
|
||||
, &clearColor
|
||||
, 1
|
||||
, &range
|
||||
);
|
||||
|
||||
if (VK_IMAGE_LAYOUT_UNDEFINED != saved
|
||||
&& VK_IMAGE_LAYOUT_PREINITIALIZED != saved)
|
||||
{
|
||||
setState(_commandBuffer, saved);
|
||||
}
|
||||
}
|
||||
|
||||
VkResult TextureVK::createView(uint32_t _layer, uint32_t _numLayers, uint32_t _mip, uint32_t _numMips, VkImageViewType _type, VkImageAspectFlags _aspectMask, bool _renderTarget, ::VkImageView* _view) const
|
||||
{
|
||||
VkResult result = VK_SUCCESS;
|
||||
|
||||
@@ -721,6 +721,7 @@ VK_DESTROY_FUNC(DescriptorSet);
|
||||
void destroy();
|
||||
|
||||
void update(VkCommandBuffer _commandBuffer, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
|
||||
void clear(VkCommandBuffer _commandBuffer, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers);
|
||||
void resolve(VkCommandBuffer _commandBuffer, uint8_t _resolve, uint32_t _layer, uint32_t _numLayers, uint32_t _mip);
|
||||
|
||||
void copyBufferToTexture(VkCommandBuffer _commandBuffer, VkBuffer _stagingBuffer, uint32_t _bufferImageCopyCount, VkBufferImageCopy* _bufferImageCopy);
|
||||
|
||||
@@ -1701,6 +1701,11 @@ WGPU_IMPORT
|
||||
m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _pitch, _mem);
|
||||
}
|
||||
|
||||
void clearTexture(TextureHandle _handle, uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers) override
|
||||
{
|
||||
m_textures[_handle.idx].clear(_mip, _numMips, _layer, _numLayers);
|
||||
}
|
||||
|
||||
bool s_done;
|
||||
|
||||
struct ReadTexture
|
||||
@@ -4200,6 +4205,81 @@ WGPU_IMPORT
|
||||
wgpuDestroy(m_textureResolve);
|
||||
}
|
||||
|
||||
void TextureWGPU::clear(uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers)
|
||||
{
|
||||
const bimg::TextureFormat::Enum format = bimg::TextureFormat::Enum(m_textureFormat);
|
||||
|
||||
if (0 != (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is3D = TextureWGPU::Texture3D == m_type;
|
||||
const uint32_t bpp = bimg::getBitsPerPixel(format);
|
||||
const uint8_t numMips = (UINT8_MAX == _numMips)
|
||||
? uint8_t(m_numMips - _mip)
|
||||
: _numMips
|
||||
;
|
||||
|
||||
const uint32_t tileDim = textureZeroInitTileDim(bpp);
|
||||
const uint32_t bytesPerRow = tileDim*bpp/8;
|
||||
uint8_t zeros[kTextureZeroInitBudget] = {};
|
||||
BX_ASSERT(bytesPerRow*tileDim <= sizeof(zeros), "Zero-init tile exceeds budget.");
|
||||
|
||||
for (uint8_t mip = _mip, mipEnd = uint8_t(_mip + numMips); mip < mipEnd; ++mip)
|
||||
{
|
||||
const uint32_t mipW = bx::max(1u, m_width >> mip);
|
||||
const uint32_t mipH = bx::max(1u, m_height >> mip);
|
||||
|
||||
const uint32_t totalSlices = is3D
|
||||
? bx::max(1u, m_depth >> mip)
|
||||
: m_numSides
|
||||
;
|
||||
const uint32_t numSlices = (UINT16_MAX == _numLayers)
|
||||
? (totalSlices - _layer)
|
||||
: _numLayers
|
||||
;
|
||||
|
||||
for (uint32_t slice = _layer, sliceEnd = _layer + numSlices; slice < sliceEnd; ++slice)
|
||||
{
|
||||
for (uint32_t yy = 0; yy < mipH; yy += tileDim)
|
||||
{
|
||||
const uint32_t th = bx::min<uint32_t>(tileDim, mipH - yy);
|
||||
|
||||
for (uint32_t xx = 0; xx < mipW; xx += tileDim)
|
||||
{
|
||||
const uint32_t tw = bx::min<uint32_t>(tileDim, mipW - xx);
|
||||
|
||||
s_renderWGPU->m_cmd.writeTexture(
|
||||
{
|
||||
.texture = m_texture,
|
||||
.mipLevel = mip,
|
||||
.origin =
|
||||
{
|
||||
.x = xx,
|
||||
.y = yy,
|
||||
.z = slice,
|
||||
},
|
||||
.aspect = WGPUTextureAspect_All,
|
||||
}
|
||||
, zeros
|
||||
, bytesPerRow*th
|
||||
, {
|
||||
.offset = 0,
|
||||
.bytesPerRow = bytesPerRow,
|
||||
.rowsPerImage = th,
|
||||
}
|
||||
, {
|
||||
.width = tw,
|
||||
.height = th,
|
||||
.depthOrArrayLayers = 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextureWGPU::update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem)
|
||||
{
|
||||
const uint32_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) );
|
||||
|
||||
@@ -638,6 +638,7 @@ namespace wgpu {
|
||||
void create(const Memory* _mem, uint64_t _flags, uint8_t _skip);
|
||||
void destroy();
|
||||
void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
|
||||
void clear(uint8_t _mip, uint8_t _numMips, uint16_t _layer, uint16_t _numLayers);
|
||||
|
||||
WGPUSampler getSamplerState(uint32_t _samplerFlags) const;
|
||||
WGPUTextureView getTextureView(uint8_t _baseMipLevel, uint8_t _mipLevelCount, bool _storage, uint16_t _baseArrayLayer = 0, uint16_t _arrayLayerCount = UINT16_MAX, bool _force2DArray = false) const;
|
||||
|
||||
Reference in New Issue
Block a user