Skip to content

Commit cbed9bd

Browse files
flibitijibiboslouken
authored andcommitted
gpu: D3D12 uploads should also factor in block size for height, not just width.
It turns out the reason this function was having so many overread issues was because our row copies were wrong - for compressed images we also need to reduce the row count based on the block size, similar to what we already do for pitch calculation - these copies are byte copies, not pixel copies! (cherry picked from commit f472f93)
1 parent fd345ae commit cbed9bd

File tree

1 file changed

+14
-16
lines changed

1 file changed

+14
-16
lines changed

src/gpu/d3d12/SDL_gpu_d3d12.c

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5922,7 +5922,10 @@ static void D3D12_UploadToTexture(
59225922
D3D12_TEXTURE_COPY_LOCATION sourceLocation;
59235923
D3D12_TEXTURE_COPY_LOCATION destinationLocation;
59245924
Uint32 pixelsPerRow = source->pixels_per_row;
5925+
Uint32 blockWidth;
5926+
Uint32 blockSize;
59255927
Uint32 rowPitch;
5928+
Uint32 blockHeight;
59265929
Uint32 alignedRowPitch;
59275930
Uint32 rowsPerSlice = source->rows_per_layer;
59285931
Uint32 bytesPerSlice;
@@ -5956,15 +5959,18 @@ static void D3D12_UploadToTexture(
59565959
pixelsPerRow = destination->w;
59575960
}
59585961

5959-
rowPitch = BytesPerRow(pixelsPerRow, textureContainer->header.info.format);
5960-
59615962
if (rowsPerSlice == 0) {
59625963
rowsPerSlice = destination->h;
59635964
}
59645965

5966+
blockWidth = Texture_GetBlockWidth(textureContainer->header.info.format);
5967+
blockSize = SDL_GPUTextureFormatTexelBlockSize(textureContainer->header.info.format);
5968+
rowPitch = (pixelsPerRow + (blockWidth - 1)) / blockWidth * blockSize;
5969+
blockHeight = (rowsPerSlice + (blockWidth - 1)) / blockWidth;
5970+
59655971
bytesPerSlice = rowsPerSlice * rowPitch;
59665972

5967-
alignedRowPitch = BytesPerRow(destination->w, textureContainer->header.info.format);
5973+
alignedRowPitch = (destination->w + (blockWidth - 1)) / blockWidth * blockSize;
59685974
alignedRowPitch = D3D12_INTERNAL_Align(alignedRowPitch, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
59695975
needsRealignment = rowsPerSlice != destination->h || rowPitch != alignedRowPitch;
59705976
needsPlacementCopy = source->offset % D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT != 0;
@@ -5983,7 +5989,7 @@ static void D3D12_UploadToTexture(
59835989
temporaryBuffer = D3D12_INTERNAL_CreateBuffer(
59845990
d3d12CommandBuffer->renderer,
59855991
0,
5986-
alignedRowPitch * destination->h * destination->d,
5992+
alignedRowPitch * blockHeight * destination->d,
59875993
D3D12_BUFFER_TYPE_UPLOAD,
59885994
NULL);
59895995

@@ -5994,21 +6000,13 @@ static void D3D12_UploadToTexture(
59946000
sourceLocation.pResource = temporaryBuffer->handle;
59956001

59966002
for (Uint32 sliceIndex = 0; sliceIndex < destination->d; sliceIndex += 1) {
5997-
// copy row count minus one to avoid overread
5998-
for (Uint32 rowIndex = 0; rowIndex < destination->h - 1; rowIndex += 1) {
5999-
6003+
for (Uint32 rowIndex = 0; rowIndex < blockHeight; rowIndex += 1) {
60006004
SDL_memcpy(
60016005
temporaryBuffer->mapPointer + (sliceIndex * alignedBytesPerSlice) + (rowIndex * alignedRowPitch),
60026006
transferBufferContainer->activeBuffer->mapPointer + source->offset + (sliceIndex * bytesPerSlice) + (rowIndex * rowPitch),
6003-
alignedRowPitch);
6007+
rowPitch);
60046008

60056009
}
6006-
Uint32 offset = source->offset + (sliceIndex * bytesPerSlice) + ((destination->h - 1) * rowPitch);
6007-
6008-
SDL_memcpy(
6009-
temporaryBuffer->mapPointer + (sliceIndex * alignedBytesPerSlice) + ((destination->h - 1) * alignedRowPitch),
6010-
transferBufferContainer->activeBuffer->mapPointer + offset,
6011-
SDL_min(alignedRowPitch, transferBufferContainer->size - offset));
60126010

60136011
sourceLocation.PlacedFootprint.Footprint.Width = destination->w;
60146012
sourceLocation.PlacedFootprint.Footprint.Height = destination->h;
@@ -6037,7 +6035,7 @@ static void D3D12_UploadToTexture(
60376035
temporaryBuffer = D3D12_INTERNAL_CreateBuffer(
60386036
d3d12CommandBuffer->renderer,
60396037
0,
6040-
alignedRowPitch * destination->h * destination->d,
6038+
alignedRowPitch * blockHeight * destination->d,
60416039
D3D12_BUFFER_TYPE_UPLOAD,
60426040
NULL);
60436041

@@ -6048,7 +6046,7 @@ static void D3D12_UploadToTexture(
60486046
SDL_memcpy(
60496047
temporaryBuffer->mapPointer,
60506048
transferBufferContainer->activeBuffer->mapPointer + source->offset,
6051-
alignedRowPitch * destination->h * destination->d);
6049+
alignedRowPitch * blockHeight * destination->d);
60526050

60536051
sourceLocation.pResource = temporaryBuffer->handle;
60546052
sourceLocation.PlacedFootprint.Offset = 0;

0 commit comments

Comments
 (0)