From b2513038f4b753ebeced40821c193978daa0492f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Sat, 31 Oct 2026 12:11:00 -0700 Subject: [PATCH] Fixed GL ASTC probe, VK/WebGPU uniform offsets, and emulated compressed texture uploads. Closes #4108. Closes #4109. (#4110) --- src/renderer_gl.cpp | 21 +++++++++----- src/renderer_mtl.cpp | 8 +++--- src/renderer_vk.cpp | 64 ++++++++++++++++++++++------------------- src/renderer_webgpu.cpp | 10 +++---- 4 files changed, 58 insertions(+), 45 deletions(-) diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index beadfffa6..f755bf04c 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -1594,7 +1594,7 @@ namespace bgfx { namespace gl ; GLsizei bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(_format) ); - GLsizei size = (_dim*_dim*bpp)/8; + GLsizei size = GLsizei(bimg::imageGetSize(NULL, _dim, _dim, 0, false, false, 1, bimg::TextureFormat::Enum(_format) ) ); void* data = NULL; if (bimg::isDepth(bimg::TextureFormat::Enum(_format) ) ) @@ -1621,8 +1621,7 @@ namespace bgfx { namespace gl for (uint32_t ii = 0, dim = _dim; ii < (_mipmaps ? 5u : 1u) && 0 == err; ++ii, dim >>= 1) { dim = bx::max(1, dim); - uint32_t block = bx::max(4, dim); - size = (block*block*bpp)/8; + size = GLsizei(bimg::imageGetSize(NULL, dim, dim, 0, false, false, 1, bimg::TextureFormat::Enum(_format) ) ); compressedTexImage(target, ii, internalFmt, dim, dim, 0, 0, size, data); err |= getGlError(); } @@ -1774,11 +1773,19 @@ namespace bgfx { namespace gl ; case TextureFormat::ASTC4x4: + case TextureFormat::ASTC5x4: case TextureFormat::ASTC5x5: + case TextureFormat::ASTC6x5: case TextureFormat::ASTC6x6: case TextureFormat::ASTC8x5: case TextureFormat::ASTC8x6: + case TextureFormat::ASTC8x8: case TextureFormat::ASTC10x5: + case TextureFormat::ASTC10x6: + case TextureFormat::ASTC10x8: + case TextureFormat::ASTC10x10: + case TextureFormat::ASTC12x10: + case TextureFormat::ASTC12x12: return emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_astc"); default: @@ -7008,11 +7015,11 @@ namespace bgfx { namespace gl imageDecodeToRgba8( temp , mip.m_data - , mip.m_width - , mip.m_height + , width + , height , mip.m_depth - , mip.m_width*4 - , mip.m_width*4*mip.m_height + , width*4 + , width*4*height , mip.m_format ); data = temp; diff --git a/src/renderer_mtl.cpp b/src/renderer_mtl.cpp index acd49533b..9f2afefae 100644 --- a/src/renderer_mtl.cpp +++ b/src/renderer_mtl.cpp @@ -4614,11 +4614,11 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames imageDecodeToBgra8( temp , mip.m_data - , mip.m_width - , mip.m_height + , width + , height , mip.m_depth - , mip.m_width*4 - , mip.m_width*4*mip.m_height + , width*4 + , width*4*height , mip.m_format ); data = temp; diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index 3364a0b75..ee9e1f37d 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -8186,16 +8186,18 @@ VK_DESTROY { if (convert) { - const uint32_t pitch = bx::strideAlign(bx::max(mip.m_width, 4) * bpp / 8, alignment); - const uint32_t slice = bx::strideAlign(bx::max(mip.m_height, 4) * pitch, alignment); - const uint32_t size = slice * mip.m_depth; + const uint32_t width = bx::max(1, m_width >> lod); + const uint32_t height = bx::max(1, m_height >> lod); + const uint32_t pitch = bx::strideAlign(width * bpp / 8, alignment); + const uint32_t slice = bx::strideAlign(height * pitch, alignment); + const uint32_t size = slice * mip.m_depth; uint8_t* temp = (uint8_t*)bx::alloc(g_allocator, size); imageDecodeToBgra8( temp , mip.m_data - , mip.m_width - , mip.m_height + , width + , height , mip.m_depth , pitch , slice @@ -8203,8 +8205,8 @@ VK_DESTROY ); imageInfos[kk].data = temp; - imageInfos[kk].width = mip.m_width; - imageInfos[kk].height = mip.m_height; + imageInfos[kk].width = width; + imageInfos[kk].height = height; imageInfos[kk].depth = mip.m_depth; imageInfos[kk].pitch = pitch; imageInfos[kk].slice = slice; @@ -11650,6 +11652,8 @@ VK_DESTROY VkDescriptorSet currentDescriptorSet = VK_NULL_HANDLE; uint32_t currentBindHash = 0; uint32_t descriptorSetCount = 0; + ChunkedScratchBufferOffset currentSbo = { .buffer = VK_NULL_HANDLE, .offsets = { 0, 0 } }; + uint32_t currentNumOffsets = 0; struct PipelineState { @@ -12085,18 +12089,18 @@ VK_DESTROY if (VK_NULL_HANDLE != program.m_descriptorSetLayout) { - ChunkedScratchBufferOffset sbo; - const uint32_t vsSize = program.m_vsh->m_size; - uint32_t numOffsets = 0; if (constantsChanged || hasPredefined) { + currentSbo.buffer = VK_NULL_HANDLE; + currentNumOffsets = 0; + if (vsSize > 0) { - uniformScratchBuffer.write(sbo, m_vsScratch, vsSize); - numOffsets = 1; + uniformScratchBuffer.write(currentSbo, m_vsScratch, vsSize); + currentNumOffsets = 1; } } @@ -12105,7 +12109,7 @@ VK_DESTROY hash.add(program.m_descriptorSetLayout); hash.add(program.m_msaaMask); hash.add(bindIdx); - hash.add(sbo.buffer); + hash.add(currentSbo.buffer); hash.add(vsSize); hash.add(0); @@ -12126,7 +12130,7 @@ VK_DESTROY VkDescriptorSet descriptorSet = getDescriptorSet( program , renderBind - , sbo.buffer + , currentSbo.buffer , _render->m_colorPalette ); @@ -12148,8 +12152,8 @@ VK_DESTROY , 0 , 1 , ¤tDescriptorSet - , numOffsets - , sbo.offsets + , currentNumOffsets + , currentSbo.offsets ); } @@ -12446,19 +12450,21 @@ VK_DESTROY if (VK_NULL_HANDLE != program.m_descriptorSetLayout) { - ChunkedScratchBufferOffset sbo; - const uint32_t vsSize = program.m_vsh->m_size; const uint32_t fsSize = NULL != program.m_fsh ? program.m_fsh->m_size : 0; - uint32_t numOffsets = 0; - if (true - && (constantsChanged || hasPredefined) - && (0 < vsSize || 0 < fsSize) - ) + if (constantsChanged + || hasPredefined) { - uniformScratchBuffer.write(sbo, m_vsScratch, vsSize, m_fsScratch, fsSize); - numOffsets = (0 < vsSize) + (0 < fsSize); + currentSbo.buffer = VK_NULL_HANDLE; + currentNumOffsets = 0; + + if (0 < vsSize + || 0 < fsSize) + { + uniformScratchBuffer.write(currentSbo, m_vsScratch, vsSize, m_fsScratch, fsSize); + currentNumOffsets = (0 < vsSize) + (0 < fsSize); + } } bx::HashMurmur2A hash; @@ -12466,7 +12472,7 @@ VK_DESTROY hash.add(program.m_descriptorSetLayout); hash.add(program.m_msaaMask); hash.add(bindIdx); - hash.add(sbo.buffer); + hash.add(currentSbo.buffer); hash.add(vsSize); hash.add(fsSize); @@ -12487,7 +12493,7 @@ VK_DESTROY VkDescriptorSet descriptorSet = getDescriptorSet( program , renderBind - , sbo.buffer + , currentSbo.buffer , _render->m_colorPalette ); @@ -12509,8 +12515,8 @@ VK_DESTROY , 0 , 1 , ¤tDescriptorSet - , numOffsets - , sbo.offsets + , currentNumOffsets + , currentSbo.offsets ); } diff --git a/src/renderer_webgpu.cpp b/src/renderer_webgpu.cpp index d5519e393..6ddfa1c70 100644 --- a/src/renderer_webgpu.cpp +++ b/src/renderer_webgpu.cpp @@ -7693,6 +7693,7 @@ WGPU_IMPORT ProgramHandle currentProgram = BGFX_INVALID_HANDLE; bool hasPredefined = false; + ChunkedScratchBufferOffset currentSbo = { .buffer = NULL, .offsets = { 0, 0 } }; SortKey key; uint16_t view = UINT16_MAX; const View* renderView = &_render->view(0); @@ -8133,14 +8134,13 @@ WGPU_IMPORT } } - ChunkedScratchBufferOffset sbo; const uint32_t vsSize = program.m_vsh->m_size; if (constantsChanged || hasPredefined) { viewState.setPredefined<4>(this, view, *renderView, program, _render, compute); - m_uniformScratchBuffer.write(sbo, m_vsScratch, vsSize); + m_uniformScratchBuffer.write(currentSbo, m_vsScratch, vsSize); } if (programChanged) @@ -8153,7 +8153,7 @@ WGPU_IMPORT bx::HashMurmur3 murmur; murmur.begin(0x434f4d50); murmur.add(renderBind.m_bind, sizeof(renderBind.m_bind) ); - murmur.add(sbo.buffer); + murmur.add(currentSbo.buffer); murmur.add(vsSize); murmur.add(uintptr_t(bindGroupLayout) ); const uint32_t bindHash = murmur.end(); @@ -8161,12 +8161,12 @@ WGPU_IMPORT BindGroupMap::iterator it = m_bindGroupMap.find(bindHash); if (it == m_bindGroupMap.end() ) { - const BindGroup bindGroup = createBindGroup(bindGroupLayout, program, renderBind, sbo, true); + const BindGroup bindGroup = createBindGroup(bindGroupLayout, program, renderBind, currentSbo, true); it = m_bindGroupMap.insert(stl::make_pair(bindHash, bindGroup) ).first; } const BindGroup* bindGroupCached = &it->second; - WGPU_CHECK(wgpuComputePassEncoderSetBindGroup(computePassEncoder, 0, bindGroupCached->bindGroup, bindGroupCached->numOffsets, sbo.offsets) ); + WGPU_CHECK(wgpuComputePassEncoderSetBindGroup(computePassEncoder, 0, bindGroupCached->bindGroup, bindGroupCached->numOffsets, currentSbo.offsets) ); if (isValid(compute.m_indirectBuffer) ) {