From 6adfc48baedb1f6d17285b6f45e1804e717ec76f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Fri, 7 Sep 2018 17:07:33 -0700 Subject: [PATCH] Added limit info for maximum number of compute bindings. --- include/bgfx/bgfx.h | 1 + include/bgfx/c99/bgfx.h | 1 + include/bgfx/defines.h | 2 +- src/bgfx.cpp | 23 ++++++++++++++++------- src/renderer_d3d11.cpp | 22 ++++++++++++++++------ src/renderer_d3d12.cpp | 15 +++++++++------ src/renderer_gl.cpp | 10 ++++++---- src/renderer_vk.cpp | 11 +++++++---- 8 files changed, 57 insertions(+), 28 deletions(-) diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h index ebabce7cd..c582af254 100644 --- a/include/bgfx/bgfx.h +++ b/include/bgfx/bgfx.h @@ -722,6 +722,7 @@ namespace bgfx uint32_t maxShaders; //!< Maximum number of shader handles. uint32_t maxTextures; //!< Maximum number of texture handles. uint32_t maxTextureSamplers; //!< Maximum number of texture samplers. + uint32_t maxComputeBindings; //!< Maximum number of compute bindings. uint32_t maxVertexDecls; //!< Maximum number of vertex format declarations. uint32_t maxVertexStreams; //!< Maximum number of vertex streams. uint32_t maxIndexBuffers; //!< Maximum number of index buffer handles. diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h index 8f69074b1..48039044c 100644 --- a/include/bgfx/c99/bgfx.h +++ b/include/bgfx/c99/bgfx.h @@ -509,6 +509,7 @@ typedef struct bgfx_caps_limits_s uint32_t maxShaders; uint32_t maxTextures; uint32_t maxTextureSamplers; + uint32_t maxComputeBindings; uint32_t maxVertexDecls; uint32_t maxVertexStreams; uint32_t maxIndexBuffers; diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h index f7a7695bd..b73e8465e 100644 --- a/include/bgfx/defines.h +++ b/include/bgfx/defines.h @@ -6,7 +6,7 @@ #ifndef BGFX_DEFINES_H_HEADER_GUARD #define BGFX_DEFINES_H_HEADER_GUARD -#define BGFX_API_VERSION UINT32_C(79) +#define BGFX_API_VERSION UINT32_C(80) /// Color RGB/alpha/depth write. When it's not specified write will be disabled. #define BGFX_STATE_WRITE_R UINT64_C(0x0000000000000001) //!< Enable R write. diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 650b1fb9c..e51291582 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -1268,6 +1268,7 @@ namespace bgfx LIMITS(maxShaders); LIMITS(maxTextures); LIMITS(maxTextureSamplers); + LIMITS(maxComputeBindings); LIMITS(maxVertexDecls); LIMITS(maxVertexStreams); LIMITS(maxIndexBuffers); @@ -2837,6 +2838,13 @@ namespace bgfx return false; } + if (1 <= _init.limits.maxEncoders + && 128 <= _init.limits.maxEncoders) + { + BX_TRACE("init.limits.maxEncoders must be between 1 and 128."); + return false; + } + struct ErrorState { enum Enum @@ -2893,6 +2901,7 @@ namespace bgfx g_caps.limits.maxShaders = BGFX_CONFIG_MAX_SHADERS; g_caps.limits.maxTextures = BGFX_CONFIG_MAX_TEXTURES; g_caps.limits.maxTextureSamplers = BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; + g_caps.limits.maxComputeBindings = 0; g_caps.limits.maxVertexDecls = BGFX_CONFIG_MAX_VERTEX_DECLS; g_caps.limits.maxVertexStreams = 1; g_caps.limits.maxIndexBuffers = BGFX_CONFIG_MAX_INDEX_BUFFERS; @@ -3168,7 +3177,7 @@ namespace bgfx { BGFX_CHECK_HANDLE("setTexture/UniformHandle", s_ctx->m_uniformHandle, _sampler); BGFX_CHECK_HANDLE_INVALID_OK("setTexture/TextureHandle", s_ctx->m_textureHandle, _handle); - BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); + BX_CHECK(_stage < g_caps.limits.maxTextureSamplers, "Invalid stage %d (max %d).", _stage, g_caps.limits.maxTextureSamplers); BGFX_ENCODER(setTexture(_stage, _sampler, _handle, _flags) ); } @@ -3206,21 +3215,21 @@ namespace bgfx void Encoder::setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access) { - BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); + BX_CHECK(_stage < g_caps.limits.maxComputeBindings, "Invalid stage %d (max %d).", _stage, g_caps.limits.maxComputeBindings); BGFX_CHECK_HANDLE("setBuffer", s_ctx->m_indexBufferHandle, _handle); BGFX_ENCODER(setBuffer(_stage, _handle, _access) ); } void Encoder::setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access) { - BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); + BX_CHECK(_stage < g_caps.limits.maxComputeBindings, "Invalid stage %d (max %d).", _stage, g_caps.limits.maxComputeBindings); BGFX_CHECK_HANDLE("setBuffer", s_ctx->m_vertexBufferHandle, _handle); BGFX_ENCODER(setBuffer(_stage, _handle, _access) ); } void Encoder::setBuffer(uint8_t _stage, DynamicIndexBufferHandle _handle, Access::Enum _access) { - BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); + BX_CHECK(_stage < g_caps.limits.maxComputeBindings, "Invalid stage %d (max %d).", _stage, g_caps.limits.maxComputeBindings); BGFX_CHECK_HANDLE("setBuffer", s_ctx->m_dynamicIndexBufferHandle, _handle); const DynamicIndexBuffer& dib = s_ctx->m_dynamicIndexBuffers[_handle.idx]; BGFX_ENCODER(setBuffer(_stage, dib.m_handle, _access) ); @@ -3228,7 +3237,7 @@ namespace bgfx void Encoder::setBuffer(uint8_t _stage, DynamicVertexBufferHandle _handle, Access::Enum _access) { - BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); + BX_CHECK(_stage < g_caps.limits.maxComputeBindings, "Invalid stage %d (max %d).", _stage, g_caps.limits.maxComputeBindings); BGFX_CHECK_HANDLE("setBuffer", s_ctx->m_dynamicVertexBufferHandle, _handle); const DynamicVertexBuffer& dvb = s_ctx->m_dynamicVertexBuffers[_handle.idx]; BGFX_ENCODER(setBuffer(_stage, dvb.m_handle, _access) ); @@ -3236,7 +3245,7 @@ namespace bgfx void Encoder::setBuffer(uint8_t _stage, IndirectBufferHandle _handle, Access::Enum _access) { - BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); + BX_CHECK(_stage < g_caps.limits.maxComputeBindings, "Invalid stage %d (max %d).", _stage, g_caps.limits.maxComputeBindings); BGFX_CHECK_HANDLE("setBuffer", s_ctx->m_vertexBufferHandle, _handle); VertexBufferHandle handle = { _handle.idx }; BGFX_ENCODER(setBuffer(_stage, handle, _access) ); @@ -3244,7 +3253,7 @@ namespace bgfx void Encoder::setImage(uint8_t _stage, TextureHandle _handle, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format) { - BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); + BX_CHECK(_stage < g_caps.limits.maxComputeBindings, "Invalid stage %d (max %d).", _stage, g_caps.limits.maxComputeBindings); BGFX_CHECK_HANDLE_INVALID_OK("setImage/TextureHandle", s_ctx->m_textureHandle, _handle); _format = TextureFormat::Count == _format ? TextureFormat::Enum(s_ctx->m_textureRef[_handle.idx].m_format) diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index c0759dc76..27a4d7a88 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -40,7 +40,7 @@ namespace bgfx { namespace d3d11 } ID3D11Buffer* m_buffer[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; - ID3D11UnorderedAccessView* m_uav[D3D11_PS_CS_UAV_REGISTER_COUNT]; + ID3D11UnorderedAccessView* m_uav[D3D11_1_UAV_SLOT_COUNT]; ID3D11ShaderResourceView* m_srv[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; ID3D11SamplerState* m_sampler[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; ID3D11RenderTargetView* m_rtv[BGFX_CONFIG_MAX_FRAME_BUFFERS]; @@ -1177,6 +1177,12 @@ namespace bgfx { namespace d3d11 } else { + g_caps.limits.maxComputeBindings = bx::min(BGFX_MAX_COMPUTE_BINDINGS + , 1 <= m_deviceInterfaceVersion + ? D3D11_1_UAV_SLOT_COUNT + : D3D11_PS_CS_UAV_REGISTER_COUNT + ); + g_caps.supported |= BGFX_CAPS_TEXTURE_COMPARE_ALL; g_caps.limits.maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; g_caps.limits.maxTextureLayers = D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; @@ -2226,10 +2232,12 @@ namespace bgfx { namespace d3d11 void invalidateCompute() { + const uint32_t maxComputeBindings = g_caps.limits.maxComputeBindings; + m_deviceCtx->CSSetShader(NULL, NULL, 0); - m_deviceCtx->CSSetUnorderedAccessViews(0, BGFX_MAX_COMPUTE_BINDINGS, s_zero.m_uav, NULL); - m_deviceCtx->CSSetShaderResources(0, BGFX_MAX_COMPUTE_BINDINGS, s_zero.m_srv); - m_deviceCtx->CSSetSamplers(0, BGFX_MAX_COMPUTE_BINDINGS, s_zero.m_sampler); + m_deviceCtx->CSSetUnorderedAccessViews(0, maxComputeBindings, s_zero.m_uav, NULL); + m_deviceCtx->CSSetShaderResources(0, maxComputeBindings, s_zero.m_srv); + m_deviceCtx->CSSetSamplers(0, maxComputeBindings, s_zero.m_sampler); } void updateMsaa(DXGI_FORMAT _format) const @@ -5226,6 +5234,8 @@ namespace bgfx { namespace d3d11 Rect viewScissorRect; viewScissorRect.clear(); + const uint32_t maxComputeBindings = g_caps.limits.maxComputeBindings; + uint32_t statsNumPrimsSubmitted[BX_COUNTOF(s_primInfo)] = {}; uint32_t statsNumPrimsRendered[BX_COUNTOF(s_primInfo)] = {}; uint32_t statsNumInstances[BX_COUNTOF(s_primInfo)] = {}; @@ -5443,7 +5453,7 @@ namespace bgfx { namespace d3d11 ID3D11ShaderResourceView* srv[BGFX_MAX_COMPUTE_BINDINGS] = {}; ID3D11SamplerState* sampler[BGFX_MAX_COMPUTE_BINDINGS] = {}; - for (uint32_t ii = 0; ii < BGFX_MAX_COMPUTE_BINDINGS; ++ii) + for (uint32_t ii = 0; ii < maxComputeBindings; ++ii) { const Binding& bind = renderBind.m_bind[ii]; if (kInvalidHandle != bind.m_idx) @@ -5493,7 +5503,7 @@ namespace bgfx { namespace d3d11 if (BX_ENABLED(BGFX_CONFIG_DEBUG) ) { // Quiet validation: Resource being set to CS UnorderedAccessView slot 0 is still bound on input! - deviceCtx->CSSetShaderResources(0, BGFX_MAX_COMPUTE_BINDINGS, s_zero.m_srv); + deviceCtx->CSSetShaderResources(0, maxComputeBindings, s_zero.m_srv); } deviceCtx->CSSetUnorderedAccessViews(0, BX_COUNTOF(uav), uav, NULL); deviceCtx->CSSetShaderResources(0, BX_COUNTOF(srv), srv); diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index b3f9016fb..8a447b00c 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -1088,10 +1088,11 @@ namespace bgfx { namespace d3d12 | BGFX_CAPS_TEXTURE_2D_ARRAY | BGFX_CAPS_TEXTURE_CUBE_ARRAY ); - g_caps.limits.maxTextureSize = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; - g_caps.limits.maxTextureLayers = D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; - g_caps.limits.maxFBAttachments = uint8_t(bx::uint32_min(16, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) ); - g_caps.limits.maxVertexStreams = BGFX_CONFIG_MAX_VERTEX_STREAMS; + g_caps.limits.maxTextureSize = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; + g_caps.limits.maxTextureLayers = D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; + g_caps.limits.maxFBAttachments = bx::min(16, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS); + g_caps.limits.maxComputeBindings = bx::min(D3D12_UAV_SLOT_COUNT, BGFX_MAX_COMPUTE_BINDINGS); + g_caps.limits.maxVertexStreams = BGFX_CONFIG_MAX_VERTEX_STREAMS; for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) { @@ -5605,6 +5606,8 @@ namespace bgfx { namespace d3d12 Rect viewScissorRect; viewScissorRect.clear(); + const uint32_t maxComputeBindings = g_caps.limits.maxComputeBindings; + uint32_t statsNumPrimsSubmitted[BX_COUNTOF(s_primInfo)] = {}; uint32_t statsNumPrimsRendered[BX_COUNTOF(s_primInfo)] = {}; uint32_t statsNumInstances[BX_COUNTOF(s_primInfo)] = {}; @@ -5802,7 +5805,7 @@ namespace bgfx { namespace d3d12 D3D12_GPU_DESCRIPTOR_HANDLE srvHandle[BGFX_MAX_COMPUTE_BINDINGS] = {}; uint32_t samplerFlags[BGFX_MAX_COMPUTE_BINDINGS] = {}; - for (uint32_t ii = 0; ii < BGFX_MAX_COMPUTE_BINDINGS; ++ii) + for (uint32_t ii = 0; ii < maxComputeBindings; ++ii) { const Binding& bind = renderBind.m_bind[ii]; if (kInvalidHandle != bind.m_idx) @@ -5852,7 +5855,7 @@ namespace bgfx { namespace d3d12 } } - uint16_t samplerStateIdx = getSamplerState(samplerFlags, BGFX_MAX_COMPUTE_BINDINGS, _render->m_colorPalette); + uint16_t samplerStateIdx = getSamplerState(samplerFlags, maxComputeBindings, _render->m_colorPalette); if (samplerStateIdx != currentSamplerStateIdx) { currentSamplerStateIdx = samplerStateIdx; diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 273b4afa8..858565263 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -2321,9 +2321,10 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) ); : 0 ; - g_caps.limits.maxTextureSize = uint16_t(glGet(GL_MAX_TEXTURE_SIZE) ); - g_caps.limits.maxTextureLayers = uint16_t(bx::max(glGet(GL_MAX_ARRAY_TEXTURE_LAYERS), 1) ); - g_caps.limits.maxVertexStreams = BGFX_CONFIG_MAX_VERTEX_STREAMS; + g_caps.limits.maxTextureSize = uint16_t(glGet(GL_MAX_TEXTURE_SIZE) ); + g_caps.limits.maxTextureLayers = uint16_t(bx::max(glGet(GL_MAX_ARRAY_TEXTURE_LAYERS), 1) ); + g_caps.limits.maxComputeBindings = computeSupport ? BGFX_MAX_COMPUTE_BINDINGS : 0; + g_caps.limits.maxVertexStreams = BGFX_CONFIG_MAX_VERTEX_STREAMS; if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) || BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES >= 30) @@ -6333,6 +6334,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) ); || (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) && s_extension[Extension::ARB_compute_shader].m_supported) || BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES >= 31) ; + const uint32_t maxComputeBindings = g_caps.limits.maxComputeBindings; uint32_t statsNumPrimsSubmitted[BX_COUNTOF(s_primInfo)] = {}; uint32_t statsNumPrimsRendered[BX_COUNTOF(s_primInfo)] = {}; @@ -6499,7 +6501,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) ); GL_CHECK(glUseProgram(program.m_id) ); GLbitfield barrier = 0; - for (uint32_t ii = 0; ii < BGFX_MAX_COMPUTE_BINDINGS; ++ii) + for (uint32_t ii = 0; ii < maxComputeBindings; ++ii) { const Binding& bind = renderBind.m_bind[ii]; if (kInvalidHandle != bind.m_idx) diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index e1e0992ef..a97f5cf74 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -977,8 +977,9 @@ VK_IMPORT_INSTANCE g_caps.vendorId = uint16_t(m_deviceProperties.vendorID); g_caps.deviceId = uint16_t(m_deviceProperties.deviceID); - g_caps.limits.maxTextureSize = m_deviceProperties.limits.maxImageDimension2D; - g_caps.limits.maxFBAttachments = uint8_t(bx::uint32_min(m_deviceProperties.limits.maxFragmentOutputAttachments, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) ); + g_caps.limits.maxTextureSize = m_deviceProperties.limits.maxImageDimension2D; + g_caps.limits.maxFBAttachments = uint8_t(bx::uint32_min(m_deviceProperties.limits.maxFragmentOutputAttachments, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) ); + g_caps.limits.maxComputeBindings = BGFX_MAX_COMPUTE_BINDINGS; { // VkFormatProperties fp; @@ -3694,6 +3695,8 @@ VK_DESTROY Rect viewScissorRect; viewScissorRect.clear(); + const uint32_t maxComputeBindings = g_caps.limits.maxComputeBindings; + uint32_t statsNumPrimsSubmitted[BX_COUNTOF(s_primInfo)] = {}; uint32_t statsNumPrimsRendered[BX_COUNTOF(s_primInfo)] = {}; uint32_t statsNumInstances[BX_COUNTOF(s_primInfo)] = {}; @@ -3878,7 +3881,7 @@ BX_UNUSED(currentSamplerStateIdx); // D3D12_GPU_DESCRIPTOR_HANDLE srvHandle[BGFX_MAX_COMPUTE_BINDINGS] = {}; // uint32_t samplerFlags[BGFX_MAX_COMPUTE_BINDINGS] = {}; // -// for (uint32_t ii = 0; ii < BGFX_MAX_COMPUTE_BINDINGS; ++ii) +// for (uint32_t ii = 0; ii < maxComputeBindings; ++ii) // { // const Binding& bind = renderBind.m_bind[ii]; // if (kInvalidHandle != bind.m_idx) @@ -3927,7 +3930,7 @@ BX_UNUSED(currentSamplerStateIdx); // } // } // -// uint16_t samplerStateIdx = getSamplerState(samplerFlags, BGFX_MAX_COMPUTE_BINDINGS, _render->m_colorPalette); +// uint16_t samplerStateIdx = getSamplerState(samplerFlags, maxComputeBindings, _render->m_colorPalette); // if (samplerStateIdx != currentSamplerStateIdx) // { // currentSamplerStateIdx = samplerStateIdx;