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