| author | |
| committer | |
| log | e2e75774748591fb44bfc905080e7a14008d4ec3 |
| tree | 30cd3f778609f19711a6900433c3482f32a9a378 |
| parent | 78ad866dd1fc49cb826215002274991201cbb89e |
2 files changed, 55 insertions(+), 16 deletions(-)
lib/std/gpu.zig+10-5| ... | @@ -80,7 +80,8 @@ pub fn fragmentDepth(comptime ptr: *addrspace(.output) f32) void { | ... | @@ -80,7 +80,8 @@ pub fn fragmentDepth(comptime ptr: *addrspace(.output) f32) void { |
| 80 | /// Forms the main linkage for `input` and `output` address spaces. | 80 | /// Forms the main linkage for `input` and `output` address spaces. |
| 81 | /// `ptr` must be a reference to variable or struct field. | 81 | /// `ptr` must be a reference to variable or struct field. |
| 82 | pub fn location(comptime ptr: anytype, comptime loc: u32) void { | 82 | pub fn location(comptime ptr: anytype, comptime loc: u32) void { |
| 83 | asm volatile ("OpDecorate %ptr Location $loc" | 83 | asm volatile ( |
| 84 | \\OpDecorate %ptr Location $loc | ||
| 84 | : | 85 | : |
| 85 | : [ptr] "" (ptr), | 86 | : [ptr] "" (ptr), |
| 86 | [loc] "c" (loc), | 87 | [loc] "c" (loc), |
| ... | @@ -110,7 +111,8 @@ pub const Origin = enum(u32) { | ... | @@ -110,7 +111,8 @@ pub const Origin = enum(u32) { |
| 110 | /// The coordinates appear to originate in the specified `origin`. | 111 | /// The coordinates appear to originate in the specified `origin`. |
| 111 | /// Only valid with the `Fragment` calling convention. | 112 | /// Only valid with the `Fragment` calling convention. |
| 112 | pub fn fragmentOrigin(comptime entry_point: anytype, comptime origin: Origin) void { | 113 | pub fn fragmentOrigin(comptime entry_point: anytype, comptime origin: Origin) void { |
| 113 | asm volatile ("OpExecutionMode %entry_point $origin" | 114 | asm volatile ( |
| 115 | \\OpExecutionMode %entry_point $origin | ||
| 114 | : | 116 | : |
| 115 | : [entry_point] "" (entry_point), | 117 | : [entry_point] "" (entry_point), |
| 116 | [origin] "c" (@intFromEnum(origin)), | 118 | [origin] "c" (@intFromEnum(origin)), |
| ... | @@ -137,7 +139,8 @@ pub const DepthMode = enum(u32) { | ... | @@ -137,7 +139,8 @@ pub const DepthMode = enum(u32) { |
| 137 | 139 | ||
| 138 | /// Only valid with the `Fragment` calling convention. | 140 | /// Only valid with the `Fragment` calling convention. |
| 139 | pub fn depthMode(comptime entry_point: anytype, comptime mode: DepthMode) void { | 141 | pub fn depthMode(comptime entry_point: anytype, comptime mode: DepthMode) void { |
| 140 | asm volatile ("OpExecutionMode %entry_point $mode" | 142 | asm volatile ( |
| 143 | \\OpExecutionMode %entry_point $mode | ||
| 141 | : | 144 | : |
| 142 | : [entry_point] "" (entry_point), | 145 | : [entry_point] "" (entry_point), |
| 143 | [mode] "c" (mode), | 146 | [mode] "c" (mode), |
| ... | @@ -147,7 +150,8 @@ pub fn depthMode(comptime entry_point: anytype, comptime mode: DepthMode) void { | ... | @@ -147,7 +150,8 @@ pub fn depthMode(comptime entry_point: anytype, comptime mode: DepthMode) void { |
| 147 | /// Indicates the workgroup size in the `x`, `y`, and `z` dimensions. | 150 | /// Indicates the workgroup size in the `x`, `y`, and `z` dimensions. |
| 148 | /// Only valid with the `GLCompute` or `Kernel` calling conventions. | 151 | /// Only valid with the `GLCompute` or `Kernel` calling conventions. |
| 149 | pub fn workgroupSize(comptime entry_point: anytype, comptime size: @Vector(3, u32)) void { | 152 | pub fn workgroupSize(comptime entry_point: anytype, comptime size: @Vector(3, u32)) void { |
| 150 | asm volatile ("OpExecutionMode %entry_point LocalSize %x %y %z" | 153 | asm volatile ( |
| 154 | \\OpExecutionMode %entry_point LocalSize %x %y %z | ||
| 151 | : | 155 | : |
| 152 | : [entry_point] "" (entry_point), | 156 | : [entry_point] "" (entry_point), |
| 153 | [x] "c" (size[0]), | 157 | [x] "c" (size[0]), |
| ... | @@ -159,7 +163,8 @@ pub fn workgroupSize(comptime entry_point: anytype, comptime size: @Vector(3, u3 | ... | @@ -159,7 +163,8 @@ pub fn workgroupSize(comptime entry_point: anytype, comptime size: @Vector(3, u3 |
| 159 | /// A hint to the client, which indicates the workgroup size in the `x`, `y`, and `z` dimensions. | 163 | /// A hint to the client, which indicates the workgroup size in the `x`, `y`, and `z` dimensions. |
| 160 | /// Only valid with the `GLCompute` or `Kernel` calling conventions. | 164 | /// Only valid with the `GLCompute` or `Kernel` calling conventions. |
| 161 | pub fn workgroupSizeHint(comptime entry_point: anytype, comptime size: @Vector(3, u32)) void { | 165 | pub fn workgroupSizeHint(comptime entry_point: anytype, comptime size: @Vector(3, u32)) void { |
| 162 | asm volatile ("OpExecutionMode %entry_point LocalSizeHint %x %y %z" | 166 | asm volatile ( |
| 167 | \\OpExecutionMode %entry_point LocalSizeHint %x %y %z | ||
| 163 | : | 168 | : |
| 164 | : [entry_point] "" (entry_point), | 169 | : [entry_point] "" (entry_point), |
| 165 | [x] "c" (size[0]), | 170 | [x] "c" (size[0]), |
src/codegen/spirv/Assembler.zig+45-11| ... | @@ -368,6 +368,40 @@ fn processTypeInstruction(self: *Assembler) !AsmValue { | ... | @@ -368,6 +368,40 @@ fn processTypeInstruction(self: *Assembler) !AsmValue { |
| 368 | }); | 368 | }); |
| 369 | break :blk result_id; | 369 | break :blk result_id; |
| 370 | }, | 370 | }, |
| 371 | .OpTypeStruct => blk: { | ||
| 372 | const ids = try self.gpa.alloc(IdRef, operands[1..].len); | ||
| 373 | defer self.gpa.free(ids); | ||
| 374 | for (operands[1..], ids) |op, *id| id.* = try self.resolveRefId(op.ref_id); | ||
| 375 | const result_id = self.spv.allocId(); | ||
| 376 | try self.spv.structType(result_id, ids, null); | ||
| 377 | break :blk result_id; | ||
| 378 | }, | ||
| 379 | .OpTypeImage => blk: { | ||
| 380 | const sampled_type = try self.resolveRefId(operands[1].ref_id); | ||
| 381 | const result_id = self.spv.allocId(); | ||
| 382 | try section.emit(self.gpa, .OpTypeImage, .{ | ||
| 383 | .id_result = result_id, | ||
| 384 | .sampled_type = sampled_type, | ||
| 385 | .dim = @enumFromInt(operands[2].value), | ||
| 386 | .depth = operands[3].literal32, | ||
| 387 | .arrayed = operands[4].literal32, | ||
| 388 | .ms = operands[5].literal32, | ||
| 389 | .sampled = operands[6].literal32, | ||
| 390 | .image_format = @enumFromInt(operands[7].value), | ||
| 391 | }); | ||
| 392 | break :blk result_id; | ||
| 393 | }, | ||
| 394 | .OpTypeSampler => blk: { | ||
| 395 | const result_id = self.spv.allocId(); | ||
| 396 | try section.emit(self.gpa, .OpTypeSampler, .{ .id_result = result_id }); | ||
| 397 | break :blk result_id; | ||
| 398 | }, | ||
| 399 | .OpTypeSampledImage => blk: { | ||
| 400 | const image_type = try self.resolveRefId(operands[1].ref_id); | ||
| 401 | const result_id = self.spv.allocId(); | ||
| 402 | try section.emit(self.gpa, .OpTypeSampledImage, .{ .id_result = result_id, .image_type = image_type }); | ||
| 403 | break :blk result_id; | ||
| 404 | }, | ||
| 371 | .OpTypeFunction => blk: { | 405 | .OpTypeFunction => blk: { |
| 372 | const param_operands = operands[2..]; | 406 | const param_operands = operands[2..]; |
| 373 | const return_type = try self.resolveRefId(operands[1].ref_id); | 407 | const return_type = try self.resolveRefId(operands[1].ref_id); |
| ... | @@ -406,18 +440,18 @@ fn processGenericInstruction(self: *Assembler) !?AsmValue { | ... | @@ -406,18 +440,18 @@ fn processGenericInstruction(self: *Assembler) !?AsmValue { |
| 406 | else => switch (self.inst.opcode) { | 440 | else => switch (self.inst.opcode) { |
| 407 | .OpEntryPoint => unreachable, | 441 | .OpEntryPoint => unreachable, |
| 408 | .OpExecutionMode, .OpExecutionModeId => &self.spv.sections.execution_modes, | 442 | .OpExecutionMode, .OpExecutionModeId => &self.spv.sections.execution_modes, |
| 409 | .OpVariable => switch (@as(spec.StorageClass, @enumFromInt(operands[2].value))) { | 443 | .OpVariable => section: { |
| 410 | .Function => &self.func.prologue, | 444 | const storage_class: spec.StorageClass = @enumFromInt(operands[2].value); |
| 411 | .Input, .Output => section: { | 445 | if (storage_class == .Function) break :section &self.func.prologue; |
| 412 | maybe_spv_decl_index = try self.spv.allocDecl(.global); | 446 | maybe_spv_decl_index = try self.spv.allocDecl(.global); |
| 413 | try self.func.decl_deps.put(self.spv.gpa, maybe_spv_decl_index.?, {}); | 447 | if (self.spv.version.minor < 4 and storage_class != .Input and storage_class != .Output) { |
| 414 | // TODO: In theory this can be non-empty if there is an initializer which depends on another global... | 448 | // Before version 1.4, the interface’s storage classes are limited to the Input and Output |
| 415 | try self.spv.declareDeclDeps(maybe_spv_decl_index.?, &.{}); | ||
| 416 | break :section &self.spv.sections.types_globals_constants; | 449 | break :section &self.spv.sections.types_globals_constants; |
| 417 | }, | 450 | } |
| 418 | // These don't need to be marked in the dependency system. | 451 | try self.func.decl_deps.put(self.spv.gpa, maybe_spv_decl_index.?, {}); |
| 419 | // Probably we should add them anyway, then filter out PushConstant globals. | 452 | // TODO: In theory this can be non-empty if there is an initializer which depends on another global... |
| 420 | else => &self.spv.sections.types_globals_constants, | 453 | try self.spv.declareDeclDeps(maybe_spv_decl_index.?, &.{}); |
| 454 | break :section &self.spv.sections.types_globals_constants; | ||
| 421 | }, | 455 | }, |
| 422 | // Default case - to be worked out further. | 456 | // Default case - to be worked out further. |
| 423 | else => &self.func.body, | 457 | else => &self.func.body, |