glsl: Implement indexed attribute loads

master
ameerj 2021-06-07 20:39:30 +07:00
parent 2a504b4765
commit c542204113
5 changed files with 64 additions and 29 deletions

@ -104,8 +104,22 @@ std::string_view SamplerType(TextureType type, bool is_depth) {
std::string_view ImageType(TextureType type) { std::string_view ImageType(TextureType type) {
switch (type) { switch (type) {
case TextureType::Color1D:
return "uimage1D";
case TextureType::ColorArray1D:
return "uimage1DArray";
case TextureType::Color2D: case TextureType::Color2D:
return "uimage2D"; return "uimage2D";
case TextureType::ColorArray2D:
return "uimage2DArray";
case TextureType::Color3D:
return "uimage3D";
case TextureType::ColorCube:
return "uimageCube";
case TextureType::ColorArrayCube:
return "uimageCubeArray";
case TextureType::Buffer:
return "uimageBuffer";
default: default:
throw NotImplementedException("Image type: {}", type); throw NotImplementedException("Image type: {}", type);
} }
@ -250,6 +264,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
break; break;
case Stage::Fragment: case Stage::Fragment:
stage_name = "fs"; stage_name = "fs";
position_name = "gl_FragCoord";
break; break;
case Stage::Compute: case Stage::Compute:
stage_name = "cs"; stage_name = "cs";
@ -449,6 +464,33 @@ void EmitContext::DefineHelperFunctions() {
if (info.uses_global_memory) { if (info.uses_global_memory) {
header += DefineGlobalMemoryFunctions(); header += DefineGlobalMemoryFunctions();
} }
if (info.loads_indexed_attributes) {
const bool is_array{stage == Stage::Geometry};
const auto vertex_arg{is_array ? ",uint vertex" : ""};
std::string func{
fmt::format("float IndexedAttrLoad(int offset{}){{int base_index=offset>>2;uint "
"masked_index=uint(base_index)&3u;switch(base_index>>2){{",
vertex_arg)};
if (info.loads_position) {
func += fmt::format("case {}:", static_cast<u32>(IR::Attribute::PositionX) >> 2);
const auto position_idx{is_array ? "gl_in[vertex]." : ""};
func += fmt::format("return {}{}[masked_index];", position_idx, position_name);
}
const u32 base_attribute_value = static_cast<u32>(IR::Attribute::Generic0X) >> 2;
for (u32 i = 0; i < info.input_generics.size(); ++i) {
if (!info.input_generics[i].used) {
continue;
}
const auto vertex_idx{is_array ? "[vertex]" : ""};
func += fmt::format("case {}:", base_attribute_value + i);
func += fmt::format("return in_attr{}{}[masked_index];", i, vertex_idx);
}
func += "default: return 0.0;}}";
header += func;
}
if (info.stores_indexed_attributes) {
// TODO
}
} }
std::string EmitContext::DefineGlobalMemoryFunctions() { std::string EmitContext::DefineGlobalMemoryFunctions() {

@ -150,6 +150,7 @@ public:
Stage stage{}; Stage stage{};
std::string_view stage_name = "invalid"; std::string_view stage_name = "invalid";
std::string_view position_name = "gl_Position";
std::vector<u32> texture_buffer_bindings; std::vector<u32> texture_buffer_bindings;
std::vector<u32> image_buffer_bindings; std::vector<u32> image_buffer_bindings;

@ -206,26 +206,12 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
case IR::Attribute::PositionX: case IR::Attribute::PositionX:
case IR::Attribute::PositionY: case IR::Attribute::PositionY:
case IR::Attribute::PositionZ: case IR::Attribute::PositionZ:
case IR::Attribute::PositionW: case IR::Attribute::PositionW: {
switch (ctx.stage) { const bool is_array{IsInputArray(ctx.stage)};
case Stage::VertexA: const auto input_decorator{is_array ? fmt::format("gl_in[{}].", vertex) : ""};
case Stage::VertexB: ctx.AddF32("{}={}{}.{};", inst, input_decorator, ctx.position_name, swizzle);
ctx.AddF32("{}=gl_Position.{};", inst, swizzle);
break; break;
case Stage::TessellationEval:
ctx.AddF32("{}=gl_TessCoord.{};", inst, swizzle);
break;
case Stage::TessellationControl:
case Stage::Geometry:
ctx.AddF32("{}=gl_in[{}].gl_Position.{};", inst, vertex, swizzle);
break;
case Stage::Fragment:
ctx.AddF32("{}=gl_FragCoord.{};", inst, swizzle);
break;
default:
throw NotImplementedException("Get Position for stage {}", ctx.stage);
} }
break;
case IR::Attribute::PointSpriteS: case IR::Attribute::PointSpriteS:
case IR::Attribute::PointSpriteT: case IR::Attribute::PointSpriteT:
ctx.AddF32("{}=gl_PointCoord.{};", inst, swizzle); ctx.AddF32("{}=gl_PointCoord.{};", inst, swizzle);
@ -311,6 +297,20 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val
} }
} }
void EmitGetAttributeIndexed(EmitContext& ctx, IR::Inst& inst, std::string_view offset,
std::string_view vertex) {
const bool is_array{ctx.stage == Stage::Geometry};
const auto vertex_arg{is_array ? fmt::format(",{}", vertex) : ""};
ctx.AddF32("{}=IndexedAttrLoad(int({}){});", inst, offset, vertex_arg);
}
void EmitSetAttributeIndexed([[maybe_unused]] EmitContext& ctx,
[[maybe_unused]] std::string_view offset,
[[maybe_unused]] std::string_view value,
[[maybe_unused]] std::string_view vertex) {
NotImplemented();
}
void EmitGetPatch(EmitContext& ctx, IR::Inst& inst, IR::Patch patch) { void EmitGetPatch(EmitContext& ctx, IR::Inst& inst, IR::Patch patch) {
if (!IR::IsGeneric(patch)) { if (!IR::IsGeneric(patch)) {
throw NotImplementedException("Non-generic patch load"); throw NotImplementedException("Non-generic patch load");

@ -72,7 +72,8 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
std::string_view vertex); std::string_view vertex);
void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view value, void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view value,
std::string_view vertex); std::string_view vertex);
void EmitGetAttributeIndexed(EmitContext& ctx, std::string_view offset, std::string_view vertex); void EmitGetAttributeIndexed(EmitContext& ctx, IR::Inst& inst, std::string_view offset,
std::string_view vertex);
void EmitSetAttributeIndexed(EmitContext& ctx, std::string_view offset, std::string_view value, void EmitSetAttributeIndexed(EmitContext& ctx, std::string_view offset, std::string_view value,
std::string_view vertex); std::string_view vertex);
void EmitGetPatch(EmitContext& ctx, IR::Inst& inst, IR::Patch patch); void EmitGetPatch(EmitContext& ctx, IR::Inst& inst, IR::Patch patch);

@ -124,15 +124,6 @@ void EmitGetIndirectBranchVariable(EmitContext& ctx) {
NotImplemented(); NotImplemented();
} }
void EmitGetAttributeIndexed(EmitContext& ctx, std::string_view offset, std::string_view vertex) {
NotImplemented();
}
void EmitSetAttributeIndexed(EmitContext& ctx, std::string_view offset, std::string_view value,
std::string_view vertex) {
NotImplemented();
}
void EmitSetSampleMask(EmitContext& ctx, std::string_view value) { void EmitSetSampleMask(EmitContext& ctx, std::string_view value) {
NotImplemented(); NotImplemented();
} }