Skip to content

Commit 680c043

Browse files
authored
Merge pull request #1065 from floooh/issue1063-d3d11-tex3d-update
Fix sg_update_image() for 3D textures.
2 parents c970b0b + 18c9c06 commit 680c043

File tree

3 files changed

+39
-13
lines changed

3 files changed

+39
-13
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
## Updates
22

3+
### 19-Jun-2024
4+
5+
Bugfix in the sokol_gfx.h D3D11 backend: calling `sg_update_image()` for a
6+
small-ish 3D texture didn't take the 'depth pitch' into account which then
7+
caused invalid texture content. This happened at a specific size cutoff which
8+
is CPU specific (on my laptop with integrated Intel GPU only for textures
9+
smaller than 32x32xN).
10+
11+
Related ticket: https://github.com/floooh/sokol/issues/1066
12+
...and PR: https://github.com/floooh/sokol/pull/1065
13+
14+
I also wrote a new sample for investigating the issue and to protect from
15+
future regressions: https://floooh.github.io/sokol-html5/dyntex3d-sapp.html
16+
317
### 01-Jun-2024
418

519
sokol_imgui.h is now officially supported in the [sokol-zig bindings](https://github.com/floooh/sokol-zig).

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
# Sokol
88

9-
[**See what's new**](https://github.com/floooh/sokol/blob/master/CHANGELOG.md) (**09-May-2024**: **BREAKING CHANGES** 'storage buffer support' in sokol_gfx.h
9+
[**See what's new**](https://github.com/floooh/sokol/blob/master/CHANGELOG.md) (**19-Jun-2024**: bugfix in the sokol_gfx.h d3d11 backend when updating 3d textures
1010

1111
[![Build](/../../actions/workflows/main.yml/badge.svg)](/../../actions/workflows/main.yml) [![Bindings](/../../actions/workflows/gen_bindings.yml/badge.svg)](/../../actions/workflows/gen_bindings.yml) [![build](https://github.com/floooh/sokol-zig/actions/workflows/main.yml/badge.svg)](https://github.com/floooh/sokol-zig/actions/workflows/main.yml) [![build](https://github.com/floooh/sokol-nim/actions/workflows/main.yml/badge.svg)](https://github.com/floooh/sokol-nim/actions/workflows/main.yml) [![Odin](https://github.com/floooh/sokol-odin/actions/workflows/main.yml/badge.svg)](https://github.com/floooh/sokol-odin/actions/workflows/main.yml)[![Rust](https://github.com/floooh/sokol-rust/actions/workflows/main.yml/badge.svg)](https://github.com/floooh/sokol-rust/actions/workflows/main.yml)[![Dlang](https://github.com/kassane/sokol-d/actions/workflows/build.yml/badge.svg)](https://github.com/kassane/sokol-d/actions/workflows/build.yml)
1212

sokol_gfx.h

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11437,12 +11437,15 @@ _SOKOL_PRIVATE void _sg_d3d11_append_buffer(_sg_buffer_t* buf, const sg_range* d
1143711437
}
1143811438
}
1143911439

11440+
// see: https://learn.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-resources-subresources
11441+
// also see: https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-d3d11calcsubresource
1144011442
_SOKOL_PRIVATE void _sg_d3d11_update_image(_sg_image_t* img, const sg_image_data* data) {
1144111443
SOKOL_ASSERT(img && data);
1144211444
SOKOL_ASSERT(_sg.d3d11.ctx);
1144311445
SOKOL_ASSERT(img->d3d11.res);
1144411446
const int num_faces = (img->cmn.type == SG_IMAGETYPE_CUBE) ? 6:1;
1144511447
const int num_slices = (img->cmn.type == SG_IMAGETYPE_ARRAY) ? img->cmn.num_slices:1;
11448+
const int num_depth_slices = (img->cmn.type == SG_IMAGETYPE_3D) ? img->cmn.num_slices:1;
1144611449
UINT subres_index = 0;
1144711450
HRESULT hr;
1144811451
D3D11_MAPPED_SUBRESOURCE d3d11_msr;
@@ -11452,26 +11455,35 @@ _SOKOL_PRIVATE void _sg_d3d11_update_image(_sg_image_t* img, const sg_image_data
1145211455
SOKOL_ASSERT(subres_index < (SG_MAX_MIPMAPS * SG_MAX_TEXTUREARRAY_LAYERS));
1145311456
const int mip_width = _sg_miplevel_dim(img->cmn.width, mip_index);
1145411457
const int mip_height = _sg_miplevel_dim(img->cmn.height, mip_index);
11455-
const int src_pitch = _sg_row_pitch(img->cmn.pixel_format, mip_width, 1);
11458+
const int src_row_pitch = _sg_row_pitch(img->cmn.pixel_format, mip_width, 1);
11459+
const int src_depth_pitch = _sg_surface_pitch(img->cmn.pixel_format, mip_width, mip_height, 1);
1145611460
const sg_range* subimg_data = &(data->subimage[face_index][mip_index]);
1145711461
const size_t slice_size = subimg_data->size / (size_t)num_slices;
11462+
SOKOL_ASSERT(slice_size == (size_t)(src_depth_pitch * num_depth_slices));
1145811463
const size_t slice_offset = slice_size * (size_t)slice_index;
1145911464
const uint8_t* slice_ptr = ((const uint8_t*)subimg_data->ptr) + slice_offset;
1146011465
hr = _sg_d3d11_Map(_sg.d3d11.ctx, img->d3d11.res, subres_index, D3D11_MAP_WRITE_DISCARD, 0, &d3d11_msr);
1146111466
_sg_stats_add(d3d11.num_map, 1);
1146211467
if (SUCCEEDED(hr)) {
11463-
// FIXME: need to handle difference in depth-pitch for 3D textures as well!
11464-
if (src_pitch == (int)d3d11_msr.RowPitch) {
11465-
memcpy(d3d11_msr.pData, slice_ptr, slice_size);
11466-
} else {
11467-
SOKOL_ASSERT(src_pitch < (int)d3d11_msr.RowPitch);
11468-
const uint8_t* src_ptr = slice_ptr;
11469-
uint8_t* dst_ptr = (uint8_t*) d3d11_msr.pData;
11470-
for (int row_index = 0; row_index < mip_height; row_index++) {
11471-
memcpy(dst_ptr, src_ptr, (size_t)src_pitch);
11472-
src_ptr += src_pitch;
11473-
dst_ptr += d3d11_msr.RowPitch;
11468+
const uint8_t* src_ptr = slice_ptr;
11469+
uint8_t* dst_ptr = (uint8_t*)d3d11_msr.pData;
11470+
for (int depth_index = 0; depth_index < num_depth_slices; depth_index++) {
11471+
if (src_row_pitch == (int)d3d11_msr.RowPitch) {
11472+
const size_t copy_size = slice_size / (size_t)num_depth_slices;
11473+
SOKOL_ASSERT((copy_size * (size_t)num_depth_slices) == slice_size);
11474+
memcpy(dst_ptr, src_ptr, copy_size);
11475+
} else {
11476+
SOKOL_ASSERT(src_row_pitch < (int)d3d11_msr.RowPitch);
11477+
const uint8_t* src_row_ptr = src_ptr;
11478+
uint8_t* dst_row_ptr = dst_ptr;
11479+
for (int row_index = 0; row_index < mip_height; row_index++) {
11480+
memcpy(dst_row_ptr, src_row_ptr, (size_t)src_row_pitch);
11481+
src_row_ptr += src_row_pitch;
11482+
dst_row_ptr += d3d11_msr.RowPitch;
11483+
}
1147411484
}
11485+
src_ptr += src_depth_pitch;
11486+
dst_ptr += d3d11_msr.DepthPitch;
1147511487
}
1147611488
_sg_d3d11_Unmap(_sg.d3d11.ctx, img->d3d11.res, subres_index);
1147711489
_sg_stats_add(d3d11.num_unmap, 1);

0 commit comments

Comments
 (0)