mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-11 14:41:50 +00:00
Implement External Texture Crop Functionality
Adds to the External Texture shader transform to allow cropping. Tests included. Bug: chromium:1316671 Change-Id: Id0ec9acac22a0968ba6847d6ead9cf5084eaca88 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/113281 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Ben Clayton <bclayton@google.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Dawn LUCI CQ
parent
0be08d8b88
commit
183df9d24e
@@ -209,25 +209,64 @@ MaybeError ExternalTextureBase::Initialize(DeviceBase* device,
|
||||
const float* dstFn = descriptor->dstTransferFunctionParameters;
|
||||
std::copy(dstFn, dstFn + 7, params.gammaEncodingParams.begin());
|
||||
|
||||
// These scale factors perform part of the cropping operation. These default to 1, so we can use
|
||||
// them directly for performing rotation in the matrix later.
|
||||
float xScale = descriptor->visibleRect.width;
|
||||
float yScale = descriptor->visibleRect.height;
|
||||
|
||||
// In the shader, we must convert UV coordinates from the {0, 1} space to the {-0.5, 0.5} space
|
||||
// to do rotation. Ideally, we want to combine the rotate, flip-Y operations in a single matrix
|
||||
// operation - but this is complicated because scaling most easily occurs in the {0, 1} space.
|
||||
// We can work around this and perform scaling in the {-0.5, 0.5} space by multiplying the
|
||||
// needed conversion constant "+ 0.5" by the scale factor. We then can do this all within a
|
||||
// single matrix operation by calculating and adding this value to the offset specified in the
|
||||
// matrix. For reference, this is the entire operation needed is:
|
||||
//
|
||||
// newCoords = vec3<f32>((coord - 0.5f), 1.0f) * coordTransformationMatrix) + (scaleFactor *
|
||||
// 0.5)
|
||||
//
|
||||
// Because we combine the ending (scaleFactor * 0.5) into the crop offset within the matrix, the
|
||||
// shader is actually:
|
||||
//
|
||||
// newCoords = vec3<f32>((coord - 0.5f), 1.0f) * params.coordTransformationMatrix;
|
||||
//
|
||||
// TODO(dawn:1614): Incorporate the "- 0.5f" into the matrix.
|
||||
float xOffset = descriptor->visibleRect.x + 0.5f * xScale;
|
||||
float yOffset = descriptor->visibleRect.y + 0.5f * yScale;
|
||||
|
||||
// Flip-Y can be done by simply negating the scaling factor in the y-plane. The position of the
|
||||
// y-plane scaling factor in the matrix can be different depending on the rotation.
|
||||
float flipY = 1;
|
||||
if (descriptor->flipY) {
|
||||
flipY = -1;
|
||||
}
|
||||
|
||||
// We can perform the flip-Y operation by multiplying the y-component portion of the matrix by
|
||||
// -1.
|
||||
// This block creates a 2x3 matrix which when multiplied by UV coordinates in a shader performs
|
||||
// rotation, flip-Y and cropping operations.
|
||||
switch (descriptor->rotation) {
|
||||
case wgpu::ExternalTextureRotation::Rotate0Degrees:
|
||||
params.coordTransformMatrix = {1.0, 0.0, 0.0, 1.0f * flipY};
|
||||
params.coordTransformMatrix = {xScale, 0.0, //
|
||||
xOffset, 0.0, //
|
||||
0.0, flipY * yScale, //
|
||||
yOffset, 0.0};
|
||||
break;
|
||||
case wgpu::ExternalTextureRotation::Rotate90Degrees:
|
||||
params.coordTransformMatrix = {0.0, 1.0f * flipY, -1.0, 0.0};
|
||||
params.coordTransformMatrix = {0.0, flipY * yScale, //
|
||||
xOffset, 0.0, //
|
||||
-xScale, 0.0, //
|
||||
yOffset, 0.0};
|
||||
break;
|
||||
case wgpu::ExternalTextureRotation::Rotate180Degrees:
|
||||
params.coordTransformMatrix = {-1.0, 0.0, 0.0, -1.0f * flipY};
|
||||
params.coordTransformMatrix = {-xScale, 0.0, //
|
||||
xOffset, 0.0, //
|
||||
0.0, flipY * -yScale, //
|
||||
yOffset, 0.0};
|
||||
break;
|
||||
case wgpu::ExternalTextureRotation::Rotate270Degrees:
|
||||
params.coordTransformMatrix = {0.0, -1.0f * flipY, 1.0, 0.0};
|
||||
params.coordTransformMatrix = {0.0, flipY * -yScale, //
|
||||
xOffset, 0.0, //
|
||||
xScale, 0.0, //
|
||||
yOffset, 0.0};
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ struct ExternalTextureParams {
|
||||
std::array<float, 8> gammaDecodingParams = {};
|
||||
std::array<float, 8> gammaEncodingParams = {};
|
||||
std::array<float, 12> gamutConversionMatrix = {};
|
||||
std::array<float, 4> coordTransformMatrix = {};
|
||||
std::array<float, 8> coordTransformMatrix = {};
|
||||
};
|
||||
|
||||
MaybeError ValidateExternalTextureDescriptor(const DeviceBase* device,
|
||||
|
||||
@@ -625,6 +625,341 @@ TEST_P(ExternalTextureTests, RotateAndOrFlipMultiplanar) {
|
||||
}
|
||||
}
|
||||
|
||||
// This test draws a 2x2 multi-colored square surrounded by a 1px black border. We test the external
|
||||
// texture crop functionality by cropping to specific ranges inside the texture.
|
||||
TEST_P(ExternalTextureTests, CropSinglePlane) {
|
||||
// TODO(crbug.com/tint/1774): Tint has an issue compiling shaders that use external textures on
|
||||
// OpenGL/OpenGLES.
|
||||
DAWN_SUPPRESS_TEST_IF(IsOpenGL() || IsOpenGLES());
|
||||
|
||||
const wgpu::ShaderModule sourceTextureFsModule = utils::CreateShaderModule(device, R"(
|
||||
@fragment fn main(@builtin(position) FragCoord : vec4<f32>)
|
||||
-> @location(0) vec4<f32> {
|
||||
if(FragCoord.x >= 1.0 && FragCoord.x < 3.0 && FragCoord.y >= 1.0 && FragCoord.y < 3.0) {
|
||||
if(FragCoord.y < 2.0 && FragCoord.x < 2.0) {
|
||||
return vec4<f32>(0.0, 1.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
if(FragCoord.y < 2.0 && FragCoord.x >= 2.0) {
|
||||
return vec4<f32>(1.0, 1.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
if(FragCoord.y >= 2.0 && FragCoord.x < 2.0) {
|
||||
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
if(FragCoord.y >= 2.0 && FragCoord.x >= 2.0) {
|
||||
return vec4<f32>(0.0, 0.0, 1.0, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
return vec4<f32>(0.0, 0.0, 0.0, 1.0);
|
||||
})");
|
||||
|
||||
wgpu::Texture sourceTexture =
|
||||
Create2DTexture(device, kWidth, kHeight, kFormat,
|
||||
wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment);
|
||||
|
||||
RenderToSourceTexture(sourceTextureFsModule, sourceTexture);
|
||||
|
||||
wgpu::Texture renderTexture =
|
||||
Create2DTexture(device, kWidth, kHeight, kFormat,
|
||||
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment);
|
||||
|
||||
struct CropExpectation {
|
||||
wgpu::ExternalTextureVisibleRect visibleRect;
|
||||
wgpu::ExternalTextureRotation rotation;
|
||||
utils::RGBA8 upperLeftColor;
|
||||
utils::RGBA8 upperRightColor;
|
||||
utils::RGBA8 lowerLeftColor;
|
||||
utils::RGBA8 lowerRightColor;
|
||||
};
|
||||
|
||||
std::array<CropExpectation, 9> expectations = {{
|
||||
{{0.0, 0.0, 1.0, 1.0},
|
||||
wgpu::ExternalTextureRotation::Rotate0Degrees,
|
||||
utils::RGBA8::kBlack,
|
||||
utils::RGBA8::kBlack,
|
||||
utils::RGBA8::kBlack,
|
||||
utils::RGBA8::kBlack},
|
||||
{{0.25, 0.25, 0.25, 0.25},
|
||||
wgpu::ExternalTextureRotation::Rotate0Degrees,
|
||||
utils::RGBA8::kGreen,
|
||||
utils::RGBA8::kGreen,
|
||||
utils::RGBA8::kGreen,
|
||||
utils::RGBA8::kGreen},
|
||||
{{0.5, 0.25, 0.25, 0.25},
|
||||
wgpu::ExternalTextureRotation::Rotate0Degrees,
|
||||
utils::RGBA8::kWhite,
|
||||
utils::RGBA8::kWhite,
|
||||
utils::RGBA8::kWhite,
|
||||
utils::RGBA8::kWhite},
|
||||
{{0.25, 0.5, 0.25, 0.25},
|
||||
wgpu::ExternalTextureRotation::Rotate0Degrees,
|
||||
utils::RGBA8::kRed,
|
||||
utils::RGBA8::kRed,
|
||||
utils::RGBA8::kRed,
|
||||
utils::RGBA8::kRed},
|
||||
{{0.5, 0.5, 0.25, 0.25},
|
||||
wgpu::ExternalTextureRotation::Rotate0Degrees,
|
||||
utils::RGBA8::kBlue,
|
||||
utils::RGBA8::kBlue,
|
||||
utils::RGBA8::kBlue,
|
||||
utils::RGBA8::kBlue},
|
||||
{{0.25, 0.25, 0.5, 0.5},
|
||||
wgpu::ExternalTextureRotation::Rotate0Degrees,
|
||||
utils::RGBA8::kGreen,
|
||||
utils::RGBA8::kWhite,
|
||||
utils::RGBA8::kRed,
|
||||
utils::RGBA8::kBlue},
|
||||
{{0.25, 0.25, 0.5, 0.5},
|
||||
wgpu::ExternalTextureRotation::Rotate90Degrees,
|
||||
utils::RGBA8::kRed,
|
||||
utils::RGBA8::kGreen,
|
||||
utils::RGBA8::kBlue,
|
||||
utils::RGBA8::kWhite},
|
||||
{{0.25, 0.25, 0.5, 0.5},
|
||||
wgpu::ExternalTextureRotation::Rotate180Degrees,
|
||||
utils::RGBA8::kBlue,
|
||||
utils::RGBA8::kRed,
|
||||
utils::RGBA8::kWhite,
|
||||
utils::RGBA8::kGreen},
|
||||
{{0.25, 0.25, 0.5, 0.5},
|
||||
wgpu::ExternalTextureRotation::Rotate270Degrees,
|
||||
utils::RGBA8::kWhite,
|
||||
utils::RGBA8::kBlue,
|
||||
utils::RGBA8::kGreen,
|
||||
utils::RGBA8::kRed},
|
||||
}};
|
||||
|
||||
for (const CropExpectation& exp : expectations) {
|
||||
// Pipeline Creation
|
||||
utils::ComboRenderPipelineDescriptor descriptor;
|
||||
descriptor.vertex.module = vsModule;
|
||||
descriptor.cFragment.module = fsSampleExternalTextureModule;
|
||||
descriptor.cTargets[0].format = kFormat;
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
||||
// Create an ExternalTextureDescriptor from the texture view
|
||||
wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor();
|
||||
externalDesc.plane0 = sourceTexture.CreateView();
|
||||
externalDesc.visibleRect = exp.visibleRect;
|
||||
externalDesc.rotation = exp.rotation;
|
||||
|
||||
// Import the external texture
|
||||
wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(&externalDesc);
|
||||
|
||||
// Create a sampler and bind group
|
||||
wgpu::Sampler sampler = device.CreateSampler();
|
||||
|
||||
wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
|
||||
{{0, sampler}, {1, externalTexture}});
|
||||
|
||||
// Run the shader, which should sample from the external texture and draw a triangle into
|
||||
// the upper left corner of the render texture.
|
||||
wgpu::TextureView renderView = renderTexture.CreateView();
|
||||
utils::ComboRenderPassDescriptor renderPass({renderView}, nullptr);
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
|
||||
{
|
||||
pass.SetPipeline(pipeline);
|
||||
pass.SetBindGroup(0, bindGroup);
|
||||
pass.Draw(6);
|
||||
pass.End();
|
||||
}
|
||||
|
||||
wgpu::CommandBuffer commands = encoder.Finish();
|
||||
queue.Submit(1, &commands);
|
||||
|
||||
EXPECT_PIXEL_RGBA8_EQ(exp.upperLeftColor, renderTexture, 0, 0);
|
||||
EXPECT_PIXEL_RGBA8_EQ(exp.upperRightColor, renderTexture, 3, 0);
|
||||
EXPECT_PIXEL_RGBA8_EQ(exp.lowerLeftColor, renderTexture, 0, 3);
|
||||
EXPECT_PIXEL_RGBA8_EQ(exp.lowerRightColor, renderTexture, 3, 3);
|
||||
}
|
||||
}
|
||||
|
||||
// This test draws a 2x2 multi-colored square surrounded by a 1px black border. We test the external
|
||||
// texture crop functionality by cropping to specific ranges inside the texture.
|
||||
TEST_P(ExternalTextureTests, CropMultiplanar) {
|
||||
// TODO(crbug.com/tint/1774): Tint has an issue compiling shaders that use external textures on
|
||||
// OpenGL/OpenGLES.
|
||||
DAWN_SUPPRESS_TEST_IF(IsOpenGL() || IsOpenGLES());
|
||||
|
||||
const wgpu::ShaderModule sourceTexturePlane0FsModule = utils::CreateShaderModule(device, R"(
|
||||
@fragment fn main(@builtin(position) FragCoord : vec4<f32>)
|
||||
-> @location(0) vec4<f32> {
|
||||
if(FragCoord.x >= 1.0 && FragCoord.x < 3.0 && FragCoord.y >= 1.0 && FragCoord.y < 3.0) {
|
||||
if(FragCoord.y < 2.0 && FragCoord.x < 2.0) {
|
||||
return vec4<f32>(0.7152, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
if(FragCoord.y < 2.0 && FragCoord.x >= 2.0) {
|
||||
return vec4<f32>(1.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
if(FragCoord.y >= 2.0 && FragCoord.x < 2.0) {
|
||||
return vec4<f32>(0.2126, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
if(FragCoord.y >= 2.0 && FragCoord.x >= 2.0) {
|
||||
return vec4<f32>(0.0722, 0.0, 1.0, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
return vec4<f32>(0.0, 0.0, 0.0, 0.0);
|
||||
})");
|
||||
|
||||
const wgpu::ShaderModule sourceTexturePlane1FsModule = utils::CreateShaderModule(device, R"(
|
||||
@fragment fn main(@builtin(position) FragCoord : vec4<f32>)
|
||||
-> @location(0) vec4<f32> {
|
||||
if(FragCoord.x >= 1.0 && FragCoord.x < 3.0 && FragCoord.y >= 1.0 && FragCoord.y < 3.0) {
|
||||
if(FragCoord.y < 2.0 && FragCoord.x < 2.0) {
|
||||
return vec4<f32>(0.1402, 0.0175, 0.0, 0.0);
|
||||
}
|
||||
|
||||
if(FragCoord.y < 2.0 && FragCoord.x >= 2.0) {
|
||||
return vec4<f32>(0.5, 0.5, 0.0, 0.0);
|
||||
}
|
||||
|
||||
if(FragCoord.y >= 2.0 && FragCoord.x < 2.0) {
|
||||
return vec4<f32>(0.4172, 1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
if(FragCoord.y >= 2.0 && FragCoord.x >= 2.0) {
|
||||
return vec4<f32>(1.0, 0.4937, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
return vec4<f32>(0.5, 0.5, 0.0, 0.0);
|
||||
})");
|
||||
|
||||
wgpu::Texture sourceTexturePlane0 =
|
||||
Create2DTexture(device, kWidth, kHeight, wgpu::TextureFormat::R8Unorm,
|
||||
wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment);
|
||||
wgpu::Texture sourceTexturePlane1 =
|
||||
Create2DTexture(device, kWidth, kHeight, wgpu::TextureFormat::RG8Unorm,
|
||||
wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment);
|
||||
|
||||
RenderToSourceTexture(sourceTexturePlane0FsModule, sourceTexturePlane0);
|
||||
RenderToSourceTexture(sourceTexturePlane1FsModule, sourceTexturePlane1);
|
||||
|
||||
wgpu::Texture renderTexture =
|
||||
Create2DTexture(device, kWidth, kHeight, kFormat,
|
||||
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment);
|
||||
|
||||
struct CropExpectation {
|
||||
wgpu::ExternalTextureVisibleRect visibleRect;
|
||||
wgpu::ExternalTextureRotation rotation;
|
||||
utils::RGBA8 upperLeftColor;
|
||||
utils::RGBA8 upperRightColor;
|
||||
utils::RGBA8 lowerLeftColor;
|
||||
utils::RGBA8 lowerRightColor;
|
||||
};
|
||||
|
||||
std::array<CropExpectation, 9> expectations = {{
|
||||
{{0.0, 0.0, 1.0, 1.0},
|
||||
wgpu::ExternalTextureRotation::Rotate0Degrees,
|
||||
utils::RGBA8::kBlack,
|
||||
utils::RGBA8::kBlack,
|
||||
utils::RGBA8::kBlack,
|
||||
utils::RGBA8::kBlack},
|
||||
{{0.25, 0.25, 0.25, 0.25},
|
||||
wgpu::ExternalTextureRotation::Rotate0Degrees,
|
||||
utils::RGBA8::kGreen,
|
||||
utils::RGBA8::kGreen,
|
||||
utils::RGBA8::kGreen,
|
||||
utils::RGBA8::kGreen},
|
||||
{{0.5, 0.25, 0.25, 0.25},
|
||||
wgpu::ExternalTextureRotation::Rotate0Degrees,
|
||||
utils::RGBA8::kWhite,
|
||||
utils::RGBA8::kWhite,
|
||||
utils::RGBA8::kWhite,
|
||||
utils::RGBA8::kWhite},
|
||||
{{0.25, 0.5, 0.25, 0.25},
|
||||
wgpu::ExternalTextureRotation::Rotate0Degrees,
|
||||
utils::RGBA8::kRed,
|
||||
utils::RGBA8::kRed,
|
||||
utils::RGBA8::kRed,
|
||||
utils::RGBA8::kRed},
|
||||
{{0.5, 0.5, 0.25, 0.25},
|
||||
wgpu::ExternalTextureRotation::Rotate0Degrees,
|
||||
utils::RGBA8::kBlue,
|
||||
utils::RGBA8::kBlue,
|
||||
utils::RGBA8::kBlue,
|
||||
utils::RGBA8::kBlue},
|
||||
{{0.25, 0.25, 0.5, 0.5},
|
||||
wgpu::ExternalTextureRotation::Rotate0Degrees,
|
||||
utils::RGBA8::kGreen,
|
||||
utils::RGBA8::kWhite,
|
||||
utils::RGBA8::kRed,
|
||||
utils::RGBA8::kBlue},
|
||||
{{0.25, 0.25, 0.5, 0.5},
|
||||
wgpu::ExternalTextureRotation::Rotate90Degrees,
|
||||
utils::RGBA8::kRed,
|
||||
utils::RGBA8::kGreen,
|
||||
utils::RGBA8::kBlue,
|
||||
utils::RGBA8::kWhite},
|
||||
{{0.25, 0.25, 0.5, 0.5},
|
||||
wgpu::ExternalTextureRotation::Rotate180Degrees,
|
||||
utils::RGBA8::kBlue,
|
||||
utils::RGBA8::kRed,
|
||||
utils::RGBA8::kWhite,
|
||||
utils::RGBA8::kGreen},
|
||||
{{0.25, 0.25, 0.5, 0.5},
|
||||
wgpu::ExternalTextureRotation::Rotate270Degrees,
|
||||
utils::RGBA8::kWhite,
|
||||
utils::RGBA8::kBlue,
|
||||
utils::RGBA8::kGreen,
|
||||
utils::RGBA8::kRed},
|
||||
}};
|
||||
|
||||
for (const CropExpectation& exp : expectations) {
|
||||
// Pipeline Creation
|
||||
utils::ComboRenderPipelineDescriptor descriptor;
|
||||
descriptor.vertex.module = vsModule;
|
||||
descriptor.cFragment.module = fsSampleExternalTextureModule;
|
||||
descriptor.cTargets[0].format = kFormat;
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
||||
// Create an ExternalTextureDescriptor from the texture view
|
||||
wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor();
|
||||
externalDesc.plane0 = sourceTexturePlane0.CreateView();
|
||||
externalDesc.plane1 = sourceTexturePlane1.CreateView();
|
||||
externalDesc.rotation = exp.rotation;
|
||||
externalDesc.visibleRect = exp.visibleRect;
|
||||
|
||||
// Import the external texture
|
||||
wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(&externalDesc);
|
||||
|
||||
// Create a sampler and bind group
|
||||
wgpu::Sampler sampler = device.CreateSampler();
|
||||
|
||||
wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
|
||||
{{0, sampler}, {1, externalTexture}});
|
||||
|
||||
// Run the shader, which should sample from the external texture and draw a triangle into
|
||||
// the upper left corner of the render texture.
|
||||
wgpu::TextureView renderView = renderTexture.CreateView();
|
||||
utils::ComboRenderPassDescriptor renderPass({renderView}, nullptr);
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
|
||||
{
|
||||
pass.SetPipeline(pipeline);
|
||||
pass.SetBindGroup(0, bindGroup);
|
||||
pass.Draw(6);
|
||||
pass.End();
|
||||
}
|
||||
|
||||
wgpu::CommandBuffer commands = encoder.Finish();
|
||||
queue.Submit(1, &commands);
|
||||
|
||||
EXPECT_PIXEL_RGBA8_EQ(exp.upperLeftColor, renderTexture, 0, 0);
|
||||
EXPECT_PIXEL_RGBA8_EQ(exp.upperRightColor, renderTexture, 3, 0);
|
||||
EXPECT_PIXEL_RGBA8_EQ(exp.lowerLeftColor, renderTexture, 0, 3);
|
||||
EXPECT_PIXEL_RGBA8_EQ(exp.lowerRightColor, renderTexture, 3, 3);
|
||||
}
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(ExternalTextureTests,
|
||||
D3D12Backend(),
|
||||
MetalBackend(),
|
||||
|
||||
@@ -262,7 +262,7 @@ struct MultiplanarExternalTexture::State {
|
||||
b.Member("gammaDecodeParams", b.ty.type_name("GammaTransferParams")),
|
||||
b.Member("gammaEncodeParams", b.ty.type_name("GammaTransferParams")),
|
||||
b.Member("gamutConversionMatrix", b.ty.mat3x3<f32>()),
|
||||
b.Member("rotationMatrix", b.ty.mat2x2<f32>())};
|
||||
b.Member("coordTransformationMatrix", b.ty.mat2x3<f32>())};
|
||||
|
||||
params_struct_sym = b.Symbols().New("ExternalTextureParams");
|
||||
|
||||
@@ -315,10 +315,12 @@ struct MultiplanarExternalTexture::State {
|
||||
const ast::CallExpression* plane_1_call = nullptr;
|
||||
switch (call_type) {
|
||||
case sem::BuiltinType::kTextureSampleBaseClampToEdge:
|
||||
stmts.Push(b.Decl(b.Let("modifiedCoords",
|
||||
b.Add(b.Mul(b.Sub("coord", f32(0.5)),
|
||||
b.MemberAccessor("params", "rotationMatrix")),
|
||||
f32(0.5)))));
|
||||
// TODO(dawn:1614): Change this statement to incorporate the "- 0.5" into the
|
||||
// matrix.
|
||||
stmts.Push(
|
||||
b.Decl(b.Let("modifiedCoords",
|
||||
b.Mul(b.vec3<f32>(b.Sub("coord", f32(0.5)), f32(1.0f)),
|
||||
b.MemberAccessor("params", "coordTransformationMatrix")))));
|
||||
|
||||
stmts.Push(b.Decl(b.Let(
|
||||
"plane0_dims",
|
||||
|
||||
@@ -138,7 +138,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(1) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -194,7 +194,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(1) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -249,7 +249,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -268,7 +268,7 @@ fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
|
||||
}
|
||||
|
||||
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
|
||||
let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
|
||||
let modifiedCoords = (vec3<f32>((coord - 0.5f), 1.0f) * params.coordTransformationMatrix);
|
||||
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
|
||||
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
|
||||
let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
|
||||
@@ -333,7 +333,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -348,7 +348,7 @@ fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
|
||||
}
|
||||
|
||||
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
|
||||
let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
|
||||
let modifiedCoords = (vec3<f32>((coord - 0.5f), 1.0f) * params.coordTransformationMatrix);
|
||||
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
|
||||
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
|
||||
let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
|
||||
@@ -418,7 +418,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(1) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -511,7 +511,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(1) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -603,7 +603,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -622,7 +622,7 @@ fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
|
||||
}
|
||||
|
||||
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
|
||||
let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
|
||||
let modifiedCoords = (vec3<f32>((coord - 0.5f), 1.0f) * params.coordTransformationMatrix);
|
||||
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
|
||||
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
|
||||
let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
|
||||
@@ -702,7 +702,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -717,7 +717,7 @@ fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
|
||||
}
|
||||
|
||||
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
|
||||
let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
|
||||
let modifiedCoords = (vec3<f32>((coord - 0.5f), 1.0f) * params.coordTransformationMatrix);
|
||||
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
|
||||
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
|
||||
let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
|
||||
@@ -807,7 +807,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(4) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -844,7 +844,7 @@ fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
|
||||
}
|
||||
|
||||
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
|
||||
let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
|
||||
let modifiedCoords = (vec3<f32>((coord - 0.5f), 1.0f) * params.coordTransformationMatrix);
|
||||
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
|
||||
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
|
||||
let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
|
||||
@@ -918,7 +918,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -933,7 +933,7 @@ fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
|
||||
}
|
||||
|
||||
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
|
||||
let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
|
||||
let modifiedCoords = (vec3<f32>((coord - 0.5f), 1.0f) * params.coordTransformationMatrix);
|
||||
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
|
||||
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
|
||||
let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
|
||||
@@ -1011,7 +1011,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -1031,7 +1031,7 @@ fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
|
||||
}
|
||||
|
||||
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
|
||||
let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
|
||||
let modifiedCoords = (vec3<f32>((coord - 0.5f), 1.0f) * params.coordTransformationMatrix);
|
||||
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
|
||||
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
|
||||
let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
|
||||
@@ -1104,7 +1104,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -1119,7 +1119,7 @@ fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
|
||||
}
|
||||
|
||||
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
|
||||
let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
|
||||
let modifiedCoords = (vec3<f32>((coord - 0.5f), 1.0f) * params.coordTransformationMatrix);
|
||||
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
|
||||
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
|
||||
let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
|
||||
@@ -1199,7 +1199,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(3) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -1218,7 +1218,7 @@ fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
|
||||
}
|
||||
|
||||
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
|
||||
let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
|
||||
let modifiedCoords = (vec3<f32>((coord - 0.5f), 1.0f) * params.coordTransformationMatrix);
|
||||
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
|
||||
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
|
||||
let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
|
||||
@@ -1303,7 +1303,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(3) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -1327,7 +1327,7 @@ fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
|
||||
}
|
||||
|
||||
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
|
||||
let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
|
||||
let modifiedCoords = (vec3<f32>((coord - 0.5f), 1.0f) * params.coordTransformationMatrix);
|
||||
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
|
||||
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
|
||||
let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
|
||||
@@ -1408,7 +1408,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -1423,7 +1423,7 @@ fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
|
||||
}
|
||||
|
||||
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
|
||||
let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
|
||||
let modifiedCoords = (vec3<f32>((coord - 0.5f), 1.0f) * params.coordTransformationMatrix);
|
||||
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
|
||||
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
|
||||
let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
|
||||
@@ -1509,7 +1509,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -1524,7 +1524,7 @@ fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
|
||||
}
|
||||
|
||||
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
|
||||
let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
|
||||
let modifiedCoords = (vec3<f32>((coord - 0.5f), 1.0f) * params.coordTransformationMatrix);
|
||||
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
|
||||
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
|
||||
let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
|
||||
@@ -1598,7 +1598,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
fn f(ext_tex : texture_2d<f32>, ext_tex_plane_1 : texture_2d<f32>, ext_tex_params : ExternalTextureParams) -> vec2<u32> {
|
||||
@@ -1650,7 +1650,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -1667,7 +1667,7 @@ fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
|
||||
}
|
||||
|
||||
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
|
||||
let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
|
||||
let modifiedCoords = (vec3<f32>((coord - 0.5f), 1.0f) * params.coordTransformationMatrix);
|
||||
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
|
||||
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
|
||||
let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
|
||||
@@ -1746,7 +1746,7 @@ struct ExternalTextureParams {
|
||||
gammaDecodeParams : GammaTransferParams,
|
||||
gammaEncodeParams : GammaTransferParams,
|
||||
gamutConversionMatrix : mat3x3<f32>,
|
||||
rotationMatrix : mat2x2<f32>,
|
||||
coordTransformationMatrix : mat2x3<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
|
||||
@@ -1766,7 +1766,7 @@ fn gammaCorrection(v : vec3<f32>, params : GammaTransferParams) -> vec3<f32> {
|
||||
}
|
||||
|
||||
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
|
||||
let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
|
||||
let modifiedCoords = (vec3<f32>((coord - 0.5f), 1.0f) * params.coordTransformationMatrix);
|
||||
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
|
||||
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
|
||||
let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
|
||||
|
||||
Reference in New Issue
Block a user