refactor(mod): dispatch RenderBackendOps.current() by active backend (Stage 4 kickoff)
Stage 4 Vulkan groundwork. Before this, RenderBackendOps.current() unconditionally returned GlRenderBackendOps.INSTANCE with a 'Stage 3-prep' comment. Under Vulkan the GL impl is still harmless (its methods all short-circuit on OptimizeToggles and the GL mixins never fire), but the interface lied about the active backend. - New misc/optimize/vulkan/VulkanRenderBackendOps: singleton, no-op stub, all *Supported() return false, cache/map methods do nothing. This is the skeleton the Stage 4 items (persistent VkPipelineCache, VulkanRenderPass state cache) will grow into. - RenderBackendOps.current() inspects RenderSystem.getDevice().getClass().getName() and returns VulkanRenderBackendOps for com.mojang.blaze3d.vulkan.* devices, GlRenderBackendOps otherwise. Class-name check (not instanceof) so this method itself does not force linking of GlDevice/VulkanDevice. - Wrapped getDevice() in try/catch: unit tests call current() before RenderSystem has a device and previously took the GL path; now they still do via the fallback. Doc: Stage 4 kickoff entry in the changelog.
This commit is contained in:
parent
39b270b108
commit
d5f17eb0ac
3 changed files with 129 additions and 1 deletions
|
|
@ -3,6 +3,12 @@
|
||||||
Статус: Этапы 1-3 готовы (2026-10-12). Этап 4 (Vulkan) — стартуем с универсально-полезных пунктов. Цель MC: 26.2.
|
Статус: Этапы 1-3 готовы (2026-10-12). Этап 4 (Vulkan) — стартуем с универсально-полезных пунктов. Цель MC: 26.2.
|
||||||
|
|
||||||
## История изменений
|
## История изменений
|
||||||
|
- **2026-10-12**: Этап 4 старт — `RenderBackendOps.current()` теперь определяет активный бэкенд через
|
||||||
|
`RenderSystem.getDevice().getClass().getName()` (class-name, не `instanceof`, чтобы не форсировать линковку
|
||||||
|
`GlDevice`/`VulkanDevice`); добавлен `misc/optimize/vulkan/VulkanRenderBackendOps` — no-op-заглушка со
|
||||||
|
всеми `*Supported() == false`. Под GL всё работает как раньше; под Vulkan mixins из `mixins/optimize/gl/*` не
|
||||||
|
загружаются, и теперь хотя бы интерфейс честно возвращает правильный бэкенд. Живые Vulkan-пути
|
||||||
|
(`VkPipelineCache`, state cache) — следующий шаг.
|
||||||
- **2026-10-12**: убран гейт «меряем на Windows до включения». Бенчмарки больше не блокируют работу: универсально-полезные
|
- **2026-10-12**: убран гейт «меряем на Windows до включения». Бенчмарки больше не блокируют работу: универсально-полезные
|
||||||
GL/Vulkan-оптимизации делаем сразу за default-off тумблерами (пользователь включает сам), отчёт цифр остаётся как
|
GL/Vulkan-оптимизации делаем сразу за default-off тумблерами (пользователь включает сам), отчёт цифр остаётся как
|
||||||
факультативная задача владельца и не входит в план. Этап 3 закрыт по всем пунктам, кроме п.9 (`no_item_sort` /
|
факультативная задача владельца и не входит в план. Этап 3 закрыт по всем пунктам, кроме п.9 (`no_item_sort` /
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
package dev.loki.lovisual.features.module.modules.misc.optimize.gl;
|
package dev.loki.lovisual.features.module.modules.misc.optimize.gl;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import dev.loki.lovisual.features.module.modules.misc.optimize.vulkan.VulkanRenderBackendOps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Backend-agnostic surface for the optimization layer's GL/Vulkan hooks.
|
* Backend-agnostic surface for the optimization layer's GL/Vulkan hooks.
|
||||||
*
|
*
|
||||||
|
|
@ -29,8 +32,30 @@ package dev.loki.lovisual.features.module.modules.misc.optimize.gl;
|
||||||
*/
|
*/
|
||||||
public interface RenderBackendOps {
|
public interface RenderBackendOps {
|
||||||
|
|
||||||
/** Resolve the current backend — GL backend if GL is active, otherwise {@code null}. */
|
/**
|
||||||
|
* Resolve the current backend by inspecting the active {@code GpuDeviceBackend}.
|
||||||
|
* Class-name check (not {@code instanceof}) so this method itself does not
|
||||||
|
* force the loader to link {@code GlDevice} or {@code VulkanDevice}; the
|
||||||
|
* Blaze3D jar always ships both, but keeping the check by string means the
|
||||||
|
* dispatch stays correct even when only one backend's class has been
|
||||||
|
* resolved. Falls back to the GL impl when the device is null (early boot)
|
||||||
|
* so mixins' {@code supported()} short-circuits behave the same as before.
|
||||||
|
*/
|
||||||
static RenderBackendOps current() {
|
static RenderBackendOps current() {
|
||||||
|
Object device;
|
||||||
|
try {
|
||||||
|
device = RenderSystem.getDevice();
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
// Tests and pre-init paths call current() before RenderSystem has a
|
||||||
|
// device; fall through to GL so existing unit tests keep passing.
|
||||||
|
device = null;
|
||||||
|
}
|
||||||
|
if (device != null) {
|
||||||
|
String name = device.getClass().getName();
|
||||||
|
if (name.startsWith("com.mojang.blaze3d.vulkan.")) {
|
||||||
|
return VulkanRenderBackendOps.current();
|
||||||
|
}
|
||||||
|
}
|
||||||
return GlRenderBackendOps.current();
|
return GlRenderBackendOps.current();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
package dev.loki.lovisual.features.module.modules.misc.optimize.vulkan;
|
||||||
|
|
||||||
|
import dev.loki.lovisual.features.module.modules.misc.optimize.gl.RenderBackendOps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vulkan-side implementation of {@link RenderBackendOps}. All GPU-object ops
|
||||||
|
* (lazy clear, TBO cache, shared depth FBO, RenderTypes cache) currently live
|
||||||
|
* in the GL mixin set — under Vulkan those mixins never load, so this class is
|
||||||
|
* a no-op placeholder that lets {@code RenderBackendOps.current()} dispatch by
|
||||||
|
* actual backend instead of unconditionally returning the GL impl.
|
||||||
|
*
|
||||||
|
* <p>Every {@code *Supported} reports {@code false}. Callers already gate on
|
||||||
|
* supported before attempting, so the effect is the same as "Optimize GPU
|
||||||
|
* features off" for backend-dependent items. Stage 4 adds Vulkan-specific
|
||||||
|
* paths (persistent {@code VkPipelineCache}, {@code VulkanRenderPass} state
|
||||||
|
* cache) by flipping the corresponding {@code *Supported} here to true and
|
||||||
|
* implementing the op body.
|
||||||
|
*
|
||||||
|
* <p>Doc reference: {@code mod/docs/optimize-layer-design.md}, "Этап 4" and
|
||||||
|
* "Что уже решено в архитектуре" → "Рендер-бэкенды".
|
||||||
|
*/
|
||||||
|
public final class VulkanRenderBackendOps implements RenderBackendOps {
|
||||||
|
|
||||||
|
private static final VulkanRenderBackendOps INSTANCE = new VulkanRenderBackendOps();
|
||||||
|
|
||||||
|
private VulkanRenderBackendOps() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Singleton — no state, no per-device instance needed. */
|
||||||
|
public static VulkanRenderBackendOps current() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Lazy clear ---
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean lazyClearSupported() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean skipBindFramebufferZero(int framebuffer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- TBO cache ---
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tboCacheSupported() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trackBoundTboTexture(int texture) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tboAlreadyAttached(int format, int buffer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void markTboAttached(int format, int buffer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forgetTboCache() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- FBO share ---
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean fboShareSupported() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean clearDepthInPlace(int depthId, double value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- RenderTypes cache ---
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean renderTypesCacheSupported() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object renderTypeFor(Identifier id) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cacheRenderType(Identifier id, Object type) {
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue