<commit_before>export const description = `
Tests the behavior of anisotropic filtering.

TODO:
Note that anisotropic filtering is never guaranteed to occur, but we might be able to test some
things. If there are no guarantees we can issue warnings instead of failures. Ideas:
  - No *more* than the provided maxAnisotropy samples are used, by testing how many unique
    sample values come out of the sample operation.
  - Check anisotropy is done in the correct direciton (by having a 2D gradient and checking we get
    more of the color in the correct direction).
`;

import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { assert } from '../../../../common/framework/util/util.js';
import { GPUTest } from '../../../gpu_test.js';

const kRTSize = 16;
const kBytesPerRow = 256;
const xMiddle = kRTSize / 2; // we check the pixel value in the middle of the render target
const kColorAttachmentFormat = 'rgba8unorm';
const kTextureFormat = 'rgba8unorm';
const colors = [
  new Uint8Array([0xff, 0x00, 0x00, 0xff]), // miplevel = 0
  new Uint8Array([0x00, 0xff, 0x00, 0xff]), // miplevel = 1
  new Uint8Array([0x00, 0x00, 0xff, 0xff]), // miplevel = 2
];
const checkerColors = [
  new Uint8Array([0xff, 0x00, 0x00, 0xff]),
  new Uint8Array([0x00, 0xff, 0x00, 0xff]),
];

// renders texture a slanted plane placed in a specific way
class SamplerAnisotropicFilteringSlantedPlaneTest extends GPUTest {
  copyRenderTargetToBuffer(rt: GPUTexture): GPUBuffer {
    const byteLength = kRTSize * kBytesPerRow;
    const buffer = this.device.createBuffer({
      size: byteLength,
      usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
    });

    const commandEncoder = this.device.createCommandEncoder();
    commandEncoder.copyTextureToBuffer(
      { texture: rt, mipLevel: 0, origin: [0, 0, 0] },
      { buffer, bytesPerRow: kBytesPerRow, rowsPerImage: kRTSize },
      { width: kRTSize, height: kRTSize, depthOrArrayLayers: 1 }
    );
    this.queue.submit([commandEncoder.finish()]);

    return buffer;
  }

  private pipeline: GPURenderPipeline | undefined;
  async init(): Promise<void> {
    await super.init();

    this.pipeline = this.device.createRenderPipeline({
      vertex: {
        module: this.device.createShaderModule({
          code: `
            [[builtin(vertex_index)]] var<in> VertexIndex : i32;
            [[builtin(position)]] var<out> Position : vec4<f32>;
            [[location(0)]] var<out> fragUV : vec2<f32>;

            [[stage(vertex)]] fn main() {
              let position : array<vec3<f32>, 6> = array<vec3<f32>, 6>(
                vec3<f32>(-0.5, 0.5, -0.5),
                vec3<f32>(0.5, 0.5, -0.5),
                vec3<f32>(-0.5, 0.5, 0.5),
                vec3<f32>(-0.5, 0.5, 0.5),
                vec3<f32>(0.5, 0.5, -0.5),
                vec3<f32>(0.5, 0.5, 0.5));
              // uv is pre-scaled to mimic repeating tiled texture
              let uv : array<vec2<f32>, 6> = array<vec2<f32>, 6>(
                vec2<f32>(0.0, 0.0),
                vec2<f32>(1.0, 0.0),
                vec2<f32>(0.0, 50.0),
                vec2<f32>(0.0, 50.0),
                vec2<f32>(1.0, 0.0),
                vec2<f32>(1.0, 50.0));
              // draw a slanted plane in a specific way
              let matrix : mat4x4<f32> = mat4x4<f32>(
                vec4<f32>(-1.7320507764816284, 1.8322050568049563e-16, -6.176817699518044e-17, -6.170640314703498e-17),
                vec4<f32>(-2.1211504944260596e-16, -1.496108889579773, 0.5043753981590271, 0.5038710236549377),
                vec4<f32>(0.0, -43.63650894165039, -43.232173919677734, -43.18894577026367),
                vec4<f32>(0.0, 21.693578720092773, 21.789791107177734, 21.86800193786621));

              fragUV = uv[VertexIndex];
              Position = matrix * vec4<f32>(position[VertexIndex], 1.0);
            }
            `,
        }),
        entryPoint: 'main',
      },
      fragment: {
        module: this.device.createShaderModule({
          code: `
            [[set(0), binding(0)]] var sampler0 : sampler;
            [[set(0), binding(1)]] var texture0 : texture_2d<f32>;

            [[builtin(frag_coord)]] var<in> FragCoord : vec4<f32>;

            [[location(0)]] var<in> fragUV: vec2<f32>;

            [[location(0)]] var<out> fragColor : vec4<f32>;

            [[stage(fragment)]] fn main() {
                fragColor = textureSample(texture0, sampler0, fragUV);
            }
            `,
        }),
        entryPoint: 'main',
        targets: [{ format: 'rgba8unorm' }],
      },
      primitive: { topology: 'triangle-list' },
    });
  }
<commit_msg>Replace builtin(position) with builtin(frag_coord) (#540)<commit_after>export const description = `
Tests the behavior of anisotropic filtering.

TODO:
Note that anisotropic filtering is never guaranteed to occur, but we might be able to test some
things. If there are no guarantees we can issue warnings instead of failures. Ideas:
  - No *more* than the provided maxAnisotropy samples are used, by testing how many unique
    sample values come out of the sample operation.
  - Check anisotropy is done in the correct direciton (by having a 2D gradient and checking we get
    more of the color in the correct direction).
`;

import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { assert } from '../../../../common/framework/util/util.js';
import { GPUTest } from '../../../gpu_test.js';

const kRTSize = 16;
const kBytesPerRow = 256;
const xMiddle = kRTSize / 2; // we check the pixel value in the middle of the render target
const kColorAttachmentFormat = 'rgba8unorm';
const kTextureFormat = 'rgba8unorm';
const colors = [
  new Uint8Array([0xff, 0x00, 0x00, 0xff]), // miplevel = 0
  new Uint8Array([0x00, 0xff, 0x00, 0xff]), // miplevel = 1
  new Uint8Array([0x00, 0x00, 0xff, 0xff]), // miplevel = 2
];
const checkerColors = [
  new Uint8Array([0xff, 0x00, 0x00, 0xff]),
  new Uint8Array([0x00, 0xff, 0x00, 0xff]),
];

// renders texture a slanted plane placed in a specific way
class SamplerAnisotropicFilteringSlantedPlaneTest extends GPUTest {
  copyRenderTargetToBuffer(rt: GPUTexture): GPUBuffer {
    const byteLength = kRTSize * kBytesPerRow;
    const buffer = this.device.createBuffer({
      size: byteLength,
      usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
    });

    const commandEncoder = this.device.createCommandEncoder();
    commandEncoder.copyTextureToBuffer(
      { texture: rt, mipLevel: 0, origin: [0, 0, 0] },
      { buffer, bytesPerRow: kBytesPerRow, rowsPerImage: kRTSize },
      { width: kRTSize, height: kRTSize, depthOrArrayLayers: 1 }
    );
    this.queue.submit([commandEncoder.finish()]);

    return buffer;
  }

  private pipeline: GPURenderPipeline | undefined;
  async init(): Promise<void> {
    await super.init();

    this.pipeline = this.device.createRenderPipeline({
      vertex: {
        module: this.device.createShaderModule({
          code: `
            [[builtin(vertex_index)]] var<in> VertexIndex : i32;
            [[builtin(position)]] var<out> Position : vec4<f32>;
            [[location(0)]] var<out> fragUV : vec2<f32>;

            [[stage(vertex)]] fn main() {
              let position : array<vec3<f32>, 6> = array<vec3<f32>, 6>(
                vec3<f32>(-0.5, 0.5, -0.5),
                vec3<f32>(0.5, 0.5, -0.5),
                vec3<f32>(-0.5, 0.5, 0.5),
                vec3<f32>(-0.5, 0.5, 0.5),
                vec3<f32>(0.5, 0.5, -0.5),
                vec3<f32>(0.5, 0.5, 0.5));
              // uv is pre-scaled to mimic repeating tiled texture
              let uv : array<vec2<f32>, 6> = array<vec2<f32>, 6>(
                vec2<f32>(0.0, 0.0),
                vec2<f32>(1.0, 0.0),
                vec2<f32>(0.0, 50.0),
                vec2<f32>(0.0, 50.0),
                vec2<f32>(1.0, 0.0),
                vec2<f32>(1.0, 50.0));
              // draw a slanted plane in a specific way
              let matrix : mat4x4<f32> = mat4x4<f32>(
                vec4<f32>(-1.7320507764816284, 1.8322050568049563e-16, -6.176817699518044e-17, -6.170640314703498e-17),
                vec4<f32>(-2.1211504944260596e-16, -1.496108889579773, 0.5043753981590271, 0.5038710236549377),
                vec4<f32>(0.0, -43.63650894165039, -43.232173919677734, -43.18894577026367),
                vec4<f32>(0.0, 21.693578720092773, 21.789791107177734, 21.86800193786621));

              fragUV = uv[VertexIndex];
              Position = matrix * vec4<f32>(position[VertexIndex], 1.0);
            }
            `,
        }),
        entryPoint: 'main',
      },
      fragment: {
        module: this.device.createShaderModule({
          code: `
            [[set(0), binding(0)]] var sampler0 : sampler;
            [[set(0), binding(1)]] var texture0 : texture_2d<f32>;

            [[builtin(position)]] var<in> FragCoord : vec4<f32>;

            [[location(0)]] var<in> fragUV: vec2<f32>;

            [[location(0)]] var<out> fragColor : vec4<f32>;

            [[stage(fragment)]] fn main() {
                fragColor = textureSample(texture0, sampler0, fragUV);
            }
            `,
        }),
        entryPoint: 'main',
        targets: [{ format: 'rgba8unorm' }],
      },
      primitive: { topology: 'triangle-list' },
    });
  }

{'fraction_non_alphanumeric': 0.14149324179360653, 'fraction_numerical': 0.10287491954516198, 'mean_word_length': 2.3815741748277115, 'pattern_counts': {'":': 0, '<': 83, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1366232', 'n_tokens_mistral': 3696, 'n_tokens_neox': 3139, 'n_words': 754}