Chuyển đến nội dung

Shader dialect

Một switch phải tự bật, dành cho đúng một trường hợp hẹp: chạy persona Windows trên máy host Linux, khi mà nếu không có nó, mã nguồn shader đã được dịch và chuỗi renderer sẽ chỉ ra hai backend đồ họa khác nhau.

Chỗ không khớp

WEBGL_debug_shaders.getTranslatedShaderSource() trả về bất cứ thứ gì mà backend đang hoạt động của ANGLE tạo ra. Persona Windows khai báo renderer Direct3D11, nhưng trên máy host Linux, backend Vulkan lại trả về một bản dump SPIR-V. Hai giá trị nằm ngay cạnh nhau, nên muốn đọc ra mâu thuẫn thì không cần dữ liệu tham chiếu hay baseline thống kê nào — trang chỉ việc so sánh hai giá trị:

javascript
const gl = document.createElement("canvas").getContext("webgl");
const info = gl.getExtension("WEBGL_debug_renderer_info");
gl.getParameter(info.UNMASKED_RENDERER_WEBGL);
// "ANGLE (Intel, Intel(R) UHD Graphics 770 (0x0000A780) Direct3D11 vs_5_0 ps_5_0, D3D11)"

const dbg = gl.getExtension("WEBGL_debug_shaders");
dbg.getTranslatedShaderSource(vertexShader);
// on Windows: "// INITIAL HLSL BEGIN ... #pragma warning( disable: 3081 ..."
// on Linux:   "Outputs: gl_Position ... Paste the following SPIR-V binary ..."   <- contradicts the renderer

Điều này chỉ xảy ra khi hệ điều hành của persona khác với của máy host. Persona có hệ điều hành trùng với máy host vốn đã tự nhất quán và không cần gì thêm ở đây. Tùy chọn này chỉ xử lý trường hợp persona Windows trên máy host không phải Windows; chiều ngược lại — persona Linux hoặc macOS trên máy host Windows — không được hỗ trợ, nên trong trường hợp đó hãy chọn persona khớp với máy host.

Bật tính năng

Truyền shader_dialect (shaderDialect / ShaderDialect) khi khởi chạy. Engine sẽ dịch lại shader sang HLSL chỉ riêng cho truy vấn đó; kết quả giống đến từng byte với những gì một bản build Windows báo về.

python
from clearcote import launch_persistent_context

ctx = launch_persistent_context("./profile", platform="windows", shader_dialect="hlsl")
javascript
import { launchPersistentContext } from "clearcote";

const ctx = await launchPersistentContext("./profile", { platform: "windows", shaderDialect: "hlsl" });
csharp
using Clearcote;

var ctx = await Clearcote.Clearcote.LaunchPersistentContextAsync("./profile", new LaunchOptions
{
    Platform = "windows",
    ShaderDialect = "hlsl",
});

Docker image chính thức tự bật tính năng này với CC_PLATFORM=windows khi container chạy bản build có giấy phép (đã đặt CLEARCOTE_LICENSE_KEY); ghi đè bằng CC_SHADER_DIALECT=hlsl hoặc =0. Với bất kỳ cách chạy nào khác, hãy đặt biến môi trường trong môi trường của trình duyệt — đó chính là thứ mà tùy chọn SDK đặt ở bên dưới:

bash
CLEARCOTE_SHADER_DIALECT=hlsl

Giá trị này nằm trong biến môi trường thay vì một flag dòng lệnh vì đoạn code này chạy trong GPU process, nơi không nhận các switch fingerprint.

Vì sao mặc định tắt

Việc dịch lại đi theo một code path khác với code path đã render. Một shader được backend thật chấp nhận nhưng bị trình dịch HLSL từ chối sẽ quay về dialect thật cho riêng shader đó — khiến chỗ không khớp xuất hiện trở lại, nhưng chỉ với shader đó. Mọi mặt khác của tùy chọn này đều được thiết kế thận trọng một cách có chủ đích:

  • Không ảnh hưởng đến việc render. Backend thật vẫn compile và vẽ shader; chỉ có truy vấn qua debug extension là thay đổi. Một lần vẽ WebGL kèm readback pixel cho ra hash giống hệt nhau dù bật hay tắt tùy chọn.
  • Không có tác dụng trên Windows. Nếu backend đang hoạt động vốn đã sinh ra HLSL, tùy chọn này không làm gì cả, nên máy host Windows không bị ảnh hưởng kể cả khi đã đặt biến.
  • Khi lỗi thì trả về giá trị thật. Mọi lỗi khi dịch đều trả về đầu ra thật của backend chứ không phải một kết quả rỗng hay bịa ra.
  • SDK chỉ chấp nhận "hlsl" và từ chối mọi giá trị khác — một lỗi gõ nhầm âm thầm không có tác dụng gì còn tệ hơn một lỗi được báo ra. Nếu tự đặt biến, giá trị phải chính xác là hlsl (chữ thường); engine bỏ qua mọi giá trị khác.

Yêu cầu

Bản build có giấy phép (Miễn phí với GitHub hoặc Pro), 151 r15 trở lên. Bản build mở và các binary cũ hơn sẽ bỏ qua biến này và vẫn báo dialect thật của chúng, vì vậy hãy truyền khóa giấy phép (license_key / CLEARCOTE_LICENSE_KEY) để các ví dụ ở trên có tác dụng. Xem cơ chế phát hiện hoạt động ra sao để hiểu vì sao khớp với nền tảng được khai báo lại tốt hơn trả về một giá trị trung lập thứ ba, và triển khai để biết cách chạy engine có giấy phép trong container.