mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-10-30 12:45:31 +00:00
Fixed integer render target clears and viewport depth range. (#4020)
This commit is contained in:
@@ -68,6 +68,8 @@ typedef void (GL_APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GL
|
||||
typedef void (GL_APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
typedef void (GL_APIENTRYP PFNGLCLEARDEPTHPROC) (GLdouble d);
|
||||
typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d);
|
||||
typedef void (GL_APIENTRYP PFNGLDEPTHRANGEPROC) (GLdouble n, GLdouble f);
|
||||
typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f);
|
||||
typedef void (GL_APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s);
|
||||
typedef void (GL_APIENTRYP PFNGLCLIPCONTROLPROC) (GLenum origin, GLenum depth);
|
||||
typedef void (GL_APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
|
||||
@@ -454,6 +456,7 @@ GL_IMPORT______(false, PFNGLVIEWPORTPROC, glViewport);
|
||||
|
||||
# if BGFX_CONFIG_RENDERER_OPENGL
|
||||
GL_IMPORT______(false, PFNGLCLEARDEPTHPROC, glClearDepth);
|
||||
GL_IMPORT______(false, PFNGLDEPTHRANGEPROC, glDepthRange);
|
||||
GL_IMPORT______(true, PFNGLPOINTSIZEPROC, glPointSize);
|
||||
GL_IMPORT______(true, PFNGLPOLYGONMODEPROC, glPolygonMode);
|
||||
|
||||
@@ -508,6 +511,7 @@ GL_IMPORT______(true, PFNGLTEXIMAGE3DMULTISAMPLEPROC, glTexImage3DM
|
||||
|
||||
# else // GLES
|
||||
GL_IMPORT______(false, PFNGLCLEARDEPTHFPROC, glClearDepthf);
|
||||
GL_IMPORT______(false, PFNGLDEPTHRANGEFPROC, glDepthRangef);
|
||||
GL_IMPORT_EXT__(true, PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC, glRenderbufferStorageMultisample);
|
||||
# endif // BGFX_CONFIG_RENDERER_OPENGL
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#define BGFX_RENDERER_H_HEADER_GUARD
|
||||
|
||||
#include "bgfx_p.h"
|
||||
#include <bx/pixelformat.h>
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
@@ -15,6 +16,51 @@ namespace bgfx
|
||||
bx::memCopy(&_viewName[4], _str.getPtr(), _str.getLength() );
|
||||
}
|
||||
|
||||
inline bool isIntegerFormat(TextureFormat::Enum _format)
|
||||
{
|
||||
const bx::EncodingType::Enum encoding = bx::EncodingType::Enum(bimg::getBlockInfo(bimg::TextureFormat::Enum(_format) ).encoding);
|
||||
return bx::EncodingType::Int == encoding
|
||||
|| bx::EncodingType::Uint == encoding
|
||||
;
|
||||
}
|
||||
|
||||
inline void getClearColor(float _rgba[4], const Clear& _clear, const float _palette[][4], uint32_t _attachment, bool _integer)
|
||||
{
|
||||
if (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags)
|
||||
{
|
||||
const uint8_t index = bx::min<uint8_t>(BGFX_CONFIG_MAX_COLOR_PALETTE-1, _clear.m_index[_attachment]);
|
||||
bx::memCopy(_rgba, _palette[index], sizeof(float)*4);
|
||||
}
|
||||
else
|
||||
{
|
||||
const float scale = _integer ? 1.0f : 1.0f/255.0f;
|
||||
_rgba[0] = _clear.m_index[0]*scale;
|
||||
_rgba[1] = _clear.m_index[1]*scale;
|
||||
_rgba[2] = _clear.m_index[2]*scale;
|
||||
_rgba[3] = _clear.m_index[3]*scale;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32_t packIntegerTexel(uint8_t* _out, TextureFormat::Enum _format, const float _rgba[4])
|
||||
{
|
||||
const bimg::ImageBlockInfo& info = bimg::getBlockInfo(bimg::TextureFormat::Enum(_format) );
|
||||
const uint8_t bits[4] = { info.rBits, info.gBits, info.bBits, info.aBits };
|
||||
|
||||
uint32_t size = 0;
|
||||
|
||||
for (uint32_t ii = 0; ii < 4; ++ii)
|
||||
{
|
||||
const int64_t value = int64_t(_rgba[ii]);
|
||||
|
||||
for (uint32_t bb = 0, num = bits[ii]/8; bb < num; ++bb)
|
||||
{
|
||||
_out[size++] = uint8_t(value >> (bb*8) );
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static constexpr uint32_t kTimerQueryBlock = 64;
|
||||
static constexpr uint32_t kMaxTimerQueries = BGFX_CONFIG_MAX_VIEWS*4;
|
||||
static constexpr uint32_t kMinTimerQueries = bx::min<uint32_t>(kTimerQueryBlock, kMaxTimerQueries);
|
||||
|
||||
+47
-2
@@ -505,6 +505,7 @@ namespace bgfx { namespace d3d11
|
||||
BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wunneeded-internal-declaration");
|
||||
|
||||
static const GUID IID_ID3D11Device1 = { 0xa04bfb29, 0x08ef, 0x43d6, { 0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86 } };
|
||||
static const GUID IID_ID3D11DeviceContext1 = { 0xbb2c6faa, 0xb5fb, 0x4082, { 0x8e, 0x6b, 0x38, 0x8b, 0x8c, 0xfa, 0x90, 0xe1 } };
|
||||
static const GUID IID_ID3D11Device2 = { 0x9d06dffa, 0xd1e5, 0x4d07, { 0x83, 0xa8, 0x1b, 0xb1, 0x23, 0xf2, 0xf8, 0x41 } };
|
||||
extern const GUID IID_ID3D11Device3 = { 0xa05c8c37, 0xd2c6, 0x4732, { 0xb3, 0xa0, 0x9c, 0xe0, 0xb0, 0xdc, 0x9a, 0xe6 } };
|
||||
static const GUID IID_ID3D11InfoQueue = { 0x6543dbb6, 0x1b48, 0x42f5, { 0xab, 0x82, 0xe9, 0x7e, 0xc7, 0x43, 0x26, 0xf6 } };
|
||||
@@ -800,6 +801,7 @@ namespace bgfx { namespace d3d11
|
||||
, m_device(NULL)
|
||||
, m_deviceCtx(NULL)
|
||||
, m_annotation(NULL)
|
||||
, m_deviceCtx1(NULL)
|
||||
, m_infoQueue(NULL)
|
||||
, m_deviceInterfaceVersion(0)
|
||||
, m_currentColor(NULL)
|
||||
@@ -1246,6 +1248,11 @@ namespace bgfx { namespace d3d11
|
||||
|
||||
m_numWindows = 1;
|
||||
|
||||
if (FAILED(m_deviceCtx->QueryInterface(IID_ID3D11DeviceContext1, (void**)&m_deviceCtx1) ) )
|
||||
{
|
||||
m_deviceCtx1 = NULL;
|
||||
}
|
||||
|
||||
#if USE_D3D11_DYNAMIC_LIB
|
||||
if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) )
|
||||
{
|
||||
@@ -1657,6 +1664,7 @@ namespace bgfx { namespace d3d11
|
||||
{
|
||||
case ErrorState::LoadedDXGI:
|
||||
DX_RELEASE(m_annotation, 1);
|
||||
DX_RELEASE_I(m_deviceCtx1);
|
||||
DX_RELEASE_W(m_infoQueue, 0);
|
||||
DX_RELEASE(mainFrameBuffer().m_msaaRt, 0);
|
||||
|
||||
@@ -1750,6 +1758,7 @@ namespace bgfx { namespace d3d11
|
||||
m_textures[ii].destroy();
|
||||
}
|
||||
|
||||
DX_RELEASE_I(m_deviceCtx1);
|
||||
DX_RELEASE(m_annotation, 1);
|
||||
dumpInfoQueue();
|
||||
DX_RELEASE_W(m_infoQueue, 0);
|
||||
@@ -3824,8 +3833,42 @@ namespace bgfx { namespace d3d11
|
||||
{
|
||||
ID3D11DeviceContext* deviceCtx = m_deviceCtx;
|
||||
|
||||
bool clearColor = 0 != (_clear.m_flags & BGFX_CLEAR_COLOR);
|
||||
|
||||
if (clearColor
|
||||
&& intColor
|
||||
&& NULL != m_deviceCtx1)
|
||||
{
|
||||
const FrameBufferD3D11& fb = m_frameBuffers[m_fbh.idx];
|
||||
const D3D11_RECT rect = { _rect.m_x, _rect.m_y, _rect.m_x + _rect.m_width, _rect.m_y + _rect.m_height };
|
||||
const uint8_t skipMask = _clear.getColorSkipMask(fb.m_num);
|
||||
|
||||
for (uint32_t ii = 0; ii < fb.m_num; ++ii)
|
||||
{
|
||||
if (NULL == fb.m_rtv[ii]
|
||||
|| 0 != (skipMask & (1<<ii) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const TextureFormat::Enum format = TextureFormat::Enum(m_textures[fb.m_attachment[ii].handle.idx].m_textureFormat);
|
||||
|
||||
float rgba[4];
|
||||
getClearColor(rgba, _clear, _palette, ii, isIntegerFormat(format) );
|
||||
|
||||
m_deviceCtx1->ClearView(fb.m_rtv[ii], rgba, &rect, 1);
|
||||
}
|
||||
|
||||
if (0 == (_clear.m_flags & (BGFX_CLEAR_DEPTH|BGFX_CLEAR_STENCIL) ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
clearColor = false;
|
||||
}
|
||||
|
||||
const uint64_t state = 0
|
||||
| (_clear.m_flags & BGFX_CLEAR_COLOR ? BGFX_STATE_WRITE_RGB|BGFX_STATE_WRITE_A : 0)
|
||||
| (clearColor ? BGFX_STATE_WRITE_RGB|BGFX_STATE_WRITE_A : 0)
|
||||
| (_clear.m_flags & BGFX_CLEAR_DEPTH ? BGFX_STATE_DEPTH_TEST_ALWAYS|BGFX_STATE_WRITE_Z : 0)
|
||||
;
|
||||
|
||||
@@ -3862,7 +3905,8 @@ namespace bgfx { namespace d3d11
|
||||
const float mrtClearDepth[4] = { _clear.m_depth };
|
||||
deviceCtx->UpdateSubresource(vsh->m_buffer, 0, 0, mrtClearDepth, 0, 0);
|
||||
|
||||
if (NULL != m_currentColor)
|
||||
if (clearColor
|
||||
&& NULL != m_currentColor)
|
||||
{
|
||||
const ShaderD3D11* fsh = program.m_fsh;
|
||||
deviceCtx->PSSetShader(fsh->m_pixelShader, NULL, 0);
|
||||
@@ -3973,6 +4017,7 @@ namespace bgfx { namespace d3d11
|
||||
ID3D11Device* m_device;
|
||||
ID3D11DeviceContext* m_deviceCtx;
|
||||
ID3DUserDefinedAnnotation* m_annotation;
|
||||
ID3D11DeviceContext1* m_deviceCtx1;
|
||||
ID3D11InfoQueue* m_infoQueue;
|
||||
|
||||
TimerQueryD3D11 m_gpuTimer;
|
||||
|
||||
@@ -4985,6 +4985,141 @@ namespace bgfx { namespace gl
|
||||
}
|
||||
else
|
||||
{
|
||||
bool intMrt = false;
|
||||
|
||||
if (isValid(fbh)
|
||||
&& NULL != glClearBufferfv
|
||||
&& NULL != glClearBufferiv
|
||||
&& NULL != glClearBufferuiv)
|
||||
{
|
||||
const FrameBufferGL& fb = m_frameBuffers[fbh.idx];
|
||||
|
||||
for (uint32_t ii = 0; ii < fb.m_numTh && !intMrt; ++ii)
|
||||
{
|
||||
const Attachment& at = fb.m_attachment[ii];
|
||||
|
||||
if (!isValid(at.handle) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const TextureFormat::Enum format = TextureFormat::Enum(m_textures[at.handle.idx].m_textureFormat);
|
||||
|
||||
if (bimg::isDepth(bimg::TextureFormat::Enum(format) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const bx::EncodingType::Enum enc = bx::EncodingType::Enum(bimg::getBlockInfo(bimg::TextureFormat::Enum(format) ).encoding);
|
||||
intMrt = bx::EncodingType::Int == enc
|
||||
|| bx::EncodingType::Uint == enc
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (intMrt)
|
||||
{
|
||||
const FrameBufferGL& fb = m_frameBuffers[fbh.idx];
|
||||
const bool usePalette = 0 != (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags);
|
||||
|
||||
GL_CHECK(glEnable(GL_SCISSOR_TEST) );
|
||||
GL_CHECK(glScissor(_rect.m_x, rectY, _rect.m_width, _rect.m_height) );
|
||||
GL_CHECK(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE) );
|
||||
|
||||
if (BGFX_CLEAR_COLOR & _clear.m_flags)
|
||||
{
|
||||
GLint drawBuffer = 0;
|
||||
|
||||
for (uint32_t ii = 0; ii < fb.m_numTh; ++ii)
|
||||
{
|
||||
const Attachment& at = fb.m_attachment[ii];
|
||||
|
||||
if (!isValid(at.handle) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const TextureFormat::Enum format = TextureFormat::Enum(m_textures[at.handle.idx].m_textureFormat);
|
||||
|
||||
if (bimg::isDepth(bimg::TextureFormat::Enum(format) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint8_t index = usePalette ? _clear.m_index[drawBuffer] : 0;
|
||||
|
||||
if (usePalette
|
||||
&& UINT8_MAX == index)
|
||||
{
|
||||
++drawBuffer;
|
||||
continue;
|
||||
}
|
||||
|
||||
const float* palette = usePalette
|
||||
? _palette[bx::min<uint8_t>(BGFX_CONFIG_MAX_COLOR_PALETTE-1, index)]
|
||||
: NULL
|
||||
;
|
||||
|
||||
const bx::EncodingType::Enum enc = bx::EncodingType::Enum(bimg::getBlockInfo(bimg::TextureFormat::Enum(format) ).encoding);
|
||||
|
||||
if (bx::EncodingType::Uint == enc
|
||||
|| bx::EncodingType::Int == enc)
|
||||
{
|
||||
GLint value[4];
|
||||
|
||||
for (uint32_t cc = 0; cc < 4; ++cc)
|
||||
{
|
||||
value[cc] = NULL != palette
|
||||
? GLint(palette[cc])
|
||||
: GLint(_clear.m_index[cc])
|
||||
;
|
||||
}
|
||||
|
||||
if (bx::EncodingType::Uint == enc)
|
||||
{
|
||||
GL_CHECK(glClearBufferuiv(GL_COLOR, drawBuffer, (const GLuint*)value) );
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_CHECK(glClearBufferiv(GL_COLOR, drawBuffer, value) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float rgba[4];
|
||||
|
||||
for (uint32_t cc = 0; cc < 4; ++cc)
|
||||
{
|
||||
rgba[cc] = NULL != palette
|
||||
? palette[cc]
|
||||
: _clear.m_index[cc]*1.0f/255.0f
|
||||
;
|
||||
}
|
||||
|
||||
GL_CHECK(glClearBufferfv(GL_COLOR, drawBuffer, rgba) );
|
||||
}
|
||||
|
||||
++drawBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
if (BGFX_CLEAR_DEPTH & _clear.m_flags)
|
||||
{
|
||||
GL_CHECK(glDepthMask(GL_TRUE) );
|
||||
GL_CHECK(glClearBufferfv(GL_DEPTH, 0, &_clear.m_depth) );
|
||||
}
|
||||
|
||||
if (BGFX_CLEAR_STENCIL & _clear.m_flags)
|
||||
{
|
||||
const GLint stencil = _clear.m_stencil;
|
||||
GL_CHECK(glStencilMask(0xff) );
|
||||
GL_CHECK(glClearBufferiv(GL_STENCIL, 0, &stencil) );
|
||||
}
|
||||
|
||||
GL_CHECK(glDisable(GL_SCISSOR_TEST) );
|
||||
return;
|
||||
}
|
||||
|
||||
if (0 != m_vao)
|
||||
{
|
||||
GL_CHECK(glBindVertexArray(m_vao) );
|
||||
@@ -8821,6 +8956,13 @@ namespace bgfx { namespace gl
|
||||
float currentPolygonOffsetSlope = 0.0f;
|
||||
float currentPolygonOffsetClamp = 0.0f;
|
||||
|
||||
GL_CHECK(glDisable(GL_POLYGON_OFFSET_FILL) );
|
||||
|
||||
if (s_extension[Extension::ARB_depth_clamp].m_supported)
|
||||
{
|
||||
GL_CHECK(glDisable(GL_DEPTH_CLAMP) );
|
||||
}
|
||||
|
||||
UniformCacheState ucs(_render);
|
||||
BlitState bs(_render);
|
||||
|
||||
@@ -8973,6 +9115,8 @@ namespace bgfx { namespace gl
|
||||
, viewState.m_rect.m_height
|
||||
) );
|
||||
|
||||
GL_CHECK(glDepthRange(0.0f, 1.0f) );
|
||||
|
||||
const Clear& clear = renderView->m_clear;
|
||||
discardFlags = clear.m_flags & BGFX_CLEAR_DISCARD_MASK;
|
||||
|
||||
@@ -8984,6 +9128,7 @@ namespace bgfx { namespace gl
|
||||
GL_CHECK(glDisable(GL_STENCIL_TEST) );
|
||||
GL_CHECK(glEnable(GL_DEPTH_TEST) );
|
||||
GL_CHECK(glDepthFunc(GL_LESS) );
|
||||
GL_CHECK(glDepthRange(renderView->m_minDepth, renderView->m_maxDepth) );
|
||||
GL_CHECK(glEnable(GL_CULL_FACE) );
|
||||
GL_CHECK(glDisable(GL_BLEND) );
|
||||
}
|
||||
|
||||
@@ -1231,6 +1231,7 @@ typedef double GLdouble;
|
||||
|
||||
#if !BGFX_CONFIG_RENDERER_OPENGL
|
||||
# define glClearDepth glClearDepthf
|
||||
# define glDepthRange glDepthRangef
|
||||
#endif // !BGFX_CONFIG_RENDERER_OPENGL
|
||||
|
||||
namespace bgfx
|
||||
|
||||
+111
-18
@@ -2358,6 +2358,91 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
|
||||
}
|
||||
}
|
||||
|
||||
bool clearIntegerColor(FrameBufferHandle _fbh, const Rect& _rect, const Clear& _clear, const float _palette[][4])
|
||||
{
|
||||
if (!isValid(_fbh)
|
||||
|| 0 == (_clear.m_flags & BGFX_CLEAR_COLOR) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const FrameBufferMtl& fb = m_frameBuffers[_fbh.idx];
|
||||
|
||||
bool integer = false;
|
||||
|
||||
for (uint32_t ii = 0; ii < fb.m_num; ++ii)
|
||||
{
|
||||
const TextureMtl& texture = m_textures[fb.m_colorHandle[ii].idx];
|
||||
integer |= NULL == texture.m_ptrMsaa
|
||||
&& isIntegerFormat(TextureFormat::Enum(texture.m_textureFormat) )
|
||||
;
|
||||
}
|
||||
|
||||
if (!integer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t skipMask = _clear.getColorSkipMask(fb.m_num);
|
||||
|
||||
for (uint32_t ii = 0; ii < fb.m_num; ++ii)
|
||||
{
|
||||
if (0 != (skipMask & (1<<ii) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const TextureMtl& texture = m_textures[fb.m_colorHandle[ii].idx];
|
||||
const TextureFormat::Enum format = TextureFormat::Enum(texture.m_textureFormat);
|
||||
|
||||
if (NULL != texture.m_ptrMsaa
|
||||
|| !isIntegerFormat(format) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
float rgba[4];
|
||||
getClearColor(rgba, _clear, _palette, ii, true);
|
||||
|
||||
uint8_t texel[16];
|
||||
const uint32_t texelSize = packIntegerTexel(texel, format, rgba);
|
||||
const uint32_t pitch = _rect.m_width*texelSize;
|
||||
const uint32_t size = pitch*_rect.m_height;
|
||||
|
||||
MTL::Buffer* buffer = m_device->newBuffer(size, MTL::ResourceStorageModeShared);
|
||||
uint8_t* data = (uint8_t*)buffer->contents();
|
||||
|
||||
for (uint32_t xx = 0; xx < _rect.m_width; ++xx)
|
||||
{
|
||||
bx::memCopy(data + xx*texelSize, texel, texelSize);
|
||||
}
|
||||
|
||||
for (uint32_t yy = 1; yy < _rect.m_height; ++yy)
|
||||
{
|
||||
bx::memCopy(data + yy*pitch, data, pitch);
|
||||
}
|
||||
|
||||
MTL::BlitCommandEncoder* bce = getBlitCommandEncoder();
|
||||
bce->copyFromBuffer(
|
||||
buffer
|
||||
, 0
|
||||
, pitch
|
||||
, size
|
||||
, MTL::Size::Make(_rect.m_width, _rect.m_height, 1)
|
||||
, texture.m_ptr
|
||||
, 0
|
||||
, 0
|
||||
, MTL::Origin::Make(_rect.m_x, _rect.m_y, 0)
|
||||
);
|
||||
|
||||
MTL_RELEASE_I(buffer);
|
||||
}
|
||||
|
||||
endBlitEncoding();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void clearQuad(const ClearQuad& _clearQuad, const Rect& /*_rect*/, const Clear& _clear, const float _palette[][4])
|
||||
{
|
||||
const uint64_t state = 0
|
||||
@@ -6258,6 +6343,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
|
||||
|
||||
const Rect viewRect = viewState.m_rect;
|
||||
bool clearWithRenderPass = false;
|
||||
bool integerCleared = false;
|
||||
|
||||
if (NULL == m_renderCommandEncoder
|
||||
|| fbh.idx != renderView->m_fbh.idx
|
||||
@@ -6294,6 +6380,10 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
|
||||
&& height == viewRect.m_height
|
||||
;
|
||||
|
||||
integerCleared = !clearWithRenderPass
|
||||
&& clearIntegerColor(fbh, clippedRect, clr, _render->m_colorPalette)
|
||||
;
|
||||
|
||||
setFrameBuffer(renderPassDescriptor, fbh);
|
||||
|
||||
if (clearWithRenderPass)
|
||||
@@ -6437,30 +6527,33 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
|
||||
|
||||
rce->setTriangleFillMode( (MTL::TriangleFillMode)wireframe ? MTL::TriangleFillModeLines : MTL::TriangleFillModeFill);
|
||||
|
||||
{
|
||||
MTL::Viewport vp;
|
||||
vp.originX = viewState.m_rect.m_x;
|
||||
vp.originY = viewState.m_rect.m_y;
|
||||
vp.width = viewState.m_rect.m_width;
|
||||
vp.height = viewState.m_rect.m_height;
|
||||
vp.znear = 0.0f;
|
||||
vp.zfar = 1.0f;
|
||||
rce->setViewport(vp);
|
||||
MTL::Viewport vp;
|
||||
vp.originX = viewState.m_rect.m_x;
|
||||
vp.originY = viewState.m_rect.m_y;
|
||||
vp.width = viewState.m_rect.m_width;
|
||||
vp.height = viewState.m_rect.m_height;
|
||||
vp.znear = 0.0f;
|
||||
vp.zfar = 1.0f;
|
||||
rce->setViewport(vp);
|
||||
|
||||
MTL::ScissorRect sciRect = {
|
||||
NS::UInteger(clippedRect.m_x),
|
||||
NS::UInteger(clippedRect.m_y),
|
||||
NS::UInteger(clippedRect.m_width),
|
||||
NS::UInteger(clippedRect.m_height)
|
||||
};
|
||||
rce->setScissorRect(sciRect);
|
||||
}
|
||||
MTL::ScissorRect sciRect = {
|
||||
NS::UInteger(clippedRect.m_x),
|
||||
NS::UInteger(clippedRect.m_y),
|
||||
NS::UInteger(clippedRect.m_width),
|
||||
NS::UInteger(clippedRect.m_height)
|
||||
};
|
||||
rce->setScissorRect(sciRect);
|
||||
|
||||
if (BGFX_CLEAR_NONE != (clr.m_flags & BGFX_CLEAR_MASK)
|
||||
&& !clearWithRenderPass)
|
||||
&& !clearWithRenderPass
|
||||
&& !integerCleared)
|
||||
{
|
||||
clearQuad(_clearQuad, clippedRect, clr, _render->m_colorPalette);
|
||||
}
|
||||
|
||||
vp.znear = renderView->m_minDepth;
|
||||
vp.zfar = renderView->m_maxDepth;
|
||||
rce->setViewport(vp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+120
-1
@@ -2495,6 +2495,105 @@ WGPU_IMPORT
|
||||
wgpuRelease(blitRenderPassEncoder);
|
||||
}
|
||||
|
||||
bool clearIntegerColor(WGPUCommandEncoder _commandEncoder, const FrameBufferWGPU& _fb, const Rect& _rect, const Clear& _clear, const float _palette[][4])
|
||||
{
|
||||
if (0 == (_clear.m_flags & BGFX_CLEAR_COLOR)
|
||||
|| 1 < _fb.m_msaaCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool integer = false;
|
||||
|
||||
for (uint32_t ii = 0; ii < _fb.m_numColorAttachments; ++ii)
|
||||
{
|
||||
const TextureWGPU& texture = m_textures[_fb.m_texture[ii].idx];
|
||||
integer |= isIntegerFormat(TextureFormat::Enum(texture.m_textureFormat) );
|
||||
}
|
||||
|
||||
if (!integer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t skipMask = _clear.getColorSkipMask(_fb.m_numColorAttachments);
|
||||
|
||||
for (uint32_t ii = 0; ii < _fb.m_numColorAttachments; ++ii)
|
||||
{
|
||||
if (0 != (skipMask & (1<<ii) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const TextureWGPU& texture = m_textures[_fb.m_texture[ii].idx];
|
||||
const TextureFormat::Enum format = TextureFormat::Enum(texture.m_textureFormat);
|
||||
|
||||
if (!isIntegerFormat(format) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
float rgba[4];
|
||||
getClearColor(rgba, _clear, _palette, ii, true);
|
||||
|
||||
uint8_t texel[16];
|
||||
const uint32_t texelSize = packIntegerTexel(texel, format, rgba);
|
||||
const uint32_t pitch = bx::alignUp(_rect.m_width*texelSize, 256);
|
||||
const uint32_t size = bx::alignUp(pitch*(_rect.m_height-1) + _rect.m_width*texelSize, 4);
|
||||
|
||||
uint8_t* data = (uint8_t*)bx::alloc(g_allocator, size);
|
||||
|
||||
for (uint32_t yy = 0; yy < _rect.m_height; ++yy)
|
||||
{
|
||||
uint8_t* row = data + yy*pitch;
|
||||
|
||||
for (uint32_t xx = 0; xx < _rect.m_width; ++xx)
|
||||
{
|
||||
bx::memCopy(row + xx*texelSize, texel, texelSize);
|
||||
}
|
||||
}
|
||||
|
||||
const WGPUBufferDescriptor bufferDesc =
|
||||
{
|
||||
.nextInChain = NULL,
|
||||
.label = toWGPUStringView("Integer clear"),
|
||||
.usage = WGPUBufferUsage_CopySrc | WGPUBufferUsage_CopyDst,
|
||||
.size = size,
|
||||
.mappedAtCreation = false,
|
||||
};
|
||||
|
||||
WGPUBuffer buffer = WGPU_CHECK(wgpuDeviceCreateBuffer(m_device, &bufferDesc) );
|
||||
m_cmd.writeBuffer(buffer, 0, data, size);
|
||||
bx::free(g_allocator, data);
|
||||
|
||||
const WGPUTexelCopyBufferInfo source =
|
||||
{
|
||||
.layout =
|
||||
{
|
||||
.offset = 0,
|
||||
.bytesPerRow = pitch,
|
||||
.rowsPerImage = _rect.m_height,
|
||||
},
|
||||
.buffer = buffer,
|
||||
};
|
||||
|
||||
const WGPUTexelCopyTextureInfo destination =
|
||||
{
|
||||
.texture = texture.m_texture,
|
||||
.mipLevel = 0,
|
||||
.origin = { uint32_t(_rect.m_x), uint32_t(_rect.m_y), 0 },
|
||||
.aspect = WGPUTextureAspect_All,
|
||||
};
|
||||
|
||||
const WGPUExtent3D extent = { _rect.m_width, _rect.m_height, 1 };
|
||||
|
||||
WGPU_CHECK(wgpuCommandEncoderCopyBufferToTexture(_commandEncoder, &source, &destination, &extent) );
|
||||
wgpuBufferRelease(buffer);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void clearQuad(WGPURenderPassEncoder _renderPassEncoder, FrameBufferHandle _fbh, uint32_t _msaaCount, const ClearQuad& _clearQuad, const Rect& _rect, const Clear& _clear, const float _palette[][4])
|
||||
{
|
||||
BX_UNUSED(_clearQuad, _rect, _clear, _palette);
|
||||
@@ -7239,6 +7338,14 @@ WGPU_IMPORT
|
||||
if (isFrameBufferValid)
|
||||
{
|
||||
WGPUCommandEncoder cmdEncoder = m_cmd.alloc();
|
||||
|
||||
const bool integerCleared = true
|
||||
&& !clearWhole
|
||||
&& needClear
|
||||
&& !isSwapChain
|
||||
&& clearIntegerColor(cmdEncoder, fb, clippedRect, clr, _render->m_colorPalette)
|
||||
;
|
||||
|
||||
renderPassEncoder = WGPU_CHECK(wgpuCommandEncoderBeginRenderPass(cmdEncoder, &renderPassDesc) );
|
||||
currentPipeline = NULL;
|
||||
|
||||
@@ -7254,11 +7361,23 @@ WGPU_IMPORT
|
||||
, 1.0f
|
||||
);
|
||||
|
||||
if (!clearWhole && needClear)
|
||||
if (!clearWhole
|
||||
&& needClear
|
||||
&& !integerCleared)
|
||||
{
|
||||
clearQuad(renderPassEncoder, fbh, msaaCount, _clearQuad, clippedRect, clr, _render->m_colorPalette);
|
||||
}
|
||||
|
||||
wgpuRenderPassEncoderSetViewport(
|
||||
renderPassEncoder
|
||||
, float(viewRect.m_x)
|
||||
, float(viewRect.m_y)
|
||||
, float(viewRect.m_width)
|
||||
, float(viewRect.m_height)
|
||||
, renderView->m_minDepth
|
||||
, renderView->m_maxDepth
|
||||
);
|
||||
|
||||
wgpuRenderPassEncoderSetScissorRect(
|
||||
renderPassEncoder
|
||||
, uint32_t(viewScissorRect.m_x)
|
||||
|
||||
Reference in New Issue
Block a user