mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	glsl: Implement indexed attribute loads
This commit is contained in:
		@@ -104,8 +104,22 @@ std::string_view SamplerType(TextureType type, bool is_depth) {
 | 
			
		||||
 | 
			
		||||
std::string_view ImageType(TextureType type) {
 | 
			
		||||
    switch (type) {
 | 
			
		||||
    case TextureType::Color1D:
 | 
			
		||||
        return "uimage1D";
 | 
			
		||||
    case TextureType::ColorArray1D:
 | 
			
		||||
        return "uimage1DArray";
 | 
			
		||||
    case TextureType::Color2D:
 | 
			
		||||
        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:
 | 
			
		||||
        throw NotImplementedException("Image type: {}", type);
 | 
			
		||||
    }
 | 
			
		||||
@@ -250,6 +264,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
 | 
			
		||||
        break;
 | 
			
		||||
    case Stage::Fragment:
 | 
			
		||||
        stage_name = "fs";
 | 
			
		||||
        position_name = "gl_FragCoord";
 | 
			
		||||
        break;
 | 
			
		||||
    case Stage::Compute:
 | 
			
		||||
        stage_name = "cs";
 | 
			
		||||
@@ -449,6 +464,33 @@ void EmitContext::DefineHelperFunctions() {
 | 
			
		||||
    if (info.uses_global_memory) {
 | 
			
		||||
        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() {
 | 
			
		||||
 
 | 
			
		||||
@@ -150,6 +150,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    Stage stage{};
 | 
			
		||||
    std::string_view stage_name = "invalid";
 | 
			
		||||
    std::string_view position_name = "gl_Position";
 | 
			
		||||
 | 
			
		||||
    std::vector<u32> texture_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::PositionY:
 | 
			
		||||
    case IR::Attribute::PositionZ:
 | 
			
		||||
    case IR::Attribute::PositionW:
 | 
			
		||||
        switch (ctx.stage) {
 | 
			
		||||
        case Stage::VertexA:
 | 
			
		||||
        case Stage::VertexB:
 | 
			
		||||
            ctx.AddF32("{}=gl_Position.{};", inst, swizzle);
 | 
			
		||||
            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);
 | 
			
		||||
        }
 | 
			
		||||
    case IR::Attribute::PositionW: {
 | 
			
		||||
        const bool is_array{IsInputArray(ctx.stage)};
 | 
			
		||||
        const auto input_decorator{is_array ? fmt::format("gl_in[{}].", vertex) : ""};
 | 
			
		||||
        ctx.AddF32("{}={}{}.{};", inst, input_decorator, ctx.position_name, swizzle);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case IR::Attribute::PointSpriteS:
 | 
			
		||||
    case IR::Attribute::PointSpriteT:
 | 
			
		||||
        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) {
 | 
			
		||||
    if (!IR::IsGeneric(patch)) {
 | 
			
		||||
        throw NotImplementedException("Non-generic patch load");
 | 
			
		||||
 
 | 
			
		||||
@@ -72,7 +72,8 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
 | 
			
		||||
                      std::string_view vertex);
 | 
			
		||||
void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view value,
 | 
			
		||||
                      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,
 | 
			
		||||
                             std::string_view vertex);
 | 
			
		||||
void EmitGetPatch(EmitContext& ctx, IR::Inst& inst, IR::Patch patch);
 | 
			
		||||
 
 | 
			
		||||
@@ -124,15 +124,6 @@ void EmitGetIndirectBranchVariable(EmitContext& ctx) {
 | 
			
		||||
    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) {
 | 
			
		||||
    NotImplemented();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user