Files
XCEngine/engine/tools/renderdoc_parser/tools/resource_tools.py
ssdfasd fb01beb959 Add renderdoc_parser: direct-call Python interface for RenderDoc capture analysis
- Convert from MCP protocol layer to direct Python function calls
- 42 functions across 9 modules: session, event, pipeline, resource, data, shader, advanced, performance, diagnostic
- Requires Python 3.6 (renderdoc.pyd is compiled for Python 3.6)
- Fix renderdoc API calls: GetColorBlends, GetStencilFaces, GetViewport(i), GetScissor(i)
- Remove Python 3.10+ type annotations for Python 3.6 compatibility
- Add README.md with full API documentation
- Includes test.py for basic smoke testing
2026-03-23 18:46:20 +08:00

137 lines
3.8 KiB
Python

"""Resource analysis tools: list_textures, list_buffers, list_resources, get_resource_usage."""
from typing import Optional
from ..session import get_session
from ..util import (
rd,
make_error,
serialize_texture_desc,
serialize_buffer_desc,
serialize_usage_entry,
)
def list_textures(
filter_format: Optional[str] = None, min_width: Optional[int] = None
) -> dict:
"""List all textures in the capture.
Args:
filter_format: Optional format substring to filter by (e.g. "R8G8B8A8", "BC7").
min_width: Optional minimum width to filter by.
"""
session = get_session()
err = session.require_open()
if err:
return err
textures = session.controller.GetTextures()
results = []
for tex in textures:
if min_width is not None and tex.width < min_width:
continue
fmt_name = str(tex.format.Name())
if filter_format and filter_format.upper() not in fmt_name.upper():
continue
results.append(serialize_texture_desc(tex))
return {"textures": results, "count": len(results)}
def list_buffers(min_size: Optional[int] = None) -> dict:
"""List all buffers in the capture.
Args:
min_size: Optional minimum byte size to filter by.
"""
session = get_session()
err = session.require_open()
if err:
return err
buffers = session.controller.GetBuffers()
results = []
for buf in buffers:
if min_size is not None and buf.length < min_size:
continue
results.append(serialize_buffer_desc(buf))
return {"buffers": results, "count": len(results)}
def list_resources(
type_filter: Optional[str] = None, name_pattern: Optional[str] = None
) -> dict:
"""List all named resources in the capture.
Args:
type_filter: Optional resource type substring filter (e.g. "Texture", "Buffer").
name_pattern: Optional regex pattern to filter resource names (case-insensitive).
"""
import re
session = get_session()
err = session.require_open()
if err:
return err
resources = session.controller.GetResources()
pattern = None
if name_pattern:
try:
pattern = re.compile(name_pattern, re.IGNORECASE)
except re.error as e:
return make_error(f"Invalid regex pattern: {e}", "API_ERROR")
results = []
for res in resources:
if type_filter and type_filter.lower() not in str(res.type).lower():
continue
try:
name = res.name
except Exception:
name = f"<unreadable name for {str(res.resourceId)}>"
if not isinstance(name, str):
try:
name = name.decode("utf-8", errors="replace")
except Exception:
name = repr(name)
if pattern and not pattern.search(name):
continue
results.append(
{
"resource_id": str(res.resourceId),
"name": name,
"type": str(res.type),
}
)
return {"resources": results, "count": len(results)}
def get_resource_usage(resource_id: str) -> dict:
"""Get the usage history of a resource across all events.
Shows which events read from or write to this resource.
Args:
resource_id: The resource ID string (as returned by other tools).
"""
session = get_session()
err = session.require_open()
if err:
return err
rid = session.resolve_resource_id(resource_id)
if rid is None:
return make_error(
f"Resource ID '{resource_id}' not found", "INVALID_RESOURCE_ID"
)
usages = session.controller.GetUsage(rid)
results = [serialize_usage_entry(u) for u in usages]
return {"resource_id": resource_id, "usages": results, "count": len(results)}