mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-23 04:16:57 +02:00
Fix Windows Clang SPIR-V serialization with typed operands
This commit is contained in:
@@ -45,28 +45,28 @@ uint32_t EmitBuiltinU32(EmitterState& state, IR::StageInputKind kind, uint32_t c
|
||||
if (kind == IR::StageInputKind::FrontFacing) {
|
||||
const auto value = state.builder.AllocateId();
|
||||
const auto bits = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpLoad, TypeBool(state), value, variable});
|
||||
state.builder.AddFunction({spv::OpSelect, TypeU32(state), bits, value,
|
||||
ConstantU32(state, 1), ConstantU32(state, 0)});
|
||||
state.builder.AddFunction(spv::OpLoad, TypeBool(state), value, variable);
|
||||
state.builder.AddFunction(spv::OpSelect, TypeU32(state), bits, value, ConstantU32(state, 1),
|
||||
ConstantU32(state, 0));
|
||||
return bits;
|
||||
}
|
||||
if (kind == IR::StageInputKind::VertexIndex || kind == IR::StageInputKind::InstanceIndex ||
|
||||
kind == IR::StageInputKind::Layer || kind == IR::StageInputKind::SampleId) {
|
||||
const auto value = state.builder.AllocateId();
|
||||
const auto bits = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpLoad, TypeI32(state), value, variable});
|
||||
state.builder.AddFunction({spv::OpBitcast, TypeU32(state), bits, value});
|
||||
state.builder.AddFunction(spv::OpLoad, TypeI32(state), value, variable);
|
||||
state.builder.AddFunction(spv::OpBitcast, TypeU32(state), bits, value);
|
||||
return bits;
|
||||
}
|
||||
if (kind == IR::StageInputKind::FragCoord) {
|
||||
const auto pointer = state.builder.AllocateId();
|
||||
const auto value = state.builder.AllocateId();
|
||||
const auto bits = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpAccessChain,
|
||||
TypePointer(state, spv::StorageClassInput, TypeF32(state)),
|
||||
pointer, variable, ConstantU32(state, component)});
|
||||
state.builder.AddFunction({spv::OpLoad, TypeF32(state), value, pointer});
|
||||
state.builder.AddFunction({spv::OpBitcast, TypeU32(state), bits, value});
|
||||
state.builder.AddFunction(spv::OpAccessChain,
|
||||
TypePointer(state, spv::StorageClassInput, TypeF32(state)),
|
||||
pointer, variable, ConstantU32(state, component));
|
||||
state.builder.AddFunction(spv::OpLoad, TypeF32(state), value, pointer);
|
||||
state.builder.AddFunction(spv::OpBitcast, TypeU32(state), bits, value);
|
||||
return bits;
|
||||
}
|
||||
if (kind == IR::StageInputKind::BaryCoordSmooth ||
|
||||
@@ -74,11 +74,11 @@ uint32_t EmitBuiltinU32(EmitterState& state, IR::StageInputKind kind, uint32_t c
|
||||
const auto pointer = state.builder.AllocateId();
|
||||
const auto value = state.builder.AllocateId();
|
||||
const auto bits = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpAccessChain,
|
||||
TypePointer(state, spv::StorageClassInput, TypeF32(state)),
|
||||
pointer, variable, ConstantU32(state, component + 1u)});
|
||||
state.builder.AddFunction({spv::OpLoad, TypeF32(state), value, pointer});
|
||||
state.builder.AddFunction({spv::OpBitcast, TypeU32(state), bits, value});
|
||||
state.builder.AddFunction(spv::OpAccessChain,
|
||||
TypePointer(state, spv::StorageClassInput, TypeF32(state)),
|
||||
pointer, variable, ConstantU32(state, component + 1u));
|
||||
state.builder.AddFunction(spv::OpLoad, TypeF32(state), value, pointer);
|
||||
state.builder.AddFunction(spv::OpBitcast, TypeU32(state), bits, value);
|
||||
return bits;
|
||||
}
|
||||
return EmitInputComponentU32(state, kind, component);
|
||||
@@ -99,37 +99,37 @@ uint32_t EmitDppWriteCondition(ValueEmitContext& ctx, const IR::DppMoveFlags& fl
|
||||
const auto bank_ok = state.builder.AllocateId();
|
||||
const auto row_ok = state.builder.AllocateId();
|
||||
const auto masks_ok = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{spv::OpShiftRightLogical, TypeU32(state), bank_shift, lane, ConstantU32(state, 2)});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpShiftRightLogical, TypeU32(state), row_shift, lane, ConstantU32(state, 4)});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpBitwiseAnd, TypeU32(state), bank, bank_shift, ConstantU32(state, 3)});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpBitwiseAnd, TypeU32(state), row, row_shift, ConstantU32(state, 3)});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpShiftLeftLogical, TypeU32(state), bank_bit, ConstantU32(state, 1), bank});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpShiftLeftLogical, TypeU32(state), row_bit, ConstantU32(state, 1), row});
|
||||
state.builder.AddFunction({spv::OpBitwiseAnd, TypeU32(state), bank_hit,
|
||||
ConstantU32(state, flags.bank_mask), bank_bit});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpBitwiseAnd, TypeU32(state), row_hit, ConstantU32(state, flags.row_mask), row_bit});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpINotEqual, TypeBool(state), bank_ok, bank_hit, ConstantU32(state, 0)});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpINotEqual, TypeBool(state), row_ok, row_hit, ConstantU32(state, 0)});
|
||||
state.builder.AddFunction({spv::OpLogicalAnd, TypeBool(state), masks_ok, bank_ok, row_ok});
|
||||
state.builder.AddFunction(spv::OpShiftRightLogical, TypeU32(state), bank_shift, lane,
|
||||
ConstantU32(state, 2));
|
||||
state.builder.AddFunction(spv::OpShiftRightLogical, TypeU32(state), row_shift, lane,
|
||||
ConstantU32(state, 4));
|
||||
state.builder.AddFunction(spv::OpBitwiseAnd, TypeU32(state), bank, bank_shift,
|
||||
ConstantU32(state, 3));
|
||||
state.builder.AddFunction(spv::OpBitwiseAnd, TypeU32(state), row, row_shift,
|
||||
ConstantU32(state, 3));
|
||||
state.builder.AddFunction(spv::OpShiftLeftLogical, TypeU32(state), bank_bit,
|
||||
ConstantU32(state, 1), bank);
|
||||
state.builder.AddFunction(spv::OpShiftLeftLogical, TypeU32(state), row_bit,
|
||||
ConstantU32(state, 1), row);
|
||||
state.builder.AddFunction(spv::OpBitwiseAnd, TypeU32(state), bank_hit,
|
||||
ConstantU32(state, flags.bank_mask), bank_bit);
|
||||
state.builder.AddFunction(spv::OpBitwiseAnd, TypeU32(state), row_hit,
|
||||
ConstantU32(state, flags.row_mask), row_bit);
|
||||
state.builder.AddFunction(spv::OpINotEqual, TypeBool(state), bank_ok, bank_hit,
|
||||
ConstantU32(state, 0));
|
||||
state.builder.AddFunction(spv::OpINotEqual, TypeBool(state), row_ok, row_hit,
|
||||
ConstantU32(state, 0));
|
||||
state.builder.AddFunction(spv::OpLogicalAnd, TypeBool(state), masks_ok, bank_ok, row_ok);
|
||||
uint32_t writable = masks_ok;
|
||||
if (!flags.bound_control) {
|
||||
const auto target = EmitDppTargetLane(state, flags.control);
|
||||
const auto bounded = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{spv::OpLogicalAnd, TypeBool(state), bounded, writable, target.valid});
|
||||
state.builder.AddFunction(spv::OpLogicalAnd, TypeBool(state), bounded, writable,
|
||||
target.valid);
|
||||
writable = bounded;
|
||||
}
|
||||
const auto result = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpLogicalAnd, TypeBool(state), result, exec, writable});
|
||||
state.builder.AddFunction(spv::OpLogicalAnd, TypeBool(state), result, exec, writable);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -144,11 +144,10 @@ uint32_t EmitAttribute(EmitterState& state, uint32_t attr, uint32_t chan) {
|
||||
const auto load_per_vertex = [&](uint32_t vertex) {
|
||||
const auto pointer = state.builder.AllocateId();
|
||||
const auto value = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpAccessChain,
|
||||
TypePointer(state, spv::StorageClassInput, TypeF32(state)),
|
||||
pointer, input->variable_id, ConstantU32(state, vertex),
|
||||
ConstantU32(state, chan & 3u)});
|
||||
state.builder.AddFunction({spv::OpLoad, TypeF32(state), value, pointer});
|
||||
state.builder.AddFunction(
|
||||
spv::OpAccessChain, TypePointer(state, spv::StorageClassInput, TypeF32(state)), pointer,
|
||||
input->variable_id, ConstantU32(state, vertex), ConstantU32(state, chan & 3u));
|
||||
state.builder.AddFunction(spv::OpLoad, TypeF32(state), value, pointer);
|
||||
return value;
|
||||
};
|
||||
if (input->per_vertex) {
|
||||
@@ -161,31 +160,31 @@ uint32_t EmitAttribute(EmitterState& state, uint32_t attr, uint32_t chan) {
|
||||
const auto pointer = state.builder.AllocateId();
|
||||
const auto weight = state.builder.AllocateId();
|
||||
const auto product = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpAccessChain,
|
||||
TypePointer(state, spv::StorageClassInput, TypeF32(state)),
|
||||
pointer, barycentric, ConstantU32(state, vertex)});
|
||||
state.builder.AddFunction({spv::OpLoad, TypeF32(state), weight, pointer});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpFMul, TypeF32(state), product, load_per_vertex(vertex), weight});
|
||||
state.builder.AddFunction(spv::OpAccessChain,
|
||||
TypePointer(state, spv::StorageClassInput, TypeF32(state)),
|
||||
pointer, barycentric, ConstantU32(state, vertex));
|
||||
state.builder.AddFunction(spv::OpLoad, TypeF32(state), weight, pointer);
|
||||
state.builder.AddFunction(spv::OpFMul, TypeF32(state), product, load_per_vertex(vertex),
|
||||
weight);
|
||||
if (vertex == 0u) {
|
||||
sum = product;
|
||||
} else {
|
||||
const auto next = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpFAdd, TypeF32(state), next, sum, product});
|
||||
state.builder.AddFunction(spv::OpFAdd, TypeF32(state), next, sum, product);
|
||||
sum = next;
|
||||
}
|
||||
}
|
||||
const auto bits = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpBitcast, TypeU32(state), bits, sum});
|
||||
state.builder.AddFunction(spv::OpBitcast, TypeU32(state), bits, sum);
|
||||
return bits;
|
||||
}
|
||||
const auto vector = state.builder.AllocateId();
|
||||
const auto component = state.builder.AllocateId();
|
||||
const auto bits = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpLoad, TypeF32Vector(state, 4), vector, input->variable_id});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpCompositeExtract, TypeF32(state), component, vector, chan & 3u});
|
||||
state.builder.AddFunction({spv::OpBitcast, TypeU32(state), bits, component});
|
||||
state.builder.AddFunction(spv::OpLoad, TypeF32Vector(state, 4), vector, input->variable_id);
|
||||
state.builder.AddFunction(spv::OpCompositeExtract, TypeF32(state), component, vector,
|
||||
chan & 3u);
|
||||
state.builder.AddFunction(spv::OpBitcast, TypeU32(state), bits, component);
|
||||
return bits;
|
||||
}
|
||||
|
||||
@@ -199,11 +198,10 @@ uint32_t EmitInterpolationParameter(ValueEmitContext& ctx, uint32_t attr, uint32
|
||||
const auto load_vertex = [&](uint32_t vertex) {
|
||||
const auto pointer = state.builder.AllocateId();
|
||||
const auto value = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpAccessChain,
|
||||
TypePointer(state, spv::StorageClassInput, TypeF32(state)),
|
||||
pointer, input->variable_id, ConstantU32(state, vertex),
|
||||
ConstantU32(state, chan & 3u)});
|
||||
state.builder.AddFunction({spv::OpLoad, TypeF32(state), value, pointer});
|
||||
state.builder.AddFunction(
|
||||
spv::OpAccessChain, TypePointer(state, spv::StorageClassInput, TypeF32(state)), pointer,
|
||||
input->variable_id, ConstantU32(state, vertex), ConstantU32(state, chan & 3u));
|
||||
state.builder.AddFunction(spv::OpLoad, TypeF32(state), value, pointer);
|
||||
return value;
|
||||
};
|
||||
|
||||
@@ -211,11 +209,11 @@ uint32_t EmitInterpolationParameter(ValueEmitContext& ctx, uint32_t attr, uint32
|
||||
uint32_t value = load_vertex(selected_vertex);
|
||||
if (!PixelParameterIsCustom(state, attr) && mode < 2u) {
|
||||
const auto delta = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpFSub, TypeF32(state), delta, value, load_vertex(0)});
|
||||
state.builder.AddFunction(spv::OpFSub, TypeF32(state), delta, value, load_vertex(0));
|
||||
value = delta;
|
||||
}
|
||||
const auto bits = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpBitcast, TypeU32(state), bits, value});
|
||||
state.builder.AddFunction(spv::OpBitcast, TypeU32(state), bits, value);
|
||||
return bits;
|
||||
}
|
||||
|
||||
@@ -229,8 +227,8 @@ uint32_t MrtOutputMode(const EmitterState& state, const IR::ExportInfo& exp) {
|
||||
|
||||
uint32_t ExportRawComponent(ValueEmitContext& ctx, uint32_t vector, uint32_t component) {
|
||||
const auto value = ctx.state.builder.AllocateId();
|
||||
ctx.state.builder.AddFunction(
|
||||
{spv::OpCompositeExtract, TypeU32(ctx.state), value, vector, component});
|
||||
ctx.state.builder.AddFunction(spv::OpCompositeExtract, TypeU32(ctx.state), value, vector,
|
||||
component);
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -248,22 +246,21 @@ uint32_t ExportVector(ValueEmitContext& ctx, uint32_t data, const IR::ExportInfo
|
||||
}
|
||||
const auto packed = state.builder.AllocateId();
|
||||
const auto unpacked = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{spv::OpCompositeExtract, TypeU32(state), packed, data, pair});
|
||||
state.builder.AddFunction({spv::OpExtInst, TypeF32Vector(state, 2), unpacked,
|
||||
GlslStd450(state), unpack, packed});
|
||||
state.builder.AddFunction(spv::OpCompositeExtract, TypeU32(state), packed, data, pair);
|
||||
state.builder.AddFunction(spv::OpExtInst, TypeF32Vector(state, 2), unpacked,
|
||||
GlslStd450(state), unpack, packed);
|
||||
for (uint32_t lane = 0; lane < 2u; lane++) {
|
||||
const auto component = pair * 2u + lane;
|
||||
if (((exp.en >> component) & 1u) != 0u) {
|
||||
f32[component] = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{spv::OpCompositeExtract, TypeF32(state), f32[component], unpacked, lane});
|
||||
state.builder.AddFunction(spv::OpCompositeExtract, TypeF32(state),
|
||||
f32[component], unpacked, lane);
|
||||
}
|
||||
}
|
||||
}
|
||||
const auto vector = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpCompositeConstruct, TypeF32Vector(state, 4), vector,
|
||||
f32[0], f32[1], f32[2], f32[3]});
|
||||
state.builder.AddFunction(spv::OpCompositeConstruct, TypeF32Vector(state, 4), vector,
|
||||
f32[0], f32[1], f32[2], f32[3]);
|
||||
return vector;
|
||||
}
|
||||
uint32_t raw[4] = {
|
||||
@@ -284,9 +281,9 @@ uint32_t ExportVector(ValueEmitContext& ctx, uint32_t data, const IR::ExportInfo
|
||||
continue;
|
||||
}
|
||||
raw[component] = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpBitFieldUExtract, TypeU32(state), raw[component],
|
||||
packed, ConstantU32(state, lane * 16u),
|
||||
ConstantU32(state, 16)});
|
||||
state.builder.AddFunction(spv::OpBitFieldUExtract, TypeU32(state), raw[component],
|
||||
packed, ConstantU32(state, lane * 16u),
|
||||
ConstantU32(state, 16));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -298,18 +295,18 @@ uint32_t ExportVector(ValueEmitContext& ctx, uint32_t data, const IR::ExportInfo
|
||||
}
|
||||
if (uint_output) {
|
||||
const auto vector = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpCompositeConstruct, TypeU32Vector(state, 4), vector,
|
||||
raw[0], raw[1], raw[2], raw[3]});
|
||||
state.builder.AddFunction(spv::OpCompositeConstruct, TypeU32Vector(state, 4), vector,
|
||||
raw[0], raw[1], raw[2], raw[3]);
|
||||
return vector;
|
||||
}
|
||||
uint32_t f32[4] {};
|
||||
for (uint32_t component = 0; component < 4u; component++) {
|
||||
f32[component] = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpBitcast, TypeF32(state), f32[component], raw[component]});
|
||||
state.builder.AddFunction(spv::OpBitcast, TypeF32(state), f32[component], raw[component]);
|
||||
}
|
||||
const auto vector = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpCompositeConstruct, TypeF32Vector(state, 4), vector, f32[0],
|
||||
f32[1], f32[2], f32[3]});
|
||||
state.builder.AddFunction(spv::OpCompositeConstruct, TypeF32Vector(state, 4), vector, f32[0],
|
||||
f32[1], f32[2], f32[3]);
|
||||
return vector;
|
||||
}
|
||||
|
||||
@@ -325,19 +322,19 @@ void EmitAuxPositionExport(ValueEmitContext& ctx, uint32_t data, const IR::Expor
|
||||
const auto raw = ExportRawComponent(ctx, data, component);
|
||||
if (output.layer) {
|
||||
const auto layer = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{spv::OpBitwiseAnd, TypeU32(state), layer, raw, ConstantU32(state, 0x7ffu)});
|
||||
state.builder.AddFunction(spv::OpBitwiseAnd, TypeU32(state), layer, raw,
|
||||
ConstantU32(state, 0x7ffu));
|
||||
const auto pointer = state.program.stage == ShaderType::Mesh
|
||||
? MeshOutputPointer(state, IR::StageOutputKind::Layer)
|
||||
: state.layer_variable;
|
||||
state.builder.AddFunction({spv::OpStore, pointer, layer});
|
||||
state.builder.AddFunction(spv::OpStore, pointer, layer);
|
||||
}
|
||||
if (output.viewport) {
|
||||
// GFX10 MISC.z packs the viewport index in bits 16..19 alongside the layer.
|
||||
const auto viewport = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpBitFieldUExtract, TypeU32(state), viewport, raw,
|
||||
ConstantU32(state, 16), ConstantU32(state, 4)});
|
||||
state.builder.AddFunction({spv::OpStore, state.viewport_index_variable, viewport});
|
||||
state.builder.AddFunction(spv::OpBitFieldUExtract, TypeU32(state), viewport, raw,
|
||||
ConstantU32(state, 16), ConstantU32(state, 4));
|
||||
state.builder.AddFunction(spv::OpStore, state.viewport_index_variable, viewport);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -348,9 +345,9 @@ void EmitAuxPositionExport(ValueEmitContext& ctx, uint32_t data, const IR::Expor
|
||||
|
||||
const auto raw = ExportRawComponent(ctx, data, component);
|
||||
const auto f32 = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpBitcast, TypeF32(state), f32, raw});
|
||||
state.builder.AddFunction(spv::OpBitcast, TypeF32(state), f32, raw);
|
||||
if (output.point_size) {
|
||||
state.builder.AddFunction({spv::OpStore, state.point_size_variable, f32});
|
||||
state.builder.AddFunction(spv::OpStore, state.point_size_variable, f32);
|
||||
continue;
|
||||
}
|
||||
auto StoreDistance = [&](uint32_t variable, uint32_t index) {
|
||||
@@ -358,10 +355,10 @@ void EmitAuxPositionExport(ValueEmitContext& ctx, uint32_t data, const IR::Expor
|
||||
return;
|
||||
}
|
||||
const auto pointer = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpAccessChain,
|
||||
TypePointer(state, spv::StorageClassOutput, TypeF32(state)),
|
||||
pointer, variable, ConstantU32(state, index)});
|
||||
state.builder.AddFunction({spv::OpStore, pointer, f32});
|
||||
state.builder.AddFunction(spv::OpAccessChain,
|
||||
TypePointer(state, spv::StorageClassOutput, TypeF32(state)),
|
||||
pointer, variable, ConstantU32(state, index));
|
||||
state.builder.AddFunction(spv::OpStore, pointer, f32);
|
||||
};
|
||||
StoreDistance(state.clip_distance_variable, output.clip_distance);
|
||||
StoreDistance(state.cull_distance_variable, output.cull_distance);
|
||||
@@ -374,14 +371,14 @@ uint32_t ConvertClipCoordinate(EmitterState& state, uint32_t coordinate, float s
|
||||
const auto biased = state.builder.AllocateId();
|
||||
const auto divided = state.builder.AllocateId();
|
||||
const auto ndc = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{spv::OpFMul, TypeF32(state), window, coordinate, ConstantF32Value(state, scale)});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpFAdd, TypeF32(state), biased, window, ConstantF32Value(state, offset)});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpFDiv, TypeF32(state), divided, biased, ConstantF32Value(state, half_extent)});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpFSub, TypeF32(state), ndc, divided, ConstantF32Value(state, 1.0f)});
|
||||
state.builder.AddFunction(spv::OpFMul, TypeF32(state), window, coordinate,
|
||||
ConstantF32Value(state, scale));
|
||||
state.builder.AddFunction(spv::OpFAdd, TypeF32(state), biased, window,
|
||||
ConstantF32Value(state, offset));
|
||||
state.builder.AddFunction(spv::OpFDiv, TypeF32(state), divided, biased,
|
||||
ConstantF32Value(state, half_extent));
|
||||
state.builder.AddFunction(spv::OpFSub, TypeF32(state), ndc, divided,
|
||||
ConstantF32Value(state, 1.0f));
|
||||
return ndc;
|
||||
}
|
||||
|
||||
@@ -390,16 +387,16 @@ uint32_t ConvertPositionToClipSpace(EmitterState& state, uint32_t position) {
|
||||
uint32_t components[4] {};
|
||||
for (uint32_t i = 0; i < 4; i++) {
|
||||
components[i] = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{spv::OpCompositeExtract, TypeF32(state), components[i], position, i});
|
||||
state.builder.AddFunction(spv::OpCompositeExtract, TypeF32(state), components[i], position,
|
||||
i);
|
||||
}
|
||||
components[0] = ConvertClipCoordinate(state, components[0], transform.scale[0],
|
||||
transform.offset[0], transform.half_extent[0]);
|
||||
components[1] = ConvertClipCoordinate(state, components[1], transform.scale[1],
|
||||
transform.offset[1], transform.half_extent[1]);
|
||||
const auto converted = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpCompositeConstruct, TypeF32Vector(state, 4), converted,
|
||||
components[0], components[1], components[2], components[3]});
|
||||
state.builder.AddFunction(spv::OpCompositeConstruct, TypeF32Vector(state, 4), converted,
|
||||
components[0], components[1], components[2], components[3]);
|
||||
return converted;
|
||||
}
|
||||
|
||||
@@ -411,17 +408,17 @@ uint32_t EmitWqmU64(EmitterState& state, uint32_t value) {
|
||||
const auto merged_two = state.builder.AllocateId();
|
||||
const auto quad_bits = state.builder.AllocateId();
|
||||
const auto result = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpShiftRightLogical, TypeU64(state), shifted_one, value,
|
||||
ConstantU64(state, 0x0000000100000001ull)});
|
||||
state.builder.AddFunction({spv::OpBitwiseOr, TypeU64(state), merged_one, value, shifted_one});
|
||||
state.builder.AddFunction({spv::OpShiftRightLogical, TypeU64(state), shifted_two, merged_one,
|
||||
ConstantU64(state, 0x0000000200000002ull)});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpBitwiseOr, TypeU64(state), merged_two, merged_one, shifted_two});
|
||||
state.builder.AddFunction({spv::OpBitwiseAnd, TypeU64(state), quad_bits, merged_two,
|
||||
ConstantU64(state, 0x1111111111111111ull)});
|
||||
state.builder.AddFunction({spv::OpIMul, TypeU64(state), result, quad_bits,
|
||||
ConstantU64(state, 0x0000000f0000000full)});
|
||||
state.builder.AddFunction(spv::OpShiftRightLogical, TypeU64(state), shifted_one, value,
|
||||
ConstantU64(state, 0x0000000100000001ull));
|
||||
state.builder.AddFunction(spv::OpBitwiseOr, TypeU64(state), merged_one, value, shifted_one);
|
||||
state.builder.AddFunction(spv::OpShiftRightLogical, TypeU64(state), shifted_two, merged_one,
|
||||
ConstantU64(state, 0x0000000200000002ull));
|
||||
state.builder.AddFunction(spv::OpBitwiseOr, TypeU64(state), merged_two, merged_one,
|
||||
shifted_two);
|
||||
state.builder.AddFunction(spv::OpBitwiseAnd, TypeU64(state), quad_bits, merged_two,
|
||||
ConstantU64(state, 0x1111111111111111ull));
|
||||
state.builder.AddFunction(spv::OpIMul, TypeU64(state), result, quad_bits,
|
||||
ConstantU64(state, 0x0000000f0000000full));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -432,9 +429,9 @@ void EmitSetAttribute(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
if (state.program.stage == ShaderType::Pixel && exp.vm && state.requirements.pixel_valid_mask &&
|
||||
state.pixel_valid_mask_variable != 0) {
|
||||
const auto value = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpSelect, TypeU32(state), value, exec,
|
||||
ConstantU32(state, 1), ConstantU32(state, 0)});
|
||||
state.builder.AddFunction({spv::OpStore, state.pixel_valid_mask_variable, value});
|
||||
state.builder.AddFunction(spv::OpSelect, TypeU32(state), value, exec, ConstantU32(state, 1),
|
||||
ConstantU32(state, 0));
|
||||
state.builder.AddFunction(spv::OpStore, state.pixel_valid_mask_variable, value);
|
||||
}
|
||||
if (exp.kind == IR::ExportTargetKind::Null || exp.en == 0u) {
|
||||
return;
|
||||
@@ -443,8 +440,8 @@ void EmitSetAttribute(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
const auto data = ctx.Arg(inst, 0);
|
||||
if (exp.kind == IR::ExportTargetKind::Primitive) {
|
||||
if (state.program.stage == ShaderType::Mesh) {
|
||||
state.builder.AddFunction(
|
||||
{spv::OpStore, MeshPrimitivePointer(state), ExportRawComponent(ctx, data, 0)});
|
||||
state.builder.AddFunction(spv::OpStore, MeshPrimitivePointer(state),
|
||||
ExportRawComponent(ctx, data, 0));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -456,19 +453,18 @@ void EmitSetAttribute(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
if ((exp.en & 1u) != 0u && state.depth_variable != 0) {
|
||||
const auto raw = ExportRawComponent(ctx, data, 0);
|
||||
const auto f32 = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpBitcast, TypeF32(state), f32, raw});
|
||||
state.builder.AddFunction({spv::OpStore, state.depth_variable, f32});
|
||||
state.builder.AddFunction(spv::OpBitcast, TypeF32(state), f32, raw);
|
||||
state.builder.AddFunction(spv::OpStore, state.depth_variable, f32);
|
||||
}
|
||||
if ((exp.en & 4u) != 0u && state.sample_mask_variable != 0) {
|
||||
const auto raw = ExportRawComponent(ctx, data, 2);
|
||||
const auto value = state.builder.AllocateId();
|
||||
const auto pointer = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpBitcast, TypeI32(state), value, raw});
|
||||
state.builder.AddFunction(spv::OpBitcast, TypeI32(state), value, raw);
|
||||
state.builder.AddFunction(
|
||||
{spv::OpAccessChain,
|
||||
TypePointer(state, spv::StorageClassOutput, TypeI32(state)), pointer,
|
||||
state.sample_mask_variable, ConstantU32(state, 0)});
|
||||
state.builder.AddFunction({spv::OpStore, pointer, value});
|
||||
spv::OpAccessChain, TypePointer(state, spv::StorageClassOutput, TypeI32(state)),
|
||||
pointer, state.sample_mask_variable, ConstantU32(state, 0));
|
||||
state.builder.AddFunction(spv::OpStore, pointer, value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -485,9 +481,9 @@ void EmitSetAttribute(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
const auto mapping = state.input_info.pixel->target_export_mapping[exp.index];
|
||||
if (!mapping.IsIdentity()) {
|
||||
const auto mapped = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpVectorShuffle, vector_type, mapped, value, value,
|
||||
mapping.Map(0), mapping.Map(1), mapping.Map(2),
|
||||
mapping.Map(3)});
|
||||
state.builder.AddFunction(spv::OpVectorShuffle, vector_type, mapped, value, value,
|
||||
mapping.Map(0), mapping.Map(1), mapping.Map(2),
|
||||
mapping.Map(3));
|
||||
value = mapped;
|
||||
}
|
||||
}
|
||||
@@ -499,17 +495,17 @@ void EmitSetAttribute(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
const auto kind = exp.kind == IR::ExportTargetKind::Position
|
||||
? IR::StageOutputKind::Position
|
||||
: IR::StageOutputKind::Parameter;
|
||||
state.builder.AddFunction(
|
||||
{spv::OpStore, MeshOutputPointer(state, kind, exp.index), value});
|
||||
state.builder.AddFunction(spv::OpStore, MeshOutputPointer(state, kind, exp.index),
|
||||
value);
|
||||
} else if (exp.kind == IR::ExportTargetKind::Position) {
|
||||
const auto pointer = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{spv::OpAccessChain,
|
||||
TypePointer(state, spv::StorageClassOutput, TypeF32Vector(state, 4)), pointer,
|
||||
variable, ConstantU32(state, 0)});
|
||||
state.builder.AddFunction({spv::OpStore, pointer, value});
|
||||
spv::OpAccessChain,
|
||||
TypePointer(state, spv::StorageClassOutput, TypeF32Vector(state, 4)), pointer,
|
||||
variable, ConstantU32(state, 0));
|
||||
state.builder.AddFunction(spv::OpStore, pointer, value);
|
||||
} else {
|
||||
state.builder.AddFunction({spv::OpStore, variable, value});
|
||||
state.builder.AddFunction(spv::OpStore, variable, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -523,9 +519,9 @@ void EmitVoid(ValueEmitContext&) {}
|
||||
void EmitBarrier(EmitterState& state) {
|
||||
const auto semantics =
|
||||
spv::MemorySemanticsAcquireReleaseMask | spv::MemorySemanticsWorkgroupMemoryMask;
|
||||
state.builder.AddFunction({spv::OpControlBarrier, ConstantU32(state, spv::ScopeWorkgroup),
|
||||
ConstantU32(state, spv::ScopeWorkgroup),
|
||||
ConstantU32(state, semantics)});
|
||||
state.builder.AddFunction(spv::OpControlBarrier, ConstantU32(state, spv::ScopeWorkgroup),
|
||||
ConstantU32(state, spv::ScopeWorkgroup),
|
||||
ConstantU32(state, semantics));
|
||||
}
|
||||
|
||||
uint32_t EmitMeshDrawParameter(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
@@ -536,10 +532,10 @@ uint32_t EmitMeshDrawParameter(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
ctx.Fail(inst, "invalid mesh draw parameter");
|
||||
}
|
||||
const auto pointer = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpAccessChain, TypePushConstantElementPointer(state), pointer,
|
||||
state.push_constant_variable, ConstantU32(state, 0),
|
||||
ConstantU32(state, index)});
|
||||
state.builder.AddFunction({spv::OpLoad, TypeU32(state), result, pointer});
|
||||
state.builder.AddFunction(spv::OpAccessChain, TypePushConstantElementPointer(state), pointer,
|
||||
state.push_constant_variable, ConstantU32(state, 0),
|
||||
ConstantU32(state, index));
|
||||
state.builder.AddFunction(spv::OpLoad, TypeU32(state), result, pointer);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -559,7 +555,7 @@ uint32_t EmitGetBuiltin(ValueEmitContext& ctx, IR::Value kind, IR::Value index)
|
||||
|
||||
uint32_t EmitUndefU1(EmitterState& state, const IR::Inst& inst) {
|
||||
const auto result = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpUndef, TypeId(state, inst.GetType()), result});
|
||||
state.builder.AddFunction(spv::OpUndef, TypeId(state, inst.GetType()), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -574,8 +570,8 @@ uint32_t EmitDppMoveU32(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
const auto ballot = ctx.Ballot(inst.Arg(1));
|
||||
const auto source_active = EmitBallotLaneActiveBool(state, ballot, target.lane);
|
||||
const auto can_fetch = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{spv::OpLogicalAnd, TypeBool(state), can_fetch, target.valid, source_active});
|
||||
state.builder.AddFunction(spv::OpLogicalAnd, TypeBool(state), can_fetch, target.valid,
|
||||
source_active);
|
||||
return EmitNative<spv::OpSelect, IR::Type::U32>(ctx.state, can_fetch, shuffled,
|
||||
ConstantU32(state, 0));
|
||||
}
|
||||
@@ -604,8 +600,8 @@ uint32_t EmitReadLane(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
uint32_t EmitWriteLane(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
auto& state = ctx.state;
|
||||
const auto hit = state.builder.AllocateId();
|
||||
state.builder.AddFunction({spv::OpIEqual, TypeBool(state), hit,
|
||||
EmitSubgroupLocalInvocationId(state), ctx.Arg(inst, 2)});
|
||||
state.builder.AddFunction(spv::OpIEqual, TypeBool(state), hit,
|
||||
EmitSubgroupLocalInvocationId(state), ctx.Arg(inst, 2));
|
||||
return EmitNative<spv::OpSelect, IR::Type::U32>(ctx.state, hit, ctx.Arg(inst, 1),
|
||||
ctx.Arg(inst, 0));
|
||||
}
|
||||
@@ -624,35 +620,35 @@ uint32_t EmitPermlane16U32(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
const auto shifted = state.builder.AllocateId();
|
||||
const auto index = state.builder.AllocateId();
|
||||
const auto target = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{spv::OpBitwiseAnd, TypeU32(state), row, subid, ConstantU32(state, 0xfffffff0u)});
|
||||
state.builder.AddFunction(spv::OpBitwiseAnd, TypeU32(state), row, subid,
|
||||
ConstantU32(state, 0xfffffff0u));
|
||||
if (flags.x16) {
|
||||
state.builder.AddFunction(
|
||||
{spv::OpBitwiseXor, TypeU32(state), row_value, row, ConstantU32(state, 16)});
|
||||
state.builder.AddFunction(spv::OpBitwiseXor, TypeU32(state), row_value, row,
|
||||
ConstantU32(state, 16));
|
||||
} else {
|
||||
state.builder.AddFunction({spv::OpCopyObject, TypeU32(state), row_value, row});
|
||||
state.builder.AddFunction(spv::OpCopyObject, TypeU32(state), row_value, row);
|
||||
}
|
||||
state.builder.AddFunction(
|
||||
{spv::OpBitwiseAnd, TypeU32(state), lane, subid, ConstantU32(state, 15)});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpBitwiseAnd, TypeU32(state), lane8, lane, ConstantU32(state, 7)});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpShiftLeftLogical, TypeU32(state), shift, lane8, ConstantU32(state, 2)});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpUGreaterThanEqual, TypeBool(state), upper, lane, ConstantU32(state, 8)});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpSelect, TypeU32(state), selected, upper, ctx.Arg(inst, 2), ctx.Arg(inst, 1)});
|
||||
state.builder.AddFunction({spv::OpShiftRightLogical, TypeU32(state), shifted, selected, shift});
|
||||
state.builder.AddFunction(
|
||||
{spv::OpBitwiseAnd, TypeU32(state), index, shifted, ConstantU32(state, 15)});
|
||||
state.builder.AddFunction({spv::OpBitwiseOr, TypeU32(state), target, row_value, index});
|
||||
state.builder.AddFunction(spv::OpBitwiseAnd, TypeU32(state), lane, subid,
|
||||
ConstantU32(state, 15));
|
||||
state.builder.AddFunction(spv::OpBitwiseAnd, TypeU32(state), lane8, lane,
|
||||
ConstantU32(state, 7));
|
||||
state.builder.AddFunction(spv::OpShiftLeftLogical, TypeU32(state), shift, lane8,
|
||||
ConstantU32(state, 2));
|
||||
state.builder.AddFunction(spv::OpUGreaterThanEqual, TypeBool(state), upper, lane,
|
||||
ConstantU32(state, 8));
|
||||
state.builder.AddFunction(spv::OpSelect, TypeU32(state), selected, upper, ctx.Arg(inst, 2),
|
||||
ctx.Arg(inst, 1));
|
||||
state.builder.AddFunction(spv::OpShiftRightLogical, TypeU32(state), shifted, selected, shift);
|
||||
state.builder.AddFunction(spv::OpBitwiseAnd, TypeU32(state), index, shifted,
|
||||
ConstantU32(state, 15));
|
||||
state.builder.AddFunction(spv::OpBitwiseOr, TypeU32(state), target, row_value, index);
|
||||
const auto shuffled = ctx.Shuffle(inst, 0, target);
|
||||
uint32_t result = shuffled;
|
||||
if (!flags.fetch_inactive) {
|
||||
const auto source_exec = ctx.Shuffle(inst, 3, target);
|
||||
result = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{spv::OpSelect, TypeU32(state), result, source_exec, shuffled, ConstantU32(state, 0)});
|
||||
state.builder.AddFunction(spv::OpSelect, TypeU32(state), result, source_exec, shuffled,
|
||||
ConstantU32(state, 0));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user