feat(viewer): select Vulkan texture through WEAR
This commit is contained in:
@@ -113,7 +113,7 @@ struct SmokeOptions {
|
|||||||
resize_frame: u32,
|
resize_frame: u32,
|
||||||
timeout_seconds: u64,
|
timeout_seconds: u64,
|
||||||
mesh_input: MeshInput,
|
mesh_input: MeshInput,
|
||||||
texture_input: Option<ResourceInput>,
|
texture_input: Option<TextureInput>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
@@ -123,6 +123,44 @@ struct ResourceInput {
|
|||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
struct WearMaterialInput {
|
||||||
|
root: PathBuf,
|
||||||
|
archive: String,
|
||||||
|
name: String,
|
||||||
|
material_index: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
enum TextureInput {
|
||||||
|
Direct(ResourceInput),
|
||||||
|
WearMaterial(WearMaterialInput),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TextureInput {
|
||||||
|
fn source(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Direct(_) => "original-texm",
|
||||||
|
Self::WearMaterial(_) => "original-wear-mat0-texm",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn archive(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Self::Direct(input) => &input.archive,
|
||||||
|
Self::WearMaterial(_) => "Textures.lib",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn requested_name(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Self::Direct(input) => &input.name,
|
||||||
|
// The selected name comes from MAT0 at load time and is not a CLI request.
|
||||||
|
Self::WearMaterial(_) => "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
enum MeshInput {
|
enum MeshInput {
|
||||||
SmokeTriangle,
|
SmokeTriangle,
|
||||||
@@ -169,6 +207,10 @@ impl SmokeOptions {
|
|||||||
let mut texture_root = None;
|
let mut texture_root = None;
|
||||||
let mut texture_archive = None;
|
let mut texture_archive = None;
|
||||||
let mut texture_name = None;
|
let mut texture_name = None;
|
||||||
|
let mut wear_root = None;
|
||||||
|
let mut wear_archive = None;
|
||||||
|
let mut wear_name = None;
|
||||||
|
let mut material_index = None;
|
||||||
let mut iter = args.iter();
|
let mut iter = args.iter();
|
||||||
while let Some(arg) = iter.next() {
|
while let Some(arg) = iter.next() {
|
||||||
match arg.as_str() {
|
match arg.as_str() {
|
||||||
@@ -242,6 +284,35 @@ impl SmokeOptions {
|
|||||||
.ok_or_else(|| "--texture-name requires a value".to_string())?,
|
.ok_or_else(|| "--texture-name requires a value".to_string())?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
"--wear-root" => {
|
||||||
|
wear_root = Some(
|
||||||
|
iter.next()
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.ok_or_else(|| "--wear-root requires a path".to_string())?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
"--wear-archive" => {
|
||||||
|
wear_archive = Some(
|
||||||
|
iter.next()
|
||||||
|
.cloned()
|
||||||
|
.ok_or_else(|| "--wear-archive requires a value".to_string())?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
"--wear-name" => {
|
||||||
|
wear_name = Some(
|
||||||
|
iter.next()
|
||||||
|
.cloned()
|
||||||
|
.ok_or_else(|| "--wear-name requires a value".to_string())?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
"--material-index" => {
|
||||||
|
material_index = Some(
|
||||||
|
iter.next()
|
||||||
|
.ok_or_else(|| "--material-index requires a value".to_string())?
|
||||||
|
.parse()
|
||||||
|
.map_err(|_| "--material-index must be a u16".to_string())?,
|
||||||
|
);
|
||||||
|
}
|
||||||
_ => return Err(format!("unknown native smoke option: {arg}")),
|
_ => return Err(format!("unknown native smoke option: {arg}")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,11 +341,11 @@ impl SmokeOptions {
|
|||||||
};
|
};
|
||||||
let texture_input = match (texture_root, texture_archive, texture_name) {
|
let texture_input = match (texture_root, texture_archive, texture_name) {
|
||||||
(None, None, None) => None,
|
(None, None, None) => None,
|
||||||
(Some(root), Some(archive), Some(name)) => Some(ResourceInput {
|
(Some(root), Some(archive), Some(name)) => Some(TextureInput::Direct(ResourceInput {
|
||||||
root,
|
root,
|
||||||
archive,
|
archive,
|
||||||
name,
|
name,
|
||||||
}),
|
})),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(
|
return Err(
|
||||||
"--texture-root, --texture-archive and --texture-name must be supplied together"
|
"--texture-root, --texture-archive and --texture-name must be supplied together"
|
||||||
@@ -282,13 +353,36 @@ impl SmokeOptions {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let wear_material_input = match (wear_root, wear_archive, wear_name, material_index) {
|
||||||
|
(None, None, None, None) => None,
|
||||||
|
(Some(root), Some(archive), Some(name), Some(material_index)) => {
|
||||||
|
Some(TextureInput::WearMaterial(WearMaterialInput {
|
||||||
|
root,
|
||||||
|
archive,
|
||||||
|
name,
|
||||||
|
material_index,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err(
|
||||||
|
"--wear-root, --wear-archive, --wear-name and --material-index must be supplied together"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if texture_input.is_some() && wear_material_input.is_some() {
|
||||||
|
return Err(
|
||||||
|
"manual --texture-* input cannot be combined with --wear-* material input"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
out,
|
out,
|
||||||
frames,
|
frames,
|
||||||
resize_frame,
|
resize_frame,
|
||||||
timeout_seconds,
|
timeout_seconds,
|
||||||
mesh_input,
|
mesh_input,
|
||||||
texture_input,
|
texture_input: texture_input.or(wear_material_input),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,26 +400,50 @@ impl SmokeOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_texture(&self) -> Result<Option<VulkanStaticTexture>, String> {
|
fn load_texture(&self) -> Result<Option<LoadedTexture>, String> {
|
||||||
self.texture_input.as_ref().map_or(Ok(None), |input| {
|
self.texture_input.as_ref().map_or(Ok(None), |input| {
|
||||||
let image = fparkan_inspection::load_texture_mip0_rgba8_from_root(
|
let (image, selected_name) = match input {
|
||||||
|
TextureInput::Direct(input) => (
|
||||||
|
fparkan_inspection::load_texture_mip0_rgba8_from_root(
|
||||||
&input.root,
|
&input.root,
|
||||||
&input.archive,
|
&input.archive,
|
||||||
&input.name,
|
&input.name,
|
||||||
|
)?,
|
||||||
|
input.name.clone(),
|
||||||
|
),
|
||||||
|
TextureInput::WearMaterial(input) => {
|
||||||
|
let selected =
|
||||||
|
fparkan_inspection::load_wear_material_texture_mip0_rgba8_from_root(
|
||||||
|
&input.root,
|
||||||
|
&input.archive,
|
||||||
|
&input.name,
|
||||||
|
input.material_index,
|
||||||
)?;
|
)?;
|
||||||
Ok(Some(VulkanStaticTexture {
|
(selected.image, selected.texture_name)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(Some(LoadedTexture {
|
||||||
|
texture: VulkanStaticTexture {
|
||||||
width: image.width,
|
width: image.width,
|
||||||
height: image.height,
|
height: image.height,
|
||||||
rgba8: image.rgba8,
|
rgba8: image.rgba8,
|
||||||
|
},
|
||||||
|
selected_name,
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct LoadedTexture {
|
||||||
|
texture: VulkanStaticTexture,
|
||||||
|
selected_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
struct SmokeApp {
|
struct SmokeApp {
|
||||||
options: SmokeOptions,
|
options: SmokeOptions,
|
||||||
mesh: VulkanStaticMesh,
|
mesh: VulkanStaticMesh,
|
||||||
texture: Option<VulkanStaticTexture>,
|
texture: Option<LoadedTexture>,
|
||||||
completed: Arc<AtomicBool>,
|
completed: Arc<AtomicBool>,
|
||||||
progress: Arc<SharedSmokeProgress>,
|
progress: Arc<SharedSmokeProgress>,
|
||||||
window_id: Option<WindowId>,
|
window_id: Option<WindowId>,
|
||||||
@@ -370,7 +488,7 @@ impl SmokeApp {
|
|||||||
fn new(
|
fn new(
|
||||||
options: SmokeOptions,
|
options: SmokeOptions,
|
||||||
mesh: VulkanStaticMesh,
|
mesh: VulkanStaticMesh,
|
||||||
texture: Option<VulkanStaticTexture>,
|
texture: Option<LoadedTexture>,
|
||||||
completed: Arc<AtomicBool>,
|
completed: Arc<AtomicBool>,
|
||||||
progress: Arc<SharedSmokeProgress>,
|
progress: Arc<SharedSmokeProgress>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -478,19 +596,29 @@ impl SmokeApp {
|
|||||||
.options
|
.options
|
||||||
.texture_input
|
.texture_input
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or("none", |_| "original-texm"),
|
.map_or("none", TextureInput::source),
|
||||||
texture_archive: self
|
texture_archive: self
|
||||||
.options
|
.options
|
||||||
.texture_input
|
.texture_input
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or("", |input| input.archive.as_str()),
|
.map_or("", TextureInput::archive),
|
||||||
texture_name: self
|
texture_name: self.texture.as_ref().map_or_else(
|
||||||
.options
|
|| {
|
||||||
|
self.options
|
||||||
.texture_input
|
.texture_input
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or("", |input| input.name.as_str()),
|
.map_or("", TextureInput::requested_name)
|
||||||
texture_width: self.texture.as_ref().map_or(0, |texture| texture.width),
|
},
|
||||||
texture_height: self.texture.as_ref().map_or(0, |texture| texture.height),
|
|texture| texture.selected_name.as_str(),
|
||||||
|
),
|
||||||
|
texture_width: self
|
||||||
|
.texture
|
||||||
|
.as_ref()
|
||||||
|
.map_or(0, |texture| texture.texture.width),
|
||||||
|
texture_height: self
|
||||||
|
.texture
|
||||||
|
.as_ref()
|
||||||
|
.map_or(0, |texture| texture.texture.height),
|
||||||
shader_manifest_hash: renderer
|
shader_manifest_hash: renderer
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or("", |snapshot| snapshot.report.shader_manifest_hash.as_str()),
|
.map_or("", |snapshot| snapshot.report.shader_manifest_hash.as_str()),
|
||||||
@@ -698,15 +826,15 @@ fn render_timeout_failure_report(
|
|||||||
texture_source: options
|
texture_source: options
|
||||||
.texture_input
|
.texture_input
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or("none", |_| "original-texm"),
|
.map_or("none", TextureInput::source),
|
||||||
texture_archive: options
|
texture_archive: options
|
||||||
.texture_input
|
.texture_input
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or("", |input| input.archive.as_str()),
|
.map_or("", TextureInput::archive),
|
||||||
texture_name: options
|
texture_name: options
|
||||||
.texture_input
|
.texture_input
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or("", |input| input.name.as_str()),
|
.map_or("", TextureInput::requested_name),
|
||||||
texture_width: 0,
|
texture_width: 0,
|
||||||
texture_height: 0,
|
texture_height: 0,
|
||||||
shader_manifest_hash: "",
|
shader_manifest_hash: "",
|
||||||
@@ -804,7 +932,7 @@ impl ApplicationHandler for SmokeApp {
|
|||||||
render_request: RenderRequest::conservative(),
|
render_request: RenderRequest::conservative(),
|
||||||
enable_validation: true,
|
enable_validation: true,
|
||||||
mesh: self.mesh.clone(),
|
mesh: self.mesh.clone(),
|
||||||
texture: self.texture.clone(),
|
texture: self.texture.as_ref().map(|texture| texture.texture.clone()),
|
||||||
bootstrap_progress: Some(Arc::clone(&self.progress.bootstrap)),
|
bootstrap_progress: Some(Arc::clone(&self.progress.bootstrap)),
|
||||||
}) {
|
}) {
|
||||||
Ok(renderer) => renderer,
|
Ok(renderer) => renderer,
|
||||||
@@ -1297,12 +1425,41 @@ mod tests {
|
|||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
parsed,
|
parsed,
|
||||||
Ok(SmokeOptions {
|
Ok(SmokeOptions {
|
||||||
texture_input: Some(ResourceInput { archive, name, .. }),
|
texture_input: Some(TextureInput::Direct(ResourceInput { archive, name, .. })),
|
||||||
..
|
..
|
||||||
}) if archive == "Textures.lib" && name == "DEFAULT.0"
|
}) if archive == "Textures.lib" && name == "DEFAULT.0"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parses_original_wear_material_input_as_one_atomic_request() {
|
||||||
|
let parsed = SmokeOptions::parse(&[
|
||||||
|
"--out".to_string(),
|
||||||
|
"target/report.json".to_string(),
|
||||||
|
"--wear-root".to_string(),
|
||||||
|
"C:/GOG".to_string(),
|
||||||
|
"--wear-archive".to_string(),
|
||||||
|
"system.rlb".to_string(),
|
||||||
|
"--wear-name".to_string(),
|
||||||
|
"MODEL.WEA".to_string(),
|
||||||
|
"--material-index".to_string(),
|
||||||
|
"7".to_string(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert!(matches!(
|
||||||
|
parsed,
|
||||||
|
Ok(SmokeOptions {
|
||||||
|
texture_input: Some(TextureInput::WearMaterial(WearMaterialInput {
|
||||||
|
archive,
|
||||||
|
name,
|
||||||
|
material_index,
|
||||||
|
..
|
||||||
|
})),
|
||||||
|
..
|
||||||
|
}) if archive == "system.rlb" && name == "MODEL.WEA" && material_index == 7
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rejects_deprecated_self_assertion_flags() {
|
fn rejects_deprecated_self_assertion_flags() {
|
||||||
for flag in [
|
for flag in [
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
| Path | Native window / swapchain | Draws pixels | Uses original assets | Acceptance class | Что доказывает | Чего не доказывает |
|
| Path | Native window / swapchain | Draws pixels | Uses original assets | Acceptance class | Что доказывает | Чего не доказывает |
|
||||||
| --- | --- | --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
| `fparkan-vulkan-smoke` / `VulkanSmokeRenderer` | Yes | Yes | Static MSH plus sampled TEXM | `covered-gpu` for Stage 0 smoke and explicit MSH/TEXM/descriptor bridge IDs | Loader, instance, surface, swapchain, submit/present, validation-clean triangle path; original MSH indexed draw; TEXM RGBA8 staging upload, `SHADER_READ_ONLY_OPTIMAL`, sampler/descriptor binding and fragment sampling | Original material mapping, exact MSH UV scale, terrain, gameplay rendering |
|
| `fparkan-vulkan-smoke` / `VulkanSmokeRenderer` | Yes | Yes | Static MSH plus sampled TEXM | `covered-gpu` for Stage 0 smoke and explicit MSH/TEXM/descriptor bridge IDs | Loader, instance, surface, swapchain, submit/present, validation-clean triangle path; original MSH indexed draw; TEXM RGBA8 staging upload, sampler/descriptor binding, fragment sampling and one explicitly selected WEAR/MAT0 material path | Per-batch material selection, phase animation, lightmaps, terrain, gameplay rendering |
|
||||||
| `VulkanPlanningBackend` | No | No | Optional CPU-side IDs only | `covered-planning` | Deterministic command validation, canonical capture, frame submission planning | Любой live GPU draw, pixel parity, validation-clean asset frame |
|
| `VulkanPlanningBackend` | No | No | Optional CPU-side IDs only | `covered-planning` | Deterministic command validation, canonical capture, frame submission planning | Любой live GPU draw, pixel parity, validation-clean asset frame |
|
||||||
| `RecordingBackend` | No | No | Optional CPU-side IDs only | `covered-planning` | Stable command capture for backend-neutral tests | Native window, Vulkan, GPU resource lifetime, pixels |
|
| `RecordingBackend` | No | No | Optional CPU-side IDs only | `covered-planning` | Stable command capture for backend-neutral tests | Native window, Vulkan, GPU resource lifetime, pixels |
|
||||||
| `NullBackend` | No | No | Optional CPU-side IDs only | Usually `covered` for validation-only rows | Command stream framing and bounds validation | Capture stability, GPU execution, pixels |
|
| `NullBackend` | No | No | Optional CPU-side IDs only | Usually `covered` for validation-only rows | Command stream framing and bounds validation | Capture stability, GPU execution, pixels |
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
## Current repository status
|
## Current repository status
|
||||||
|
|
||||||
- Реальный Vulkan в репозитории имеет smoke triangle path и узкий static asset bridge: `fparkan-vulkan-smoke --model-root <GOG_ROOT> --model-archive system.rlb --model-name MTCHECK.MSH --texture-root <GOG_ROOT> --texture-archive Textures.lib --texture-name DEFAULT.0` загружает validated original MSH, разворачивает batch `base_vertex`, нормализует XZ viewer plane, выполняет real indexed draw и загружает decoded TEXM mip-0 в device-local image. Image переходит в sampling layout, записывается в `set=0,binding=0` combined image sampler и sampled fragment shader-ом. `Res5` UV0 декодируется как signed fixed point `int16 / 1024.0`; XZ-planar UV остаётся только fallback для модели без optional stream. Это не WEAR/MAT0, exact material, terrain или gameplay renderer.
|
- Реальный Vulkan в репозитории имеет smoke triangle path и узкий static asset bridge. Помимо direct TEXM input, `fparkan-vulkan-smoke --model-root <GOG_ROOT> --model-archive fortif.rlb --model-name FR_L_MTP.msh --wear-root <GOG_ROOT> --wear-archive fortif.rlb --wear-name FR_L_MTP.WEA --material-index 0` проходит `WEAR → MAT0 → Textures.lib`, выбирает `MTP_01.0`, выполняет real indexed draw и загружает selected TEXM mip-0 в device-local image. Image переходит в sampling layout, записывается в `set=0,binding=0` combined image sampler и sampled fragment shader-ом. `Res5` UV0 декодируется как signed fixed point `int16 / 1024.0`; XZ-planar UV остаётся только fallback для модели без optional stream. Это один explicit material selector, не полный per-batch/phase/lightmap/terrain или gameplay renderer.
|
||||||
- `apps/fparkan-game` сейчас выдает `render-planning` JSON report поверх
|
- `apps/fparkan-game` сейчас выдает `render-planning` JSON report поверх
|
||||||
synthetic window descriptor и `VulkanPlanningBackend`.
|
synthetic window descriptor и `VulkanPlanningBackend`.
|
||||||
- `apps/fparkan-viewer` сейчас inspection-only CLI и не открывает live Vulkan
|
- `apps/fparkan-viewer` сейчас inspection-only CLI и не открывает live Vulkan
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ S3-VK-MESH-UPLOAD-001 covered-gpu cargo run -p fparkan-vulkan-smoke --release --
|
|||||||
S3-VK-TEXM-UPLOAD-001 covered-gpu cargo run -p fparkan-vulkan-smoke --release --locked -- --out target/fparkan/stage3-mtcheck-texm-upload.json --frames 300 --resize-frame 120 --timeout-seconds 90 --model-root <GOG_ROOT> --model-archive system.rlb --model-name MTCHECK.MSH --texture-root <GOG_ROOT> --texture-archive Textures.lib --texture-name DEFAULT.0; original TEXM 16x16 decoded RGBA8, staged into device-local image and transitioned to SHADER_READ_ONLY_OPTIMAL
|
S3-VK-TEXM-UPLOAD-001 covered-gpu cargo run -p fparkan-vulkan-smoke --release --locked -- --out target/fparkan/stage3-mtcheck-texm-upload.json --frames 300 --resize-frame 120 --timeout-seconds 90 --model-root <GOG_ROOT> --model-archive system.rlb --model-name MTCHECK.MSH --texture-root <GOG_ROOT> --texture-archive Textures.lib --texture-name DEFAULT.0; original TEXM 16x16 decoded RGBA8, staged into device-local image and transitioned to SHADER_READ_ONLY_OPTIMAL
|
||||||
S3-VK-DESCRIPTOR-001 covered-gpu cargo run -p fparkan-vulkan-smoke --release --locked -- --out target/fparkan/stage3-texm-sampled.json --frames 300 --resize-frame 120 --timeout-seconds 90 --model-root <GOG_ROOT> --model-archive system.rlb --model-name MTCHECK.MSH --texture-root <GOG_ROOT> --texture-archive Textures.lib --texture-name DEFAULT.0; original TEXM is bound as set=0,binding=0 combined image sampler and sampled in fragment shader; validation_warning_count=0 and validation_error_count=0
|
S3-VK-DESCRIPTOR-001 covered-gpu cargo run -p fparkan-vulkan-smoke --release --locked -- --out target/fparkan/stage3-texm-sampled.json --frames 300 --resize-frame 120 --timeout-seconds 90 --model-root <GOG_ROOT> --model-archive system.rlb --model-name MTCHECK.MSH --texture-root <GOG_ROOT> --texture-archive Textures.lib --texture-name DEFAULT.0; original TEXM is bound as set=0,binding=0 combined image sampler and sampled in fragment shader; validation_warning_count=0 and validation_error_count=0
|
||||||
S3-VK-PIPELINE-001 blocked awaits Stage 3 graphics pipeline key and cache implementation
|
S3-VK-PIPELINE-001 blocked awaits Stage 3 graphics pipeline key and cache implementation
|
||||||
S3-VK-DRAW-MODEL-001 covered-gpu cargo run -p fparkan-vulkan-smoke --release --locked -- --out target/fparkan/stage3-mtcheck-msh.json --frames 300 --resize-frame 120 --timeout-seconds 90 --model-root <GOG_ROOT> --model-archive system.rlb --model-name MTCHECK.MSH; live Win32 Vulkan indexed MSH draw/present
|
S3-VK-DRAW-MODEL-001 covered-gpu cargo run -p fparkan-vulkan-smoke --release --locked -- --out target/fparkan/stage3-fr-l-mtp-wear-mat0.json --frames 300 --resize-frame 120 --timeout-seconds 90 --model-root <GOG_ROOT> --model-archive fortif.rlb --model-name FR_L_MTP.msh --wear-root <GOG_ROOT> --wear-archive fortif.rlb --wear-name FR_L_MTP.WEA --material-index 0; live Win32 Vulkan indexed MSH draw with original WEAR→MAT0-selected MTP_01.0 TEXM
|
||||||
S3-VK-DRAW-TERRAIN-001 blocked awaits Stage 3 terrain Vulkan draw path
|
S3-VK-DRAW-TERRAIN-001 blocked awaits Stage 3 terrain Vulkan draw path
|
||||||
S3-VK-PIXEL-CAPTURE-001 blocked awaits Stage 3 fixed-camera pixel capture approval flow
|
S3-VK-PIXEL-CAPTURE-001 blocked awaits Stage 3 fixed-camera pixel capture approval flow
|
||||||
S3-VK-VALIDATION-001 covered-gpu cargo run -p fparkan-vulkan-smoke --release --locked -- --out target/fparkan/stage3-mtcheck-msh.json --frames 300 --resize-frame 120 --timeout-seconds 90 --model-root <GOG_ROOT> --model-archive system.rlb --model-name MTCHECK.MSH; validation_warning_count=0 and validation_error_count=0
|
S3-VK-VALIDATION-001 covered-gpu cargo run -p fparkan-vulkan-smoke --release --locked -- --out target/fparkan/stage3-mtcheck-msh.json --frames 300 --resize-frame 120 --timeout-seconds 90 --model-root <GOG_ROOT> --model-archive system.rlb --model-name MTCHECK.MSH; validation_warning_count=0 and validation_error_count=0
|
||||||
|
|||||||
|
Reference in New Issue
Block a user