- 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
137 lines
3.8 KiB
Python
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)}
|