diff --git a/.github/workflows/visual-regression.yml b/.github/workflows/visual-regression.yml new file mode 100644 index 00000000..4cdfb7c2 --- /dev/null +++ b/.github/workflows/visual-regression.yml @@ -0,0 +1,201 @@ +name: Visual Regression + +on: + pull_request: + paths: + - 'Src/Render/Vulkan/**' + - 'Src/Render/Render_Shader.h' + - 'Include/GFx_Renderer_Vulkan.h' + - 'Tests/VisualRegression/**' + - 'Bin/x64/Msvc10/GFxPlayerTinyVulkan/**' + - 'Lib/**/libgfxrender_vulkan*' + workflow_dispatch: + +jobs: + swiftshader-capture: + name: Vulkan capture (SwiftShader) vs D3D11 reference + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + + # Install Vulkan SDK (headers + loader needed for build) + - name: Install Vulkan SDK + shell: pwsh + run: | + $sdkVersion = "1.3.290.0" + $url = "https://sdk.lunarg.com/sdk/download/$sdkVersion/windows/VulkanSDK-$sdkVersion-Installer.exe" + $installer = "$env:RUNNER_TEMP\VulkanSDK-Installer.exe" + Write-Host "Downloading Vulkan SDK $sdkVersion..." + Invoke-WebRequest -Uri $url -OutFile $installer -UseBasicParsing + Write-Host "Installing Vulkan SDK..." + Start-Process -FilePath $installer -ArgumentList "--accept-licenses --default-answer --confirm-command install" -Wait + $sdkPath = "C:\VulkanSDK\$sdkVersion" + echo "VULKAN_SDK=$sdkPath" >> $env:GITHUB_ENV + echo "VK_SDK_PATH=$sdkPath" >> $env:GITHUB_ENV + echo "$sdkPath\Bin" >> $env:GITHUB_PATH + + # Build CaptureVulkan from source + - name: Build CaptureVulkan + shell: pwsh + run: | + # Build expat, Render_Vulkan lib, and CaptureVulkan (skip D3D11 — no libs in CI) + & Tests/VisualRegression/build_tests.ps1 -SkipD3D11 + if (-not (Test-Path "Bin/x64/Msvc10/Tests/CaptureVulkan.exe")) { + Write-Error "CaptureVulkan.exe was not built" + exit 1 + } + Write-Host "CaptureVulkan.exe built successfully" + + # Download and set up SwiftShader as the Vulkan ICD + - name: Install SwiftShader + shell: pwsh + run: | + $swiftshaderDir = "$env:RUNNER_TEMP\swiftshader" + New-Item -ItemType Directory -Force -Path $swiftshaderDir | Out-Null + + # Download SwiftShader from official Chrome build artifacts + $url = "https://github.com/nicebyte/swiftshader-binaries/releases/download/v1/swiftshader-windows-x86_64.zip" + $zipPath = "$env:RUNNER_TEMP\swiftshader.zip" + Write-Host "Downloading SwiftShader from $url" + Invoke-WebRequest -Uri $url -OutFile $zipPath -UseBasicParsing + Expand-Archive -Path $zipPath -DestinationPath $swiftshaderDir -Force + + # Find the ICD JSON and DLL + $icdJson = Get-ChildItem -Path $swiftshaderDir -Recurse -Filter "vk_swiftshader_icd.json" | Select-Object -First 1 + if (-not $icdJson) { + Write-Error "vk_swiftshader_icd.json not found in downloaded archive" + exit 1 + } + Write-Host "SwiftShader ICD: $($icdJson.FullName)" + + # Set VK_ICD_FILENAMES so the Vulkan loader picks up SwiftShader + echo "VK_ICD_FILENAMES=$($icdJson.FullName)" >> $env:GITHUB_ENV + echo "SWIFTSHADER_DIR=$($icdJson.DirectoryName)" >> $env:GITHUB_ENV + + - name: Verify SwiftShader + shell: pwsh + run: | + Write-Host "VK_ICD_FILENAMES=$env:VK_ICD_FILENAMES" + if (-not (Test-Path $env:VK_ICD_FILENAMES)) { + Write-Error "SwiftShader ICD file not found" + exit 1 + } + Write-Host "SwiftShader ready" + + # Run CaptureVulkan for each test in the manifest + - name: Capture Vulkan frames (SwiftShader) + shell: pwsh + run: | + $manifest = Get-Content Tests/VisualRegression/TestManifest.json | ConvertFrom-Json + $captureExe = "Bin/x64/Msvc10/Tests/CaptureVulkan.exe" + $dataDir = "Bin/Data" + $outputRoot = "Tests/VisualRegression/Output/Captures/vulkan_swiftshader" + $defaultFrames = ($manifest.defaultFrames -join ",") + $defaultWidth = $manifest.defaultResolution.width + $defaultHeight = $manifest.defaultResolution.height + + if (-not (Test-Path $captureExe)) { + Write-Error "CaptureVulkan.exe not found — build step may have failed" + exit 1 + } + + $failed = 0 + foreach ($test in $manifest.tests) { + $name = $test.name + $swf = Join-Path $dataDir $test.swf + $outDir = Join-Path $outputRoot $name + New-Item -ItemType Directory -Force -Path $outDir | Out-Null + + $frames = if ($test.frames) { $test.frames -join "," } else { $defaultFrames } + $w = if ($test.resolution) { $test.resolution.width } else { $defaultWidth } + $h = if ($test.resolution) { $test.resolution.height } else { $defaultHeight } + + Write-Host "=== $name ===" -ForegroundColor Cyan + $proc = Start-Process -FilePath $captureExe ` + -ArgumentList "`"$swf`" `"$outDir`" --frames $frames --width $w --height $h" ` + -NoNewWindow -PassThru -Wait + if ($proc.ExitCode -ne 0) { + Write-Host " FAILED (exit code $($proc.ExitCode))" -ForegroundColor Red + $failed++ + } + } + + if ($failed -gt 0) { + Write-Warning "$failed test(s) failed to capture" + } + + # Convert PPM captures to PNG for comparison + - name: Convert captures to PNG + shell: python + run: | + import os, json, struct, zlib + + def ppm_to_png(ppm_path, png_path): + with open(ppm_path, 'rb') as f: + data = f.read() + # Parse PPM P6 header + idx = 0 + tokens = [] + while len(tokens) < 4: + while idx < len(data) and data[idx:idx+1] in (b' ', b'\t', b'\n', b'\r'): + idx += 1 + if data[idx:idx+1] == b'#': + while idx < len(data) and data[idx:idx+1] != b'\n': + idx += 1 + continue + start = idx + while idx < len(data) and data[idx:idx+1] not in (b' ', b'\t', b'\n', b'\r'): + idx += 1 + tokens.append(data[start:idx].decode()) + idx += 1 # skip whitespace after maxval + w, h = int(tokens[1]), int(tokens[2]) + pixels = data[idx:idx + w * h * 3] + + # Write PNG + def chunk(tag, d): + c = tag + d + return struct.pack('>I', len(d)) + c + struct.pack('>I', zlib.crc32(c) & 0xFFFFFFFF) + row = w * 3 + raw = bytearray() + for y in range(h): + raw.append(0) + raw.extend(pixels[y*row:(y+1)*row]) + with open(png_path, 'wb') as f: + f.write(b'\x89PNG\r\n\x1a\n') + f.write(chunk(b'IHDR', struct.pack('>IIBBBBB', w, h, 8, 2, 0, 0, 0))) + f.write(chunk(b'IDAT', zlib.compress(bytes(raw), 6))) + f.write(chunk(b'IEND', b'')) + + root = 'Tests/VisualRegression/Output/Captures/vulkan_swiftshader' + count = 0 + for dirpath, dirnames, filenames in os.walk(root): + for fn in filenames: + if fn.endswith('.ppm'): + ppm = os.path.join(dirpath, fn) + png = ppm.rsplit('.', 1)[0] + '.png' + ppm_to_png(ppm, png) + count += 1 + print(f'Converted {count} PPM files to PNG') + + # Compare SwiftShader captures against D3D11 reference + - name: Compare SwiftShader vs D3D11 reference + run: > + python Tests/VisualRegression/compare_reference.py + --vulkan-dir Tests/VisualRegression/Output/Captures/vulkan_swiftshader + --threshold 16 + + - name: Upload captures on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: swiftshader-captures + path: | + Tests/VisualRegression/Output/Captures/vulkan_swiftshader/ + Tests/VisualRegression/Output/Diff/ + diff --git a/Tests/VisualRegression/Reference/d3d11/3DInventory_AS3/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/3DInventory_AS3/frame_0001.png new file mode 100644 index 00000000..ce791d18 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DInventory_AS3/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/3DInventory_AS3/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/3DInventory_AS3/frame_0010.png new file mode 100644 index 00000000..82ba1b23 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DInventory_AS3/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/3DInventory_AS3/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/3DInventory_AS3/frame_0030.png new file mode 100644 index 00000000..9d098687 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DInventory_AS3/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/3DInventory_AS3/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/3DInventory_AS3/frame_0060.png new file mode 100644 index 00000000..b84e58a7 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DInventory_AS3/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/3DSquares_AS2/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS2/frame_0001.png new file mode 100644 index 00000000..a7f8bcb8 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/3DSquares_AS2/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS2/frame_0010.png new file mode 100644 index 00000000..388c9ae8 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/3DSquares_AS2/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS2/frame_0030.png new file mode 100644 index 00000000..e8ba42b6 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/3DSquares_AS2/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS2/frame_0060.png new file mode 100644 index 00000000..5067cca2 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/3DSquares_AS3/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS3/frame_0001.png new file mode 100644 index 00000000..a7f8bcb8 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS3/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/3DSquares_AS3/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS3/frame_0010.png new file mode 100644 index 00000000..5f9eb0b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS3/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/3DSquares_AS3/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS3/frame_0030.png new file mode 100644 index 00000000..5605114f Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS3/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/3DSquares_AS3/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS3/frame_0060.png new file mode 100644 index 00000000..ee9ea5fa Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DSquares_AS3/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/3DWindow_AS2/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/3DWindow_AS2/frame_0001.png new file mode 100644 index 00000000..31915b58 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DWindow_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/3DWindow_AS2/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/3DWindow_AS2/frame_0010.png new file mode 100644 index 00000000..1828ac78 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DWindow_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/3DWindow_AS2/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/3DWindow_AS2/frame_0030.png new file mode 100644 index 00000000..a4ea97a6 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DWindow_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/3DWindow_AS2/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/3DWindow_AS2/frame_0060.png new file mode 100644 index 00000000..d1cc827b Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/3DWindow_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FiltersExample/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/FiltersExample/frame_0001.png new file mode 100644 index 00000000..b89e81b6 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FiltersExample/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FiltersExample/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/FiltersExample/frame_0010.png new file mode 100644 index 00000000..b89e81b6 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FiltersExample/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FiltersExample/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/FiltersExample/frame_0030.png new file mode 100644 index 00000000..b89e81b6 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FiltersExample/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FiltersExample/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/FiltersExample/frame_0060.png new file mode 100644 index 00000000..b89e81b6 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FiltersExample/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishImage_AS2/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/FishImage_AS2/frame_0001.png new file mode 100644 index 00000000..a63110d5 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishImage_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishImage_AS2/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/FishImage_AS2/frame_0010.png new file mode 100644 index 00000000..2daf51d3 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishImage_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishImage_AS2/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/FishImage_AS2/frame_0030.png new file mode 100644 index 00000000..17e4a039 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishImage_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishImage_AS2/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/FishImage_AS2/frame_0060.png new file mode 100644 index 00000000..8d762aad Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishImage_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishImage_AS3/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/FishImage_AS3/frame_0001.png new file mode 100644 index 00000000..d56969af Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishImage_AS3/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishImage_AS3/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/FishImage_AS3/frame_0010.png new file mode 100644 index 00000000..a752f400 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishImage_AS3/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishImage_AS3/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/FishImage_AS3/frame_0030.png new file mode 100644 index 00000000..82c571c9 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishImage_AS3/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishImage_AS3/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/FishImage_AS3/frame_0060.png new file mode 100644 index 00000000..b6be2e4b Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishImage_AS3/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishVector_AS2/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/FishVector_AS2/frame_0001.png new file mode 100644 index 00000000..241b25af Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishVector_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishVector_AS2/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/FishVector_AS2/frame_0010.png new file mode 100644 index 00000000..5a745415 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishVector_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishVector_AS2/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/FishVector_AS2/frame_0030.png new file mode 100644 index 00000000..9cc35f1b Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishVector_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishVector_AS2/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/FishVector_AS2/frame_0060.png new file mode 100644 index 00000000..30639b8f Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishVector_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishVector_AS3/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/FishVector_AS3/frame_0001.png new file mode 100644 index 00000000..241b25af Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishVector_AS3/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishVector_AS3/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/FishVector_AS3/frame_0010.png new file mode 100644 index 00000000..5a745415 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishVector_AS3/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishVector_AS3/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/FishVector_AS3/frame_0030.png new file mode 100644 index 00000000..07c55a1d Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishVector_AS3/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/FishVector_AS3/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/FishVector_AS3/frame_0060.png new file mode 100644 index 00000000..30639b8f Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/FishVector_AS3/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/GFx_GDC_06/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/GFx_GDC_06/frame_0001.png new file mode 100644 index 00000000..659e1138 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/GFx_GDC_06/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/GFx_GDC_06/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/GFx_GDC_06/frame_0010.png new file mode 100644 index 00000000..29dd0ecc Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/GFx_GDC_06/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/GFx_GDC_06/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/GFx_GDC_06/frame_0030.png new file mode 100644 index 00000000..cabee498 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/GFx_GDC_06/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/GFx_GDC_06/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/GFx_GDC_06/frame_0060.png new file mode 100644 index 00000000..6388248b Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/GFx_GDC_06/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/GameCenter_AS2/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS2/frame_0001.png new file mode 100644 index 00000000..7ad5ec4f Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/GameCenter_AS2/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS2/frame_0010.png new file mode 100644 index 00000000..7ad5ec4f Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/GameCenter_AS2/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS2/frame_0030.png new file mode 100644 index 00000000..7ad5ec4f Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/GameCenter_AS2/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS2/frame_0060.png new file mode 100644 index 00000000..7ad5ec4f Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/GameCenter_AS3/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS3/frame_0001.png new file mode 100644 index 00000000..3e8d6fac Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS3/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/GameCenter_AS3/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS3/frame_0010.png new file mode 100644 index 00000000..a9cfb393 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS3/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/GameCenter_AS3/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS3/frame_0030.png new file mode 100644 index 00000000..d4b29e7a Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS3/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/GameCenter_AS3/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS3/frame_0060.png new file mode 100644 index 00000000..d4b29e7a Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/GameCenter_AS3/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/ImageDelegate_AS2/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/ImageDelegate_AS2/frame_0001.png new file mode 100644 index 00000000..f9e67323 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/ImageDelegate_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/ImageDelegate_AS2/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/ImageDelegate_AS2/frame_0010.png new file mode 100644 index 00000000..1afd0cc5 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/ImageDelegate_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/ImageDelegate_AS2/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/ImageDelegate_AS2/frame_0030.png new file mode 100644 index 00000000..03498912 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/ImageDelegate_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/ImageDelegate_AS2/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/ImageDelegate_AS2/frame_0060.png new file mode 100644 index 00000000..da2560ca Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/ImageDelegate_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/MMOPackedRender/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/MMOPackedRender/frame_0001.png new file mode 100644 index 00000000..a957ad77 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/MMOPackedRender/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/MMOPackedRender/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/MMOPackedRender/frame_0010.png new file mode 100644 index 00000000..71004695 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/MMOPackedRender/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/MMOPackedRender/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/MMOPackedRender/frame_0030.png new file mode 100644 index 00000000..e790ce9e Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/MMOPackedRender/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/MMOPackedRender/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/MMOPackedRender/frame_0060.png new file mode 100644 index 00000000..1d4ab044 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/MMOPackedRender/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/Mask_AS2/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/Mask_AS2/frame_0001.png new file mode 100644 index 00000000..4b84c0a8 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/Mask_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/Mask_AS2/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/Mask_AS2/frame_0010.png new file mode 100644 index 00000000..edc8e5f6 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/Mask_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/Mask_AS2/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/Mask_AS2/frame_0030.png new file mode 100644 index 00000000..8d6709d1 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/Mask_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/Mask_AS2/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/Mask_AS2/frame_0060.png new file mode 100644 index 00000000..810d04f6 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/Mask_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/Mask_AS3/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/Mask_AS3/frame_0001.png new file mode 100644 index 00000000..4b84c0a8 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/Mask_AS3/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/Mask_AS3/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/Mask_AS3/frame_0010.png new file mode 100644 index 00000000..edc8e5f6 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/Mask_AS3/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/Mask_AS3/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/Mask_AS3/frame_0030.png new file mode 100644 index 00000000..8d6709d1 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/Mask_AS3/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/Mask_AS3/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/Mask_AS3/frame_0060.png new file mode 100644 index 00000000..810d04f6 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/Mask_AS3/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/PropertyModifier/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/PropertyModifier/frame_0001.png new file mode 100644 index 00000000..5483aea6 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/PropertyModifier/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/PropertyModifier/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/PropertyModifier/frame_0010.png new file mode 100644 index 00000000..8395189f Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/PropertyModifier/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/PropertyModifier/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/PropertyModifier/frame_0030.png new file mode 100644 index 00000000..8395189f Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/PropertyModifier/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/PropertyModifier/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/PropertyModifier/frame_0060.png new file mode 100644 index 00000000..8395189f Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/PropertyModifier/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS2/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS2/frame_0001.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS2/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS2/frame_0010.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS2/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS2/frame_0030.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS2/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS2/frame_0060.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS3/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS3/frame_0001.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS3/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS3/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS3/frame_0010.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS3/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS3/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS3/frame_0030.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS3/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS3/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS3/frame_0060.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/ScaleformLogo_AS3/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/TextFilterEffects/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/TextFilterEffects/frame_0001.png new file mode 100644 index 00000000..21c42106 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/TextFilterEffects/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/TextFilterEffects/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/TextFilterEffects/frame_0010.png new file mode 100644 index 00000000..ff6548df Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/TextFilterEffects/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/TextFilterEffects/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/TextFilterEffects/frame_0030.png new file mode 100644 index 00000000..fb960ea2 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/TextFilterEffects/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/TextFilterEffects/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/TextFilterEffects/frame_0060.png new file mode 100644 index 00000000..ffa8fe90 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/TextFilterEffects/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/Window_AS2/frame_0001.png b/Tests/VisualRegression/Reference/d3d11/Window_AS2/frame_0001.png new file mode 100644 index 00000000..3da7dcfa Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/Window_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/Window_AS2/frame_0010.png b/Tests/VisualRegression/Reference/d3d11/Window_AS2/frame_0010.png new file mode 100644 index 00000000..42b115e3 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/Window_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/Window_AS2/frame_0030.png b/Tests/VisualRegression/Reference/d3d11/Window_AS2/frame_0030.png new file mode 100644 index 00000000..8f65e246 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/Window_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/d3d11/Window_AS2/frame_0060.png b/Tests/VisualRegression/Reference/d3d11/Window_AS2/frame_0060.png new file mode 100644 index 00000000..0a428d25 Binary files /dev/null and b/Tests/VisualRegression/Reference/d3d11/Window_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DInventory_AS3/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/3DInventory_AS3/frame_0001.png new file mode 100644 index 00000000..ce791d18 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DInventory_AS3/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DInventory_AS3/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/3DInventory_AS3/frame_0010.png new file mode 100644 index 00000000..82ba1b23 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DInventory_AS3/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DInventory_AS3/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/3DInventory_AS3/frame_0030.png new file mode 100644 index 00000000..efd85cf1 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DInventory_AS3/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DInventory_AS3/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/3DInventory_AS3/frame_0060.png new file mode 100644 index 00000000..1a16da76 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DInventory_AS3/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DSquares_AS2/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS2/frame_0001.png new file mode 100644 index 00000000..a7f8bcb8 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DSquares_AS2/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS2/frame_0010.png new file mode 100644 index 00000000..388c9ae8 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DSquares_AS2/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS2/frame_0030.png new file mode 100644 index 00000000..e8ba42b6 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DSquares_AS2/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS2/frame_0060.png new file mode 100644 index 00000000..5067cca2 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DSquares_AS3/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS3/frame_0001.png new file mode 100644 index 00000000..a7f8bcb8 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS3/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DSquares_AS3/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS3/frame_0010.png new file mode 100644 index 00000000..5f9eb0b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS3/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DSquares_AS3/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS3/frame_0030.png new file mode 100644 index 00000000..5605114f Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS3/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DSquares_AS3/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS3/frame_0060.png new file mode 100644 index 00000000..ee9ea5fa Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DSquares_AS3/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DWindow_AS2/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/3DWindow_AS2/frame_0001.png new file mode 100644 index 00000000..31915b58 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DWindow_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DWindow_AS2/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/3DWindow_AS2/frame_0010.png new file mode 100644 index 00000000..1828ac78 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DWindow_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DWindow_AS2/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/3DWindow_AS2/frame_0030.png new file mode 100644 index 00000000..d646dbc5 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DWindow_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/3DWindow_AS2/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/3DWindow_AS2/frame_0060.png new file mode 100644 index 00000000..d1cc827b Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/3DWindow_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FiltersExample/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/FiltersExample/frame_0001.png new file mode 100644 index 00000000..b89e81b6 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FiltersExample/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FiltersExample/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/FiltersExample/frame_0010.png new file mode 100644 index 00000000..b89e81b6 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FiltersExample/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FiltersExample/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/FiltersExample/frame_0030.png new file mode 100644 index 00000000..b89e81b6 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FiltersExample/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FiltersExample/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/FiltersExample/frame_0060.png new file mode 100644 index 00000000..b89e81b6 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FiltersExample/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishImage_AS2/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/FishImage_AS2/frame_0001.png new file mode 100644 index 00000000..a63110d5 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishImage_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishImage_AS2/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/FishImage_AS2/frame_0010.png new file mode 100644 index 00000000..2daf51d3 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishImage_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishImage_AS2/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/FishImage_AS2/frame_0030.png new file mode 100644 index 00000000..17e4a039 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishImage_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishImage_AS2/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/FishImage_AS2/frame_0060.png new file mode 100644 index 00000000..8d762aad Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishImage_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishImage_AS3/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/FishImage_AS3/frame_0001.png new file mode 100644 index 00000000..d56969af Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishImage_AS3/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishImage_AS3/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/FishImage_AS3/frame_0010.png new file mode 100644 index 00000000..a752f400 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishImage_AS3/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishImage_AS3/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/FishImage_AS3/frame_0030.png new file mode 100644 index 00000000..82c571c9 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishImage_AS3/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishImage_AS3/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/FishImage_AS3/frame_0060.png new file mode 100644 index 00000000..b6be2e4b Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishImage_AS3/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishVector_AS2/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/FishVector_AS2/frame_0001.png new file mode 100644 index 00000000..241b25af Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishVector_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishVector_AS2/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/FishVector_AS2/frame_0010.png new file mode 100644 index 00000000..5a745415 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishVector_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishVector_AS2/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/FishVector_AS2/frame_0030.png new file mode 100644 index 00000000..07c55a1d Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishVector_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishVector_AS2/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/FishVector_AS2/frame_0060.png new file mode 100644 index 00000000..30639b8f Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishVector_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishVector_AS3/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/FishVector_AS3/frame_0001.png new file mode 100644 index 00000000..241b25af Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishVector_AS3/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishVector_AS3/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/FishVector_AS3/frame_0010.png new file mode 100644 index 00000000..5a745415 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishVector_AS3/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishVector_AS3/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/FishVector_AS3/frame_0030.png new file mode 100644 index 00000000..07c55a1d Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishVector_AS3/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/FishVector_AS3/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/FishVector_AS3/frame_0060.png new file mode 100644 index 00000000..30639b8f Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/FishVector_AS3/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/GFx_GDC_06/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/GFx_GDC_06/frame_0001.png new file mode 100644 index 00000000..659e1138 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/GFx_GDC_06/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/GFx_GDC_06/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/GFx_GDC_06/frame_0010.png new file mode 100644 index 00000000..29dd0ecc Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/GFx_GDC_06/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/GFx_GDC_06/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/GFx_GDC_06/frame_0030.png new file mode 100644 index 00000000..cabee498 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/GFx_GDC_06/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/GFx_GDC_06/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/GFx_GDC_06/frame_0060.png new file mode 100644 index 00000000..6388248b Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/GFx_GDC_06/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/GameCenter_AS2/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS2/frame_0001.png new file mode 100644 index 00000000..7ad5ec4f Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/GameCenter_AS2/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS2/frame_0010.png new file mode 100644 index 00000000..7ad5ec4f Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/GameCenter_AS2/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS2/frame_0030.png new file mode 100644 index 00000000..7ad5ec4f Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/GameCenter_AS2/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS2/frame_0060.png new file mode 100644 index 00000000..7ad5ec4f Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/GameCenter_AS3/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS3/frame_0001.png new file mode 100644 index 00000000..3e8d6fac Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS3/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/GameCenter_AS3/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS3/frame_0010.png new file mode 100644 index 00000000..a9cfb393 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS3/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/GameCenter_AS3/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS3/frame_0030.png new file mode 100644 index 00000000..d4b29e7a Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS3/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/GameCenter_AS3/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS3/frame_0060.png new file mode 100644 index 00000000..d4b29e7a Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/GameCenter_AS3/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/ImageDelegate_AS2/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/ImageDelegate_AS2/frame_0001.png new file mode 100644 index 00000000..f9e67323 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/ImageDelegate_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/ImageDelegate_AS2/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/ImageDelegate_AS2/frame_0010.png new file mode 100644 index 00000000..1afd0cc5 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/ImageDelegate_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/ImageDelegate_AS2/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/ImageDelegate_AS2/frame_0030.png new file mode 100644 index 00000000..03498912 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/ImageDelegate_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/ImageDelegate_AS2/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/ImageDelegate_AS2/frame_0060.png new file mode 100644 index 00000000..da2560ca Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/ImageDelegate_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/MMOPackedRender/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/MMOPackedRender/frame_0001.png new file mode 100644 index 00000000..457361bc Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/MMOPackedRender/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/MMOPackedRender/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/MMOPackedRender/frame_0010.png new file mode 100644 index 00000000..3d451ff5 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/MMOPackedRender/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/MMOPackedRender/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/MMOPackedRender/frame_0030.png new file mode 100644 index 00000000..0211af07 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/MMOPackedRender/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/MMOPackedRender/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/MMOPackedRender/frame_0060.png new file mode 100644 index 00000000..6313e780 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/MMOPackedRender/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/Mask_AS2/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/Mask_AS2/frame_0001.png new file mode 100644 index 00000000..4b84c0a8 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/Mask_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/Mask_AS2/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/Mask_AS2/frame_0010.png new file mode 100644 index 00000000..edc8e5f6 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/Mask_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/Mask_AS2/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/Mask_AS2/frame_0030.png new file mode 100644 index 00000000..8d6709d1 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/Mask_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/Mask_AS2/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/Mask_AS2/frame_0060.png new file mode 100644 index 00000000..810d04f6 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/Mask_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/Mask_AS3/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/Mask_AS3/frame_0001.png new file mode 100644 index 00000000..4b84c0a8 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/Mask_AS3/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/Mask_AS3/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/Mask_AS3/frame_0010.png new file mode 100644 index 00000000..edc8e5f6 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/Mask_AS3/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/Mask_AS3/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/Mask_AS3/frame_0030.png new file mode 100644 index 00000000..8d6709d1 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/Mask_AS3/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/Mask_AS3/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/Mask_AS3/frame_0060.png new file mode 100644 index 00000000..810d04f6 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/Mask_AS3/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/PropertyModifier/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/PropertyModifier/frame_0001.png new file mode 100644 index 00000000..5483aea6 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/PropertyModifier/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/PropertyModifier/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/PropertyModifier/frame_0010.png new file mode 100644 index 00000000..8395189f Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/PropertyModifier/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/PropertyModifier/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/PropertyModifier/frame_0030.png new file mode 100644 index 00000000..8395189f Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/PropertyModifier/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/PropertyModifier/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/PropertyModifier/frame_0060.png new file mode 100644 index 00000000..8395189f Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/PropertyModifier/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS2/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS2/frame_0001.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS2/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS2/frame_0010.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS2/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS2/frame_0030.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS2/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS2/frame_0060.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS3/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS3/frame_0001.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS3/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS3/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS3/frame_0010.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS3/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS3/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS3/frame_0030.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS3/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS3/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS3/frame_0060.png new file mode 100644 index 00000000..5d57b7b3 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/ScaleformLogo_AS3/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/TextFilterEffects/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/TextFilterEffects/frame_0001.png new file mode 100644 index 00000000..21c42106 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/TextFilterEffects/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/TextFilterEffects/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/TextFilterEffects/frame_0010.png new file mode 100644 index 00000000..ff6548df Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/TextFilterEffects/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/TextFilterEffects/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/TextFilterEffects/frame_0030.png new file mode 100644 index 00000000..fb960ea2 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/TextFilterEffects/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/TextFilterEffects/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/TextFilterEffects/frame_0060.png new file mode 100644 index 00000000..ffa8fe90 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/TextFilterEffects/frame_0060.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/Window_AS2/frame_0001.png b/Tests/VisualRegression/Reference/vulkan/Window_AS2/frame_0001.png new file mode 100644 index 00000000..3da7dcfa Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/Window_AS2/frame_0001.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/Window_AS2/frame_0010.png b/Tests/VisualRegression/Reference/vulkan/Window_AS2/frame_0010.png new file mode 100644 index 00000000..42b115e3 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/Window_AS2/frame_0010.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/Window_AS2/frame_0030.png b/Tests/VisualRegression/Reference/vulkan/Window_AS2/frame_0030.png new file mode 100644 index 00000000..8f65e246 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/Window_AS2/frame_0030.png differ diff --git a/Tests/VisualRegression/Reference/vulkan/Window_AS2/frame_0060.png b/Tests/VisualRegression/Reference/vulkan/Window_AS2/frame_0060.png new file mode 100644 index 00000000..077ddcd7 Binary files /dev/null and b/Tests/VisualRegression/Reference/vulkan/Window_AS2/frame_0060.png differ diff --git a/Tests/VisualRegression/build_tests.ps1 b/Tests/VisualRegression/build_tests.ps1 index 2bc7d5b9..c7a17a1c 100644 --- a/Tests/VisualRegression/build_tests.ps1 +++ b/Tests/VisualRegression/build_tests.ps1 @@ -1,5 +1,8 @@ # Build visual regression test tools: CaptureD3D11 and CaptureVulkan. # Run from scaleform_sdk root, or from Tests/VisualRegression. +# Use --skip-d3d11 to build only Vulkan (e.g. in CI without D3D11 libs). + +param([switch]$SkipD3D11) $ErrorActionPreference = "Stop" @@ -7,22 +10,38 @@ $ErrorActionPreference = "Stop" $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $root = (Resolve-Path (Join-Path $scriptDir "..\..")).Path -$vsDevCmd = "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\VsDevCmd.bat" +# Find Visual Studio using vswhere (works for all editions: Community, Professional, Enterprise) +$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" +if (Test-Path $vswhere) { + $vsInstall = & $vswhere -latest -property installationPath 2>$null + if ($vsInstall) { + $vsDevCmd = Join-Path $vsInstall "Common7\Tools\VsDevCmd.bat" + } +} +# Fallback to hardcoded paths +if (-not $vsDevCmd -or -not (Test-Path $vsDevCmd)) { + $vsDevCmd = "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\VsDevCmd.bat" +} if (-not (Test-Path $vsDevCmd)) { - # Try Community 2019 $vsDevCmd = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat" } if (-not (Test-Path $vsDevCmd)) { - Write-Error "VsDevCmd.bat not found. Please set the path for your Visual Studio installation." + Write-Error "VsDevCmd.bat not found. Install Visual Studio or set the path manually." exit 1 } $expatProj = Join-Path $root "3rdParty\expat-2.1.0\gfx_projects\Win32\Msvc10\expat.vcxproj" $renderVkProj = Join-Path $root "Projects\Win32\Msvc10\SDK\Render\Render_Vulkan.vcxproj" -$captureD3D11Proj = Join-Path $root "Projects\Win32\Msvc10\Tests\CaptureD3D11\CaptureD3D11.vcxproj" $captureVkProj = Join-Path $root "Projects\Win32\Msvc10\Tests\CaptureVulkan\CaptureVulkan.vcxproj" -foreach ($proj in @($expatProj, $renderVkProj, $captureD3D11Proj, $captureVkProj)) { +$requiredProjs = @($expatProj, $renderVkProj, $captureVkProj) + +if (-not $SkipD3D11) { + $captureD3D11Proj = Join-Path $root "Projects\Win32\Msvc10\Tests\CaptureD3D11\CaptureD3D11.vcxproj" + $requiredProjs += $captureD3D11Proj +} + +foreach ($proj in $requiredProjs) { if (-not (Test-Path $proj)) { Write-Error "Project not found: $proj"; exit 1 } } @@ -43,9 +62,13 @@ MSBuild $expatProj "Release" "x64" Write-Host "=== Building Render_Vulkan (Vulkan_Release x64) ===" -ForegroundColor Cyan MSBuild $renderVkProj "Vulkan_Release" "x64" -# 3) Build CaptureD3D11 -Write-Host "=== Building CaptureD3D11 (D3D11_Release x64) ===" -ForegroundColor Cyan -MSBuild $captureD3D11Proj "D3D11_Release" "x64" +# 3) Build CaptureD3D11 (skipped with -SkipD3D11) +if (-not $SkipD3D11) { + Write-Host "=== Building CaptureD3D11 (D3D11_Release x64) ===" -ForegroundColor Cyan + MSBuild $captureD3D11Proj "D3D11_Release" "x64" +} else { + Write-Host "=== Skipping CaptureD3D11 (-SkipD3D11) ===" -ForegroundColor Yellow +} # 4) Build CaptureVulkan Write-Host "=== Building CaptureVulkan (Vulkan_Release x64) ===" -ForegroundColor Cyan diff --git a/Tests/VisualRegression/compare_images.py b/Tests/VisualRegression/compare_images.py index 27f8d0da..9c03da80 100644 --- a/Tests/VisualRegression/compare_images.py +++ b/Tests/VisualRegression/compare_images.py @@ -1,14 +1,13 @@ #!/usr/bin/env python3 """ -compare_images.py - Per-pixel comparison of two PPM (P6 binary) images. +compare_images.py - Per-pixel comparison of two PPM/PNG images. -Reads two PPM files, computes pixel-level differences, and outputs a JSON -result to stdout. +Reads two image files (PPM P6 binary or PNG 8-bit RGB/RGBA), computes +pixel-level differences, and outputs a JSON result to stdout. -Writes alongside each PPM: - - A .png version of the reference image - - A .png version of the test image - - A diff PPM + PNG (4x amplified, written only when mismatches exist) +Writes alongside each input image: + - A .png version of the image (skipped when input is already PNG) + - A diff PNG (4x amplified, written only when mismatches exist) Output JSON: { pass, rmse, maxDelta, mismatchCount, mismatchPercent, threshold, width, height } @@ -76,6 +75,155 @@ def token(): return width, height, pixels +# --------------------------------------------------------------------------- +# PNG reader (pure stdlib - struct + zlib, no Pillow required) +# --------------------------------------------------------------------------- + +def read_png(path): + """Read an 8-bit RGB or RGBA PNG file. Returns (width, height, rgb_bytes). + + Only supports bit_depth=8, color_type=2 (RGB) or 6 (RGBA). + RGBA images have their alpha channel stripped to return RGB only. + """ + with open(path, 'rb') as f: + data = f.read() + + # Validate PNG signature + sig = b'\x89PNG\r\n\x1a\n' + if data[:8] != sig: + raise ValueError(f'Not a PNG file: {path!r}') + + # Parse chunks + pos = 8 + ihdr_parsed = False + width = height = bit_depth = color_type = 0 + idat_chunks = [] + + while pos < len(data): + if pos + 8 > len(data): + break + length = struct.unpack('>I', data[pos:pos + 4])[0] + tag = data[pos + 4:pos + 8] + chunk_data = data[pos + 8:pos + 8 + length] + # skip CRC (4 bytes after chunk data) + pos = pos + 8 + length + 4 + + if tag == b'IHDR': + if len(chunk_data) < 13: + raise ValueError(f'Truncated IHDR in {path!r}') + width, height, bit_depth, color_type, comp, filt, interlace = \ + struct.unpack('>IIBBBBB', chunk_data[:13]) + if bit_depth != 8: + raise ValueError( + f'Unsupported bit depth {bit_depth} in {path!r} (only 8 supported)') + if color_type not in (2, 6): + raise ValueError( + f'Unsupported color type {color_type} in {path!r} ' + f'(only RGB=2 and RGBA=6 supported)') + if interlace != 0: + raise ValueError(f'Interlaced PNGs not supported: {path!r}') + ihdr_parsed = True + elif tag == b'IDAT': + idat_chunks.append(chunk_data) + elif tag == b'IEND': + break + + if not ihdr_parsed: + raise ValueError(f'No IHDR chunk found in {path!r}') + if not idat_chunks: + raise ValueError(f'No IDAT chunks found in {path!r}') + + # Decompress concatenated IDAT data + raw = zlib.decompress(b''.join(idat_chunks)) + + # Determine bytes per pixel and stride + bpp = 3 if color_type == 2 else 4 + stride = width * bpp + expected_raw = height * (1 + stride) # 1 filter byte per row + if len(raw) < expected_raw: + raise ValueError( + f'Decompressed data too short in {path!r}: ' + f'expected {expected_raw}, got {len(raw)}') + + # Reverse PNG row filters + def paeth(a, b, c): + p = a + b - c + pa = abs(p - a) + pb = abs(p - b) + pc = abs(p - c) + if pa <= pb and pa <= pc: + return a + elif pb <= pc: + return b + else: + return c + + prev_row = bytearray(stride) + pixels = bytearray(height * stride) + + for y in range(height): + row_start = y * (1 + stride) + filter_type = raw[row_start] + cur_raw = raw[row_start + 1:row_start + 1 + stride] + cur_row = bytearray(stride) + + if filter_type == 0: # None + cur_row[:] = cur_raw + elif filter_type == 1: # Sub + for x in range(stride): + a = cur_row[x - bpp] if x >= bpp else 0 + cur_row[x] = (cur_raw[x] + a) & 0xFF + elif filter_type == 2: # Up + for x in range(stride): + cur_row[x] = (cur_raw[x] + prev_row[x]) & 0xFF + elif filter_type == 3: # Average + for x in range(stride): + a = cur_row[x - bpp] if x >= bpp else 0 + b = prev_row[x] + cur_row[x] = (cur_raw[x] + ((a + b) >> 1)) & 0xFF + elif filter_type == 4: # Paeth + for x in range(stride): + a = cur_row[x - bpp] if x >= bpp else 0 + b = prev_row[x] + c = prev_row[x - bpp] if x >= bpp else 0 + cur_row[x] = (cur_raw[x] + paeth(a, b, c)) & 0xFF + else: + raise ValueError( + f'Unknown PNG filter type {filter_type} at row {y} in {path!r}') + + pixels[y * stride:(y + 1) * stride] = cur_row + prev_row = cur_row + + # If RGBA, strip alpha to return RGB only + if color_type == 6: + rgb = bytearray(width * height * 3) + for i in range(width * height): + rgb[i * 3] = pixels[i * 4] + rgb[i * 3 + 1] = pixels[i * 4 + 1] + rgb[i * 3 + 2] = pixels[i * 4 + 2] + return width, height, bytes(rgb) + + return width, height, bytes(pixels) + + +# --------------------------------------------------------------------------- +# Image dispatcher +# --------------------------------------------------------------------------- + +def read_image(path): + """Read a PPM or PNG image file. Returns (width, height, rgb_bytes). + + Dispatches to read_ppm or read_png based on file extension. + """ + ext = os.path.splitext(path)[1].lower() + if ext == '.ppm': + return read_ppm(path) + elif ext == '.png': + return read_png(path) + else: + raise ValueError(f'Unsupported image format {ext!r} for {path!r} (expected .ppm or .png)') + + # --------------------------------------------------------------------------- # PNG writer (pure stdlib - struct + zlib, no Pillow required) # --------------------------------------------------------------------------- @@ -111,23 +259,23 @@ def ppm_to_png_path(ppm_path): def main(): ap = argparse.ArgumentParser( - description='Compare two PPM images pixel by pixel; also writes PNG versions.' + description='Compare two PPM/PNG images pixel by pixel; writes PNG diff output.' ) - ap.add_argument('reference', help='Reference PPM image path') - ap.add_argument('test', help='Test PPM image path') - ap.add_argument('--diff', default='', help='Output diff PPM path') + ap.add_argument('reference', help='Reference image path (PPM or PNG)') + ap.add_argument('test', help='Test image path (PPM or PNG)') + ap.add_argument('--diff', default='', help='Output diff image path (PPM or PNG)') ap.add_argument('--threshold', type=int, default=8, help='Per-pixel sum-of-channels threshold for mismatch (default: 8)') args = ap.parse_args() try: - rw, rh, rpx = read_ppm(args.reference) + rw, rh, rpx = read_image(args.reference) except Exception as e: print(json.dumps({'pass': False, 'error': f'Failed to read reference: {e}'})) sys.exit(1) try: - tw, th, tpx = read_ppm(args.test) + tw, th, tpx = read_image(args.test) except Exception as e: print(json.dumps({'pass': False, 'error': f'Failed to read test: {e}'})) sys.exit(1) @@ -166,18 +314,28 @@ def main(): mismatch_pct = round(mismatch_count / n * 100, 4) passed = mismatch_count == 0 or rmse <= args.threshold / 3.0 - # Write PNG versions of reference and test for easy viewing - write_png(ppm_to_png_path(args.reference), w, h, bytes(rpx[:n * 3])) - write_png(ppm_to_png_path(args.test), w, h, bytes(tpx[:n * 3])) + # Write PNG versions of reference and test for easy viewing (skip if already PNG) + ref_ext = os.path.splitext(args.reference)[1].lower() + test_ext = os.path.splitext(args.test)[1].lower() + if ref_ext != '.png': + write_png(ppm_to_png_path(args.reference), w, h, bytes(rpx[:n * 3])) + if test_ext != '.png': + write_png(ppm_to_png_path(args.test), w, h, bytes(tpx[:n * 3])) - # Write diff PPM + PNG when there are any mismatches + # Write diff output when there are any mismatches if diff_data is not None and mismatch_count > 0: diff_dir = os.path.dirname(os.path.abspath(args.diff)) os.makedirs(diff_dir, exist_ok=True) - with open(args.diff, 'wb') as f: - f.write(f'P6\n{w} {h}\n255\n'.encode('ascii')) - f.write(bytes(diff_data)) - write_png(ppm_to_png_path(args.diff), w, h, bytes(diff_data)) + diff_ext = os.path.splitext(args.diff)[1].lower() + if diff_ext == '.png': + # Write PNG diff directly + write_png(args.diff, w, h, bytes(diff_data)) + else: + # Write PPM diff + a PNG copy alongside + with open(args.diff, 'wb') as f: + f.write(f'P6\n{w} {h}\n255\n'.encode('ascii')) + f.write(bytes(diff_data)) + write_png(ppm_to_png_path(args.diff), w, h, bytes(diff_data)) result = { 'pass': passed, diff --git a/Tests/VisualRegression/compare_reference.py b/Tests/VisualRegression/compare_reference.py new file mode 100644 index 00000000..7e507778 --- /dev/null +++ b/Tests/VisualRegression/compare_reference.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python3 +""" +compare_reference.py - Compare committed reference images (no GPU needed). + +Reads TestManifest.json and compares D3D11 vs Vulkan reference PNGs from +the Reference/ directory. Intended for CI where no GPU is available. + +Can also compare live Vulkan captures against D3D11 reference when run +after CaptureVulkan with --vulkan-dir pointing to fresh captures. + +Usage: + compare_reference.py [--reference-dir Reference] + [--vulkan-dir Reference/vulkan] + [--threshold 8] + [--manifest TestManifest.json] + +Exit code: 0 = all pass, 1 = any failure. +""" + +import sys +import os +import json +import subprocess +import argparse + +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) + + +def main(): + ap = argparse.ArgumentParser(description='Compare reference images (no GPU needed)') + ap.add_argument('--manifest', default='', + help='Path to TestManifest.json') + ap.add_argument('--reference-dir', default='', + help='Root reference directory (default: Reference/)') + ap.add_argument('--vulkan-dir', default='', + help='Vulkan captures directory (default: /vulkan)') + ap.add_argument('--threshold', type=int, default=8, + help='Per-pixel mismatch threshold (default: 8)') + ap.add_argument('--diff-dir', default='', + help='Output directory for diff images (default: Output/Diff)') + args = ap.parse_args() + + manifest_path = args.manifest or os.path.join(SCRIPT_DIR, 'TestManifest.json') + reference_dir = args.reference_dir or os.path.join(SCRIPT_DIR, 'Reference') + vulkan_dir = args.vulkan_dir or os.path.join(reference_dir, 'vulkan') + d3d11_dir = os.path.join(reference_dir, 'd3d11') + diff_dir = args.diff_dir or os.path.join(SCRIPT_DIR, 'Output', 'Diff') + compare_script = os.path.join(SCRIPT_DIR, 'compare_images.py') + + if not os.path.exists(manifest_path): + print(f'ERROR: Manifest not found: {manifest_path}', file=sys.stderr) + sys.exit(1) + + with open(manifest_path) as f: + manifest = json.load(f) + + tests = manifest.get('tests', []) + default_frames = manifest.get('defaultFrames', [1, 10, 30, 60]) + + all_results = [] + passed_count = 0 + total_frames = 0 + failed_frames = 0 + + for test in tests: + name = test['name'] + frames = sorted(test.get('frames', default_frames)) + + print(f'\n=== {name} ===') + test_pass = True + + for frame in frames: + frame_str = f'{frame:04d}' + ref_png = os.path.join(d3d11_dir, name, f'frame_{frame_str}.png') + vk_png = os.path.join(vulkan_dir, name, f'frame_{frame_str}.png') + diff_png = os.path.join(diff_dir, 'd3d11_vs_vulkan', name, f'frame_{frame_str}_diff.png') + + total_frames += 1 + + if not os.path.exists(ref_png): + print(f' Frame {frame}: [SKIP] missing D3D11 reference: {ref_png}') + continue + if not os.path.exists(vk_png): + print(f' Frame {frame}: [SKIP] missing Vulkan image: {vk_png}') + continue + + os.makedirs(os.path.dirname(diff_png), exist_ok=True) + cmd = [ + sys.executable, compare_script, + ref_png, vk_png, + '--diff', diff_png, + '--threshold', str(args.threshold), + ] + result = subprocess.run(cmd, capture_output=True, text=True) + try: + cmp = json.loads(result.stdout) + except Exception: + cmp = {'pass': False, 'error': result.stderr[:300] if result.stderr else '(no output)'} + + ok = cmp.get('pass', False) + if not ok: + test_pass = False + failed_frames += 1 + + status = 'PASS' if ok else 'FAIL' + rmse = cmp.get('rmse', '?') + mismatch = cmp.get('mismatchCount', '?') + print(f' Frame {frame}: [{status}] rmse={rmse} mismatch={mismatch}px') + + if test_pass: + passed_count += 1 + print(f" {name}: [{'PASS' if test_pass else 'FAIL'}]") + all_results.append({'name': name, 'pass': test_pass}) + + overall = passed_count == len(tests) + print(f'\n{"=" * 40}') + print(f" OVERALL: {'PASS' if overall else 'FAIL'} ({passed_count}/{len(tests)} tests)") + if failed_frames > 0: + print(f" Failed frames: {failed_frames}/{total_frames}") + print(f'{"=" * 40}') + sys.exit(0 if overall else 1) + + +if __name__ == '__main__': + main() diff --git a/Tests/VisualRegression/update_reference.py b/Tests/VisualRegression/update_reference.py new file mode 100644 index 00000000..22af5d81 --- /dev/null +++ b/Tests/VisualRegression/update_reference.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +""" +update_reference.py - Refresh reference images from latest captures. + +Run this after making Vulkan renderer changes and verifying correctness. +Copies PNG captures from Output/Captures/ to Reference/ for all tests +listed in TestManifest.json. + +Usage: + update_reference.py [--renderer d3d11|vulkan|both] + [--captures-dir Output/Captures] + [--reference-dir Reference] + [--manifest TestManifest.json] + +Typical workflow: + 1. Make Vulkan code changes + 2. Rebuild (build_tests.ps1) + 3. Run captures (run_all.py) + 4. Verify results look correct (inspect Output/Captures/) + 5. Run: python update_reference.py --renderer vulkan + 6. Commit updated Reference/vulkan/ PNGs +""" + +import sys +import os +import shutil +import json +import argparse + +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) + + +def main(): + ap = argparse.ArgumentParser(description='Update reference images from captures') + ap.add_argument('--renderer', default='both', choices=['d3d11', 'vulkan', 'both'], + help='Which renderer reference to update (default: both)') + ap.add_argument('--captures-dir', default='', + help='Captures directory (default: Output/Captures)') + ap.add_argument('--reference-dir', default='', + help='Reference directory (default: Reference)') + ap.add_argument('--manifest', default='', + help='Path to TestManifest.json') + args = ap.parse_args() + + manifest_path = args.manifest or os.path.join(SCRIPT_DIR, 'TestManifest.json') + captures_dir = args.captures_dir or os.path.join(SCRIPT_DIR, 'Output', 'Captures') + reference_dir = args.reference_dir or os.path.join(SCRIPT_DIR, 'Reference') + + with open(manifest_path) as f: + manifest = json.load(f) + + tests = manifest.get('tests', []) + default_frames = manifest.get('defaultFrames', [1, 10, 30, 60]) + + renderers = ['d3d11', 'vulkan'] if args.renderer == 'both' else [args.renderer] + + total_copied = 0 + total_missing = 0 + + for renderer in renderers: + print(f'\n=== Updating {renderer} reference ===') + for test in tests: + name = test['name'] + frames = sorted(test.get('frames', default_frames)) + + src_dir = os.path.join(captures_dir, renderer, name) + dst_dir = os.path.join(reference_dir, renderer, name) + + if not os.path.isdir(src_dir): + print(f' [SKIP] {name}: capture dir not found: {src_dir}') + total_missing += 1 + continue + + os.makedirs(dst_dir, exist_ok=True) + copied = 0 + for frame in frames: + png_name = f'frame_{frame:04d}.png' + src = os.path.join(src_dir, png_name) + dst = os.path.join(dst_dir, png_name) + if os.path.exists(src): + shutil.copy2(src, dst) + copied += 1 + else: + print(f' [WARN] {name}: missing {png_name}') + total_missing += 1 + + total_copied += copied + + print(f'\nDone: {total_copied} files copied, {total_missing} missing') + if total_missing > 0: + print('Run run_all.py first to generate captures, then retry.') + sys.exit(1) + + +if __name__ == '__main__': + main()