Skip to content

Commit

Permalink
[WebGPU] 2D texture copy fails in Queue::writeTexture when sourceByte…
Browse files Browse the repository at this point in the history
…sPerRow is not a multiple of 16 bytes

https://bugs.webkit.org/show_bug.cgi?id=272209
<radar://124475311>

Reviewed by Tadeu Zagallo.

Ensure compressed texture copies are a multiple of
their block size.

* Source/WebGPU/WebGPU/Queue.mm:
(WebGPU::Queue::writeTexture):

Canonical link: https://commits.webkit.org/277135@main
  • Loading branch information
mwyrzykowski committed Apr 5, 2024
1 parent 75713db commit 0713e3e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
27 changes: 23 additions & 4 deletions Source/WebGPU/WebGPU/Queue.mm
Original file line number Diff line number Diff line change
Expand Up @@ -590,10 +590,29 @@
bytesPerImage = 0;
}

switch (textureDimension) {
case WGPUTextureDimension_1D:
if (!widthForMetal)
return;
break;
case WGPUTextureDimension_2D:
if (!widthForMetal || !heightForMetal)
return;
break;
case WGPUTextureDimension_3D:
if (!widthForMetal || !heightForMetal || !depthForMetal)
return;
break;
case WGPUTextureDimension_Force32:
return;
}

Vector<uint8_t> newData;
const auto newBytesPerRow = blockSize * ((widthForMetal / blockWidth) + ((widthForMetal % blockWidth) ? 1 : 0));
auto dataLayoutOffset = dataLayout.offset;
if (isCompressed && newBytesPerRow != bytesPerRow && (widthForMetal == logicalSize.width && heightForMetal == logicalSize.height)) {
const bool widthMismatch = newBytesPerRow != bytesPerRow && widthForMetal == logicalSize.width && heightForMetal == logicalSize.height;
const bool multipleOfBlockSize = bytesPerRow % blockSize;
if (isCompressed && (widthMismatch || multipleOfBlockSize)) {

auto maxY = std::max<size_t>(blockHeight, heightForMetal) / blockHeight;
auto newBytesPerImage = newBytesPerRow * std::max<size_t>(blockHeight, logicalSize.height) / blockHeight;
Expand Down Expand Up @@ -646,7 +665,7 @@
{
switch (textureDimension) {
case WGPUTextureDimension_1D: {
if (!size.width)
if (!widthForMetal)
return;

auto region = MTLRegionMake1D(destination.origin.x, widthForMetal);
Expand All @@ -664,7 +683,7 @@
break;
}
case WGPUTextureDimension_2D: {
if (!size.width || !size.height)
if (!widthForMetal || !heightForMetal)
return;

auto region = MTLRegionMake2D(destination.origin.x, destination.origin.y, widthForMetal, heightForMetal);
Expand All @@ -682,7 +701,7 @@
break;
}
case WGPUTextureDimension_3D: {
if (!size.width || !size.height || !size.depthOrArrayLayers)
if (!widthForMetal || !heightForMetal || !depthForMetal)
return;

auto region = MTLRegionMake3D(destination.origin.x, destination.origin.y, destination.origin.z, widthForMetal, heightForMetal, depthForMetal);
Expand Down
3 changes: 3 additions & 0 deletions Source/WebGPU/WebGPU/ShaderModule.mm
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,9 @@ static void populateStageInMap(const WGSL::Type& type, ShaderModule::VertexStage

const ShaderModule::VertexStageIn* ShaderModule::stageInTypesForEntryPoint(const String& entryPoint) const
{
if (!entryPoint.length())
return nullptr;

if (auto it = m_stageInTypesForEntryPoint.find(entryPoint); it != m_stageInTypesForEntryPoint.end())
return &it->value;

Expand Down

0 comments on commit 0713e3e

Please sign in to comment.