Nope. Sdlstreams has a converter that goes the other way, taking an existing TStream and making a new PSDL_RWops out of it, but that's the opposite of what I'm looking for.

Here's my preliminary offering. If it's good enough, maybe it could get integrated into the sdlstreams unit.
[pascal]unit SDL_rwStream;

interface
uses
classes,
SDL;

type
TRWStream = class(TStream)
private
FOps: PSDL_RWops;
FOwnsOps: Boolean;
public
constructor Create(ops: PSDL_RWops; owns: boolean = true);
destructor Destroy; override;
function Read(var Buffer; Count: Integer): Integer; override;
function Write(const Buffer; Count: Integer): Integer; override;
function Seek(Offset: Integer; Origin: Word): Integer; override;
end;

implementation

{ TRWStream }

constructor TRWStream.Create(ops: PSDL_RWops; owns: boolean);
begin
inherited Create;
if not assigned(ops) then
raise EStreamError.Create('No SDL_RWops available for TRWStream creation!');
FOps := ops;
FOwnsOps := owns;
end;

destructor TRWStream.Destroy;
begin
if FOwnsOps then
begin
FOps.close(FOps);
SDL_FreeRW(FOps);
end

//this is not strictly necessary, but it leaves the RWops in a known state,
//which is always nice
else self.Seek(0, soFromBeginning);
inherited Destroy;
end;

function TRWStream.Read(var Buffer; Count: Integer): Integer;
begin
result := FOps.read(FOps, @Buffer, 1, count);
end;

function TRWStream.Seek(Offset: Integer; Origin: Word): Integer;
begin
result := FOps.seek(FOps, offset, origin);
end;

function TRWStream.Write(const Buffer; Count: Integer): Integer;
begin
result := FOps.write(FOps, @buffer, 1, count);
end;

end.[/pascal]

EDIT: After poking around in SDL_rwops.c, it appears that I had some of the arguments to Read and Write backwards, causing unexpected return values. Fixed now.