mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-01-13 06:09:11 +00:00
Merge branch 'Ryujinx:master' into features/crash-verification-ex
This commit is contained in:
commit
cd765abf49
88 changed files with 565 additions and 3232 deletions
8
.github/assign/audio.yml
vendored
8
.github/assign/audio.yml
vendored
|
@ -1,8 +0,0 @@
|
||||||
addReviewers: true
|
|
||||||
|
|
||||||
reviewers:
|
|
||||||
- marysaka
|
|
||||||
|
|
||||||
filterLabels:
|
|
||||||
include:
|
|
||||||
- audio
|
|
11
.github/assign/cpu.yml
vendored
11
.github/assign/cpu.yml
vendored
|
@ -1,11 +0,0 @@
|
||||||
addReviewers: true
|
|
||||||
|
|
||||||
reviewers:
|
|
||||||
- gdkchan
|
|
||||||
- riperiperi
|
|
||||||
- marysaka
|
|
||||||
- LDj3SNuD
|
|
||||||
|
|
||||||
filterLabels:
|
|
||||||
include:
|
|
||||||
- cpu
|
|
4
.github/assign/global.yml
vendored
4
.github/assign/global.yml
vendored
|
@ -1,4 +0,0 @@
|
||||||
addReviewers: true
|
|
||||||
|
|
||||||
reviewers:
|
|
||||||
- Ryujinx/developers
|
|
10
.github/assign/gpu.yml
vendored
10
.github/assign/gpu.yml
vendored
|
@ -1,10 +0,0 @@
|
||||||
addReviewers: true
|
|
||||||
|
|
||||||
reviewers:
|
|
||||||
- gdkchan
|
|
||||||
- riperiperi
|
|
||||||
- marysaka
|
|
||||||
|
|
||||||
filterLabels:
|
|
||||||
include:
|
|
||||||
- gpu
|
|
11
.github/assign/gui.yml
vendored
11
.github/assign/gui.yml
vendored
|
@ -1,11 +0,0 @@
|
||||||
addReviewers: true
|
|
||||||
|
|
||||||
reviewers:
|
|
||||||
- Ack77
|
|
||||||
- emmauss
|
|
||||||
- TSRBerry
|
|
||||||
- marysaka
|
|
||||||
|
|
||||||
filterLabels:
|
|
||||||
include:
|
|
||||||
- gui
|
|
11
.github/assign/horizon.yml
vendored
11
.github/assign/horizon.yml
vendored
|
@ -1,11 +0,0 @@
|
||||||
addReviewers: true
|
|
||||||
|
|
||||||
reviewers:
|
|
||||||
- gdkchan
|
|
||||||
- Ack77
|
|
||||||
- marysaka
|
|
||||||
- TSRBerry
|
|
||||||
|
|
||||||
filterLabels:
|
|
||||||
include:
|
|
||||||
- horizon
|
|
9
.github/assign/infra.yml
vendored
9
.github/assign/infra.yml
vendored
|
@ -1,9 +0,0 @@
|
||||||
addReviewers: true
|
|
||||||
|
|
||||||
reviewers:
|
|
||||||
- marysaka
|
|
||||||
- TSRBerry
|
|
||||||
|
|
||||||
filterLabels:
|
|
||||||
include:
|
|
||||||
- infra
|
|
32
.github/reviewers.yml
vendored
Normal file
32
.github/reviewers.yml
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
audio:
|
||||||
|
- marysaka
|
||||||
|
|
||||||
|
cpu:
|
||||||
|
- gdkchan
|
||||||
|
- riperiperi
|
||||||
|
- marysaka
|
||||||
|
- LDj3SNuD
|
||||||
|
|
||||||
|
gpu:
|
||||||
|
- gdkchan
|
||||||
|
- riperiperi
|
||||||
|
- marysaka
|
||||||
|
|
||||||
|
gui:
|
||||||
|
- Ack77
|
||||||
|
- emmauss
|
||||||
|
- TSRBerry
|
||||||
|
- marysaka
|
||||||
|
|
||||||
|
horizon:
|
||||||
|
- gdkchan
|
||||||
|
- Ack77
|
||||||
|
- marysaka
|
||||||
|
- TSRBerry
|
||||||
|
|
||||||
|
infra:
|
||||||
|
- marysaka
|
||||||
|
- TSRBerry
|
||||||
|
|
||||||
|
default:
|
||||||
|
- "@developers"
|
79
.github/update_reviewers.py
vendored
Normal file
79
.github/update_reviewers.py
vendored
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import List, Set
|
||||||
|
from github import Github
|
||||||
|
from github.Repository import Repository
|
||||||
|
from github.GithubException import GithubException
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
|
||||||
|
def add_reviewers(
|
||||||
|
reviewers: Set[str], team_reviewers: Set[str], new_entries: List[str]
|
||||||
|
):
|
||||||
|
for reviewer in new_entries:
|
||||||
|
if reviewer.startswith("@"):
|
||||||
|
team_reviewers.add(reviewer[1:])
|
||||||
|
else:
|
||||||
|
reviewers.add(reviewer)
|
||||||
|
|
||||||
|
|
||||||
|
def update_reviewers(config, repo: Repository, pr_id: int) -> int:
|
||||||
|
pull_request = repo.get_pull(pr_id)
|
||||||
|
|
||||||
|
if not pull_request:
|
||||||
|
sys.stderr.writable(f"Unknown PR #{pr_id}\n")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
pull_request_author = pull_request.user.login
|
||||||
|
reviewers = set()
|
||||||
|
team_reviewers = set()
|
||||||
|
|
||||||
|
for label in pull_request.labels:
|
||||||
|
if label.name in config:
|
||||||
|
add_reviewers(reviewers, team_reviewers, config[label.name])
|
||||||
|
|
||||||
|
if "default" in config:
|
||||||
|
add_reviewers(reviewers, team_reviewers, config["default"])
|
||||||
|
|
||||||
|
if pull_request_author in reviewers:
|
||||||
|
reviewers.remove(pull_request_author)
|
||||||
|
|
||||||
|
try:
|
||||||
|
reviewers = list(reviewers)
|
||||||
|
team_reviewers = list(team_reviewers)
|
||||||
|
print(
|
||||||
|
f"Attempting to assign reviewers ({reviewers}) and team_reviewers ({team_reviewers})"
|
||||||
|
)
|
||||||
|
pull_request.create_review_request(reviewers, team_reviewers)
|
||||||
|
return 0
|
||||||
|
except GithubException as e:
|
||||||
|
sys.stderr.write(f"Cannot assign review request for PR #{pr_id}: {e}\n")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) != 5:
|
||||||
|
sys.stderr.write("usage: <token> <repo_path> <pr_id> <config_path>\n")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
token = sys.argv[1]
|
||||||
|
repo_path = sys.argv[2]
|
||||||
|
pr_id = int(sys.argv[3])
|
||||||
|
config_path = Path(sys.argv[4])
|
||||||
|
|
||||||
|
g = Github(token)
|
||||||
|
repo = g.get_repo(repo_path)
|
||||||
|
|
||||||
|
if not repo:
|
||||||
|
sys.stderr.write("Repository not found!\n")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if not config_path.exists():
|
||||||
|
sys.stderr.write(f'Config "{config_path}" not found!\n')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
with open(config_path, "r") as f:
|
||||||
|
config = yaml.safe_load(f)
|
||||||
|
|
||||||
|
sys.exit(update_reviewers(config, repo, pr_id))
|
48
.github/workflows/pr_triage.yml
vendored
48
.github/workflows/pr_triage.yml
vendored
|
@ -12,43 +12,23 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
# Grab sources to get update_reviewers.py and reviewers.yml
|
||||||
|
- name: Fetch sources
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
# Ensure we pin the source origin as pull_request_target run under forks.
|
||||||
|
fetch-depth: 0
|
||||||
|
repository: Ryujinx/Ryujinx
|
||||||
|
ref: master
|
||||||
|
|
||||||
- name: Update labels based on changes
|
- name: Update labels based on changes
|
||||||
uses: actions/labeler@v4
|
uses: actions/labeler@v4
|
||||||
with:
|
with:
|
||||||
sync-labels: true
|
sync-labels: true
|
||||||
dot: true
|
dot: true
|
||||||
|
|
||||||
- name: Auto Assign [Audio]
|
- name: Assign reviewers
|
||||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
run: |
|
||||||
with:
|
pip3 install PyGithub
|
||||||
configuration-path: '.github/assign/audio.yml'
|
python3 .github/update_reviewers.py ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${{ github.event.pull_request.number }} .github/reviewers.yml
|
||||||
|
shell: bash
|
||||||
- name: Auto Assign [CPU]
|
|
||||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
|
||||||
with:
|
|
||||||
configuration-path: '.github/assign/cpu.yml'
|
|
||||||
|
|
||||||
- name: Auto Assign [GPU]
|
|
||||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
|
||||||
with:
|
|
||||||
configuration-path: '.github/assign/gpu.yml'
|
|
||||||
|
|
||||||
- name: Auto Assign [GUI]
|
|
||||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
|
||||||
with:
|
|
||||||
configuration-path: '.github/assign/gui.yml'
|
|
||||||
|
|
||||||
- name: Auto Assign [Horizon]
|
|
||||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
|
||||||
with:
|
|
||||||
configuration-path: '.github/assign/horizon.yml'
|
|
||||||
|
|
||||||
- name: Auto Assign [Infra]
|
|
||||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
|
||||||
with:
|
|
||||||
configuration-path: '.github/assign/infra.yml'
|
|
||||||
|
|
||||||
- name: Auto Assign [Global]
|
|
||||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
|
||||||
with:
|
|
||||||
configuration-path: '.github/assign/global.yml'
|
|
||||||
|
|
|
@ -79,7 +79,6 @@ namespace Ryujinx.Graphics.GAL
|
||||||
|
|
||||||
void SetRasterizerDiscard(bool discard);
|
void SetRasterizerDiscard(bool discard);
|
||||||
|
|
||||||
void SetRenderTargetScale(float scale);
|
|
||||||
void SetRenderTargetColorMasks(ReadOnlySpan<uint> componentMask);
|
void SetRenderTargetColorMasks(ReadOnlySpan<uint> componentMask);
|
||||||
void SetRenderTargets(ITexture[] colors, ITexture depthStencil);
|
void SetRenderTargets(ITexture[] colors, ITexture depthStencil);
|
||||||
|
|
||||||
|
@ -99,7 +98,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs);
|
void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs);
|
||||||
void SetVertexBuffers(ReadOnlySpan<VertexBufferDescriptor> vertexBuffers);
|
void SetVertexBuffers(ReadOnlySpan<VertexBufferDescriptor> vertexBuffers);
|
||||||
|
|
||||||
void SetViewports(ReadOnlySpan<Viewport> viewports, bool disableTransform);
|
void SetViewports(ReadOnlySpan<Viewport> viewports);
|
||||||
|
|
||||||
void TextureBarrier();
|
void TextureBarrier();
|
||||||
void TextureBarrierTiled();
|
void TextureBarrierTiled();
|
||||||
|
@ -107,7 +106,5 @@ namespace Ryujinx.Graphics.GAL
|
||||||
bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual);
|
bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual);
|
||||||
bool TryHostConditionalRendering(ICounterEvent value, ICounterEvent compare, bool isEqual);
|
bool TryHostConditionalRendering(ICounterEvent value, ICounterEvent compare, bool isEqual);
|
||||||
void EndHostConditionalRendering();
|
void EndHostConditionalRendering();
|
||||||
|
|
||||||
void UpdateRenderScale(ReadOnlySpan<float> scales, int totalCount, int fragmentCount);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ namespace Ryujinx.Graphics.GAL
|
||||||
void BackgroundContextAction(Action action, bool alwaysBackground = false);
|
void BackgroundContextAction(Action action, bool alwaysBackground = false);
|
||||||
|
|
||||||
BufferHandle CreateBuffer(int size, BufferHandle storageHint);
|
BufferHandle CreateBuffer(int size, BufferHandle storageHint);
|
||||||
|
|
||||||
BufferHandle CreateBuffer(int size)
|
BufferHandle CreateBuffer(int size)
|
||||||
{
|
{
|
||||||
return CreateBuffer(size, BufferHandle.Null);
|
return CreateBuffer(size, BufferHandle.Null);
|
||||||
|
@ -28,7 +27,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info);
|
IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info);
|
||||||
|
|
||||||
ISampler CreateSampler(SamplerCreateInfo info);
|
ISampler CreateSampler(SamplerCreateInfo info);
|
||||||
ITexture CreateTexture(TextureCreateInfo info, float scale);
|
ITexture CreateTexture(TextureCreateInfo info);
|
||||||
bool PrepareHostMapping(nint address, ulong size);
|
bool PrepareHostMapping(nint address, ulong size);
|
||||||
|
|
||||||
void CreateSync(ulong id, bool strict);
|
void CreateSync(ulong id, bool strict);
|
||||||
|
@ -49,7 +48,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
|
|
||||||
void PreFrame();
|
void PreFrame();
|
||||||
|
|
||||||
ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, bool hostReserved);
|
ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, float divisor, bool hostReserved);
|
||||||
|
|
||||||
void ResetCounter(CounterType type);
|
void ResetCounter(CounterType type);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ namespace Ryujinx.Graphics.GAL
|
||||||
{
|
{
|
||||||
int Width { get; }
|
int Width { get; }
|
||||||
int Height { get; }
|
int Height { get; }
|
||||||
float ScaleFactor { get; }
|
|
||||||
|
|
||||||
void CopyTo(ITexture destination, int firstLayer, int firstLevel);
|
void CopyTo(ITexture destination, int firstLayer, int firstLevel);
|
||||||
void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel);
|
void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel);
|
||||||
|
|
|
@ -125,7 +125,6 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
Register<SetProgramCommand>(CommandType.SetProgram);
|
Register<SetProgramCommand>(CommandType.SetProgram);
|
||||||
Register<SetRasterizerDiscardCommand>(CommandType.SetRasterizerDiscard);
|
Register<SetRasterizerDiscardCommand>(CommandType.SetRasterizerDiscard);
|
||||||
Register<SetRenderTargetColorMasksCommand>(CommandType.SetRenderTargetColorMasks);
|
Register<SetRenderTargetColorMasksCommand>(CommandType.SetRenderTargetColorMasks);
|
||||||
Register<SetRenderTargetScaleCommand>(CommandType.SetRenderTargetScale);
|
|
||||||
Register<SetRenderTargetsCommand>(CommandType.SetRenderTargets);
|
Register<SetRenderTargetsCommand>(CommandType.SetRenderTargets);
|
||||||
Register<SetScissorsCommand>(CommandType.SetScissor);
|
Register<SetScissorsCommand>(CommandType.SetScissor);
|
||||||
Register<SetStencilTestCommand>(CommandType.SetStencilTest);
|
Register<SetStencilTestCommand>(CommandType.SetStencilTest);
|
||||||
|
@ -138,7 +137,6 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
Register<TextureBarrierTiledCommand>(CommandType.TextureBarrierTiled);
|
Register<TextureBarrierTiledCommand>(CommandType.TextureBarrierTiled);
|
||||||
Register<TryHostConditionalRenderingCommand>(CommandType.TryHostConditionalRendering);
|
Register<TryHostConditionalRenderingCommand>(CommandType.TryHostConditionalRendering);
|
||||||
Register<TryHostConditionalRenderingFlushCommand>(CommandType.TryHostConditionalRenderingFlush);
|
Register<TryHostConditionalRenderingFlushCommand>(CommandType.TryHostConditionalRenderingFlush);
|
||||||
Register<UpdateRenderScaleCommand>(CommandType.UpdateRenderScale);
|
|
||||||
|
|
||||||
return maxCommandSize;
|
return maxCommandSize;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,6 @@
|
||||||
SetProgram,
|
SetProgram,
|
||||||
SetRasterizerDiscard,
|
SetRasterizerDiscard,
|
||||||
SetRenderTargetColorMasks,
|
SetRenderTargetColorMasks,
|
||||||
SetRenderTargetScale,
|
|
||||||
SetRenderTargets,
|
SetRenderTargets,
|
||||||
SetScissor,
|
SetScissor,
|
||||||
SetStencilTest,
|
SetStencilTest,
|
||||||
|
@ -100,6 +99,5 @@
|
||||||
TextureBarrierTiled,
|
TextureBarrierTiled,
|
||||||
TryHostConditionalRendering,
|
TryHostConditionalRendering,
|
||||||
TryHostConditionalRenderingFlush,
|
TryHostConditionalRenderingFlush,
|
||||||
UpdateRenderScale,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,18 +8,16 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||||
public readonly CommandType CommandType => CommandType.CreateTexture;
|
public readonly CommandType CommandType => CommandType.CreateTexture;
|
||||||
private TableRef<ThreadedTexture> _texture;
|
private TableRef<ThreadedTexture> _texture;
|
||||||
private TextureCreateInfo _info;
|
private TextureCreateInfo _info;
|
||||||
private float _scale;
|
|
||||||
|
|
||||||
public void Set(TableRef<ThreadedTexture> texture, TextureCreateInfo info, float scale)
|
public void Set(TableRef<ThreadedTexture> texture, TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
_texture = texture;
|
_texture = texture;
|
||||||
_info = info;
|
_info = info;
|
||||||
_scale = scale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Run(ref CreateTextureCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
public static void Run(ref CreateTextureCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||||
{
|
{
|
||||||
command._texture.Get(threaded).Base = renderer.CreateTexture(command._info, command._scale);
|
command._texture.Get(threaded).Base = renderer.CreateTexture(command._info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,15 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||||
private TableRef<ThreadedCounterEvent> _event;
|
private TableRef<ThreadedCounterEvent> _event;
|
||||||
private CounterType _type;
|
private CounterType _type;
|
||||||
private TableRef<EventHandler<ulong>> _resultHandler;
|
private TableRef<EventHandler<ulong>> _resultHandler;
|
||||||
|
private float _divisor;
|
||||||
private bool _hostReserved;
|
private bool _hostReserved;
|
||||||
|
|
||||||
public void Set(TableRef<ThreadedCounterEvent> evt, CounterType type, TableRef<EventHandler<ulong>> resultHandler, bool hostReserved)
|
public void Set(TableRef<ThreadedCounterEvent> evt, CounterType type, TableRef<EventHandler<ulong>> resultHandler, float divisor, bool hostReserved)
|
||||||
{
|
{
|
||||||
_event = evt;
|
_event = evt;
|
||||||
_type = type;
|
_type = type;
|
||||||
_resultHandler = resultHandler;
|
_resultHandler = resultHandler;
|
||||||
|
_divisor = divisor;
|
||||||
_hostReserved = hostReserved;
|
_hostReserved = hostReserved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +26,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||||
{
|
{
|
||||||
ThreadedCounterEvent evt = command._event.Get(threaded);
|
ThreadedCounterEvent evt = command._event.Get(threaded);
|
||||||
|
|
||||||
evt.Create(renderer, command._type, command._resultHandler.Get(threaded), command._hostReserved);
|
evt.Create(renderer, command._type, command._resultHandler.Get(threaded), command._divisor, command._hostReserved);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
|
||||||
{
|
|
||||||
struct SetRenderTargetScaleCommand : IGALCommand, IGALCommand<SetRenderTargetScaleCommand>
|
|
||||||
{
|
|
||||||
public readonly CommandType CommandType => CommandType.SetRenderTargetScale;
|
|
||||||
private float _scale;
|
|
||||||
|
|
||||||
public void Set(float scale)
|
|
||||||
{
|
|
||||||
_scale = scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Run(ref SetRenderTargetScaleCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
|
||||||
{
|
|
||||||
renderer.Pipeline.SetRenderTargetScale(command._scale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,18 +7,16 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||||
{
|
{
|
||||||
public readonly CommandType CommandType => CommandType.SetViewports;
|
public readonly CommandType CommandType => CommandType.SetViewports;
|
||||||
private SpanRef<Viewport> _viewports;
|
private SpanRef<Viewport> _viewports;
|
||||||
private bool _disableTransform;
|
|
||||||
|
|
||||||
public void Set(SpanRef<Viewport> viewports, bool disableTransform)
|
public void Set(SpanRef<Viewport> viewports)
|
||||||
{
|
{
|
||||||
_viewports = viewports;
|
_viewports = viewports;
|
||||||
_disableTransform = disableTransform;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Run(ref SetViewportsCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
public static void Run(ref SetViewportsCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||||
{
|
{
|
||||||
ReadOnlySpan<Viewport> viewports = command._viewports.Get(threaded);
|
ReadOnlySpan<Viewport> viewports = command._viewports.Get(threaded);
|
||||||
renderer.Pipeline.SetViewports(viewports, command._disableTransform);
|
renderer.Pipeline.SetViewports(viewports);
|
||||||
command._viewports.Dispose(threaded);
|
command._viewports.Dispose(threaded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
|
||||||
{
|
|
||||||
struct UpdateRenderScaleCommand : IGALCommand, IGALCommand<UpdateRenderScaleCommand>
|
|
||||||
{
|
|
||||||
public readonly CommandType CommandType => CommandType.UpdateRenderScale;
|
|
||||||
private SpanRef<float> _scales;
|
|
||||||
private int _totalCount;
|
|
||||||
private int _fragmentCount;
|
|
||||||
|
|
||||||
public void Set(SpanRef<float> scales, int totalCount, int fragmentCount)
|
|
||||||
{
|
|
||||||
_scales = scales;
|
|
||||||
_totalCount = totalCount;
|
|
||||||
_fragmentCount = fragmentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Run(ref UpdateRenderScaleCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
|
||||||
{
|
|
||||||
renderer.Pipeline.UpdateRenderScale(command._scales.Get(threaded), command._totalCount, command._fragmentCount);
|
|
||||||
command._scales.Dispose(threaded);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -70,10 +70,10 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Create(IRenderer renderer, CounterType type, System.EventHandler<ulong> eventHandler, bool hostReserved)
|
public void Create(IRenderer renderer, CounterType type, System.EventHandler<ulong> eventHandler, float divisor, bool hostReserved)
|
||||||
{
|
{
|
||||||
ThreadedHelpers.SpinUntilExchange(ref _createLock, 1, 0);
|
ThreadedHelpers.SpinUntilExchange(ref _createLock, 1, 0);
|
||||||
Base = renderer.ReportCounter(type, eventHandler, hostReserved || _reserved);
|
Base = renderer.ReportCounter(type, eventHandler, divisor, hostReserved || _reserved);
|
||||||
Volatile.Write(ref _createLock, 0);
|
Volatile.Write(ref _createLock, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,13 +17,10 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
||||||
|
|
||||||
public int Height => _info.Height;
|
public int Height => _info.Height;
|
||||||
|
|
||||||
public float ScaleFactor { get; }
|
public ThreadedTexture(ThreadedRenderer renderer, TextureCreateInfo info)
|
||||||
|
|
||||||
public ThreadedTexture(ThreadedRenderer renderer, TextureCreateInfo info, float scale)
|
|
||||||
{
|
{
|
||||||
_renderer = renderer;
|
_renderer = renderer;
|
||||||
_info = info;
|
_info = info;
|
||||||
ScaleFactor = scale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TableRef<T> Ref<T>(T reference)
|
private TableRef<T> Ref<T>(T reference)
|
||||||
|
@ -64,7 +61,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
||||||
|
|
||||||
public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel)
|
public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel)
|
||||||
{
|
{
|
||||||
ThreadedTexture newTex = new(_renderer, info, ScaleFactor);
|
ThreadedTexture newTex = new(_renderer, info);
|
||||||
_renderer.New<TextureCreateViewCommand>().Set(Ref(this), Ref(newTex), info, firstLayer, firstLevel);
|
_renderer.New<TextureCreateViewCommand>().Set(Ref(this), Ref(newTex), info, firstLayer, firstLevel);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
|
|
||||||
|
|
|
@ -261,12 +261,6 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRenderTargetScale(float scale)
|
|
||||||
{
|
|
||||||
_renderer.New<SetRenderTargetScaleCommand>().Set(scale);
|
|
||||||
_renderer.QueueCommand();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetScissors(ReadOnlySpan<Rectangle<int>> scissors)
|
public void SetScissors(ReadOnlySpan<Rectangle<int>> scissors)
|
||||||
{
|
{
|
||||||
_renderer.New<SetScissorsCommand>().Set(_renderer.CopySpan(scissors));
|
_renderer.New<SetScissorsCommand>().Set(_renderer.CopySpan(scissors));
|
||||||
|
@ -321,9 +315,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetViewports(ReadOnlySpan<Viewport> viewports, bool disableTransform)
|
public void SetViewports(ReadOnlySpan<Viewport> viewports)
|
||||||
{
|
{
|
||||||
_renderer.New<SetViewportsCommand>().Set(_renderer.CopySpan(viewports), disableTransform);
|
_renderer.New<SetViewportsCommand>().Set(_renderer.CopySpan(viewports));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,11 +362,5 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateRenderScale(ReadOnlySpan<float> scales, int totalCount, int fragmentCount)
|
|
||||||
{
|
|
||||||
_renderer.New<UpdateRenderScaleCommand>().Set(_renderer.CopySpan(scales[..totalCount]), totalCount, fragmentCount);
|
|
||||||
_renderer.QueueCommand();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,21 +320,21 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ITexture CreateTexture(TextureCreateInfo info, float scale)
|
public ITexture CreateTexture(TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
if (IsGpuThread())
|
if (IsGpuThread())
|
||||||
{
|
{
|
||||||
var texture = new ThreadedTexture(this, info, scale);
|
var texture = new ThreadedTexture(this, info);
|
||||||
New<CreateTextureCommand>().Set(Ref(texture), info, scale);
|
New<CreateTextureCommand>().Set(Ref(texture), info);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var texture = new ThreadedTexture(this, info, scale)
|
var texture = new ThreadedTexture(this, info)
|
||||||
{
|
{
|
||||||
Base = _baseRenderer.CreateTexture(info, scale),
|
Base = _baseRenderer.CreateTexture(info),
|
||||||
};
|
};
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
|
@ -410,10 +410,10 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, bool hostReserved)
|
public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, float divisor, bool hostReserved)
|
||||||
{
|
{
|
||||||
ThreadedCounterEvent evt = new(this, type, _lastSampleCounterClear);
|
ThreadedCounterEvent evt = new ThreadedCounterEvent(this, type, _lastSampleCounterClear);
|
||||||
New<ReportCounterCommand>().Set(Ref(evt), type, Ref(resultHandler), hostReserved);
|
New<ReportCounterCommand>().Set(Ref(evt), type, Ref(resultHandler), divisor, hostReserved);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
if (type == CounterType.SamplesPassed)
|
if (type == CounterType.SamplesPassed)
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
using Ryujinx.Graphics.Shader;
|
|
||||||
using System;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.GAL
|
|
||||||
{
|
|
||||||
public class SupportBufferUpdater : IDisposable
|
|
||||||
{
|
|
||||||
public SupportBuffer Data;
|
|
||||||
public BufferHandle Handle;
|
|
||||||
|
|
||||||
private readonly IRenderer _renderer;
|
|
||||||
private int _startOffset = -1;
|
|
||||||
private int _endOffset = -1;
|
|
||||||
|
|
||||||
public SupportBufferUpdater(IRenderer renderer)
|
|
||||||
{
|
|
||||||
_renderer = renderer;
|
|
||||||
Handle = renderer.CreateBuffer(SupportBuffer.RequiredSize);
|
|
||||||
renderer.Pipeline.ClearBuffer(Handle, 0, SupportBuffer.RequiredSize, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MarkDirty(int startOffset, int byteSize)
|
|
||||||
{
|
|
||||||
int endOffset = startOffset + byteSize;
|
|
||||||
|
|
||||||
if (_startOffset == -1)
|
|
||||||
{
|
|
||||||
_startOffset = startOffset;
|
|
||||||
_endOffset = endOffset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (startOffset < _startOffset)
|
|
||||||
{
|
|
||||||
_startOffset = startOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (endOffset > _endOffset)
|
|
||||||
{
|
|
||||||
_endOffset = endOffset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateFragmentRenderScaleCount(int count)
|
|
||||||
{
|
|
||||||
if (Data.FragmentRenderScaleCount.X != count)
|
|
||||||
{
|
|
||||||
Data.FragmentRenderScaleCount.X = count;
|
|
||||||
|
|
||||||
MarkDirty(SupportBuffer.FragmentRenderScaleCountOffset, sizeof(int));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateGenericField<T>(int baseOffset, ReadOnlySpan<T> data, Span<T> target, int offset, int count) where T : unmanaged
|
|
||||||
{
|
|
||||||
data[..count].CopyTo(target[offset..]);
|
|
||||||
|
|
||||||
int elemSize = Unsafe.SizeOf<T>();
|
|
||||||
|
|
||||||
MarkDirty(baseOffset + offset * elemSize, count * elemSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateRenderScale(ReadOnlySpan<Vector4<float>> data, int offset, int count)
|
|
||||||
{
|
|
||||||
UpdateGenericField(SupportBuffer.GraphicsRenderScaleOffset, data, Data.RenderScale.AsSpan(), offset, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateFragmentIsBgra(ReadOnlySpan<Vector4<int>> data, int offset, int count)
|
|
||||||
{
|
|
||||||
UpdateGenericField(SupportBuffer.FragmentIsBgraOffset, data, Data.FragmentIsBgra.AsSpan(), offset, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateViewportInverse(Vector4<float> data)
|
|
||||||
{
|
|
||||||
Data.ViewportInverse = data;
|
|
||||||
|
|
||||||
MarkDirty(SupportBuffer.ViewportInverseOffset, SupportBuffer.FieldSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Commit()
|
|
||||||
{
|
|
||||||
if (_startOffset != -1)
|
|
||||||
{
|
|
||||||
ReadOnlySpan<byte> data = MemoryMarshal.Cast<SupportBuffer, byte>(MemoryMarshal.CreateSpan(ref Data, 1));
|
|
||||||
|
|
||||||
_renderer.SetBufferData(Handle, _startOffset, data[_startOffset.._endOffset]);
|
|
||||||
|
|
||||||
_startOffset = -1;
|
|
||||||
_endOffset = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
_renderer.DeleteBuffer(Handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -177,13 +177,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
resultHandler(null, (ulong)_state.State.SemaphorePayload);
|
resultHandler(null, (ulong)_state.State.SemaphorePayload);
|
||||||
break;
|
break;
|
||||||
case ReportCounterType.SamplesPassed:
|
case ReportCounterType.SamplesPassed:
|
||||||
counter = _context.Renderer.ReportCounter(CounterType.SamplesPassed, resultHandler, false);
|
float scale = _channel.TextureManager.RenderTargetScale;
|
||||||
|
float divisor = scale * scale;
|
||||||
|
counter = _context.Renderer.ReportCounter(CounterType.SamplesPassed, resultHandler, divisor, false);
|
||||||
break;
|
break;
|
||||||
case ReportCounterType.PrimitivesGenerated:
|
case ReportCounterType.PrimitivesGenerated:
|
||||||
counter = _context.Renderer.ReportCounter(CounterType.PrimitivesGenerated, resultHandler, false);
|
counter = _context.Renderer.ReportCounter(CounterType.PrimitivesGenerated, resultHandler, 1f, false);
|
||||||
break;
|
break;
|
||||||
case ReportCounterType.TransformFeedbackPrimitivesWritten:
|
case ReportCounterType.TransformFeedbackPrimitivesWritten:
|
||||||
counter = _context.Renderer.ReportCounter(CounterType.TransformFeedbackPrimitivesWritten, resultHandler, false);
|
counter = _context.Renderer.ReportCounter(CounterType.TransformFeedbackPrimitivesWritten, resultHandler, 1f, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -495,6 +495,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
{
|
{
|
||||||
clipRegionHeight = color.Height / samplesInY;
|
clipRegionHeight = color.Height / samplesInY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_context.Capabilities.SupportsBgraFormat)
|
||||||
|
{
|
||||||
|
_context.SupportBufferUpdater.SetRenderTargetIsBgra(index, color.Format.IsBgr());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,7 +544,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
|
|
||||||
if (oldScale != _channel.TextureManager.RenderTargetScale)
|
if (oldScale != _channel.TextureManager.RenderTargetScale)
|
||||||
{
|
{
|
||||||
_context.Renderer.Pipeline.SetRenderTargetScale(_channel.TextureManager.RenderTargetScale);
|
_context.SupportBufferUpdater.SetRenderTargetScale(_channel.TextureManager.RenderTargetScale);
|
||||||
|
|
||||||
UpdateViewportTransform();
|
UpdateViewportTransform();
|
||||||
UpdateScissorState();
|
UpdateScissorState();
|
||||||
|
@ -758,9 +763,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
}
|
}
|
||||||
|
|
||||||
_context.Renderer.Pipeline.SetDepthMode(GetDepthMode());
|
_context.Renderer.Pipeline.SetDepthMode(GetDepthMode());
|
||||||
_context.Renderer.Pipeline.SetViewports(viewports, disableTransform);
|
_context.Renderer.Pipeline.SetViewports(viewports);
|
||||||
|
|
||||||
_currentSpecState.SetViewportTransformDisable(_state.State.ViewportTransformEnable == 0);
|
_context.SupportBufferUpdater.SetViewportTransformDisable(
|
||||||
|
viewports[0].Region.Width,
|
||||||
|
viewports[0].Region.Height,
|
||||||
|
_channel.TextureManager.RenderTargetScale,
|
||||||
|
disableTransform);
|
||||||
|
|
||||||
|
_currentSpecState.SetViewportTransformDisable(disableTransform);
|
||||||
_currentSpecState.SetDepthMode(GetDepthMode() == DepthMode.MinusOneToOne);
|
_currentSpecState.SetDepthMode(GetDepthMode() == DepthMode.MinusOneToOne);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,11 @@ namespace Ryujinx.Graphics.Gpu
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal ConcurrentDictionary<ulong, PhysicalMemory> PhysicalMemoryRegistry { get; }
|
internal ConcurrentDictionary<ulong, PhysicalMemory> PhysicalMemoryRegistry { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Support buffer updater.
|
||||||
|
/// </summary>
|
||||||
|
internal SupportBufferUpdater SupportBufferUpdater { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Host hardware capabilities.
|
/// Host hardware capabilities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -125,6 +130,8 @@ namespace Ryujinx.Graphics.Gpu
|
||||||
|
|
||||||
PhysicalMemoryRegistry = new ConcurrentDictionary<ulong, PhysicalMemory>();
|
PhysicalMemoryRegistry = new ConcurrentDictionary<ulong, PhysicalMemory>();
|
||||||
|
|
||||||
|
SupportBufferUpdater = new SupportBufferUpdater(renderer);
|
||||||
|
|
||||||
_firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
|
_firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,6 +406,8 @@ namespace Ryujinx.Graphics.Gpu
|
||||||
physicalMemory.Dispose();
|
physicalMemory.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SupportBufferUpdater.Dispose();
|
||||||
|
|
||||||
PhysicalMemoryRegistry.Clear();
|
PhysicalMemoryRegistry.Clear();
|
||||||
|
|
||||||
RunDeferredActions();
|
RunDeferredActions();
|
||||||
|
|
|
@ -278,7 +278,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
Debug.Assert(!isView);
|
Debug.Assert(!isView);
|
||||||
|
|
||||||
TextureCreateInfo createInfo = TextureCache.GetCreateInfo(Info, _context.Capabilities, ScaleFactor);
|
TextureCreateInfo createInfo = TextureCache.GetCreateInfo(Info, _context.Capabilities, ScaleFactor);
|
||||||
HostTexture = _context.Renderer.CreateTexture(createInfo, ScaleFactor);
|
HostTexture = _context.Renderer.CreateTexture(createInfo);
|
||||||
|
|
||||||
SynchronizeMemory(); // Load the data.
|
SynchronizeMemory(); // Load the data.
|
||||||
if (ScaleMode == TextureScaleMode.Scaled)
|
if (ScaleMode == TextureScaleMode.Scaled)
|
||||||
|
@ -302,7 +302,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCreateInfo createInfo = TextureCache.GetCreateInfo(Info, _context.Capabilities, ScaleFactor);
|
TextureCreateInfo createInfo = TextureCache.GetCreateInfo(Info, _context.Capabilities, ScaleFactor);
|
||||||
HostTexture = _context.Renderer.CreateTexture(createInfo, ScaleFactor);
|
HostTexture = _context.Renderer.CreateTexture(createInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -490,7 +490,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
if (storage == null)
|
if (storage == null)
|
||||||
{
|
{
|
||||||
TextureCreateInfo createInfo = TextureCache.GetCreateInfo(Info, _context.Capabilities, scale);
|
TextureCreateInfo createInfo = TextureCache.GetCreateInfo(Info, _context.Capabilities, scale);
|
||||||
storage = _context.Renderer.CreateTexture(createInfo, scale);
|
storage = _context.Renderer.CreateTexture(createInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (copy)
|
if (copy)
|
||||||
|
|
|
@ -302,7 +302,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
_lastFragmentTotal = fragmentTotal;
|
_lastFragmentTotal = fragmentTotal;
|
||||||
|
|
||||||
_context.Renderer.Pipeline.UpdateRenderScale(_scales, total, fragmentTotal);
|
_context.SupportBufferUpdater.UpdateRenderScale(_scales, total, fragmentTotal);
|
||||||
|
|
||||||
_scaleChanged = false;
|
_scaleChanged = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -478,6 +478,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
|
|
||||||
// Force rebind after doing compute work.
|
// Force rebind after doing compute work.
|
||||||
Rebind();
|
Rebind();
|
||||||
|
|
||||||
|
_context.SupportBufferUpdater.Commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -686,6 +688,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
CommitBufferTextureBindings();
|
CommitBufferTextureBindings();
|
||||||
|
|
||||||
_rebind = false;
|
_rebind = false;
|
||||||
|
|
||||||
|
_context.SupportBufferUpdater.Commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
232
src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs
Normal file
232
src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
using Ryujinx.Graphics.GAL;
|
||||||
|
using Ryujinx.Graphics.Shader;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Support buffer data updater.
|
||||||
|
/// </summary>
|
||||||
|
class SupportBufferUpdater : IDisposable
|
||||||
|
{
|
||||||
|
private SupportBuffer _data;
|
||||||
|
private BufferHandle _handle;
|
||||||
|
|
||||||
|
private readonly IRenderer _renderer;
|
||||||
|
private int _startOffset = -1;
|
||||||
|
private int _endOffset = -1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the support buffer updater.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="renderer">Renderer that the support buffer will be used with</param>
|
||||||
|
public SupportBufferUpdater(IRenderer renderer)
|
||||||
|
{
|
||||||
|
_renderer = renderer;
|
||||||
|
|
||||||
|
var defaultScale = new Vector4<float> { X = 1f, Y = 0f, Z = 0f, W = 0f };
|
||||||
|
_data.RenderScale.AsSpan().Fill(defaultScale);
|
||||||
|
DirtyRenderScale(0, SupportBuffer.RenderScaleMaxCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Mark a region of the support buffer as modified and needing to be sent to the GPU.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="startOffset">Start offset of the region in bytes</param>
|
||||||
|
/// <param name="byteSize">Size of the region in bytes</param>
|
||||||
|
private void MarkDirty(int startOffset, int byteSize)
|
||||||
|
{
|
||||||
|
int endOffset = startOffset + byteSize;
|
||||||
|
|
||||||
|
if (_startOffset == -1)
|
||||||
|
{
|
||||||
|
_startOffset = startOffset;
|
||||||
|
_endOffset = endOffset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (startOffset < _startOffset)
|
||||||
|
{
|
||||||
|
_startOffset = startOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endOffset > _endOffset)
|
||||||
|
{
|
||||||
|
_endOffset = endOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Marks the fragment render scale count as being modified.
|
||||||
|
/// </summary>
|
||||||
|
private void DirtyFragmentRenderScaleCount()
|
||||||
|
{
|
||||||
|
MarkDirty(SupportBuffer.FragmentRenderScaleCountOffset, sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Marks data of a given type as being modified.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type of the data</typeparam>
|
||||||
|
/// <param name="baseOffset">Base offset of the data in bytes</param>
|
||||||
|
/// <param name="offset">Index of the data, in elements</param>
|
||||||
|
/// <param name="count">Number of elements</param>
|
||||||
|
private void DirtyGenericField<T>(int baseOffset, int offset, int count) where T : unmanaged
|
||||||
|
{
|
||||||
|
int elemSize = Unsafe.SizeOf<T>();
|
||||||
|
|
||||||
|
MarkDirty(baseOffset + offset * elemSize, count * elemSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Marks render scales as being modified.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offset">Index of the first scale that was modified</param>
|
||||||
|
/// <param name="count">Number of modified scales</param>
|
||||||
|
private void DirtyRenderScale(int offset, int count)
|
||||||
|
{
|
||||||
|
DirtyGenericField<Vector4<float>>(SupportBuffer.GraphicsRenderScaleOffset, offset, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Marks render target BGRA format state as modified.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offset">Index of the first render target that had its BGRA format modified</param>
|
||||||
|
/// <param name="count">Number of render targets</param>
|
||||||
|
private void DirtyFragmentIsBgra(int offset, int count)
|
||||||
|
{
|
||||||
|
DirtyGenericField<Vector4<int>>(SupportBuffer.FragmentIsBgraOffset, offset, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the inverse viewport vector.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">Inverse viewport vector</param>
|
||||||
|
private void UpdateViewportInverse(Vector4<float> data)
|
||||||
|
{
|
||||||
|
_data.ViewportInverse = data;
|
||||||
|
|
||||||
|
MarkDirty(SupportBuffer.ViewportInverseOffset, SupportBuffer.FieldSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the scale of all output render targets (they should all have the same scale).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scale">Scale value</param>
|
||||||
|
public void SetRenderTargetScale(float scale)
|
||||||
|
{
|
||||||
|
_data.RenderScale[0].X = scale;
|
||||||
|
DirtyRenderScale(0, 1); // Just the first element.
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the render scales for shader input textures or images.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scales">Scale values</param>
|
||||||
|
/// <param name="totalCount">Total number of scales across all stages</param>
|
||||||
|
/// <param name="fragmentCount">Total number of scales on the fragment shader stage</param>
|
||||||
|
public void UpdateRenderScale(ReadOnlySpan<float> scales, int totalCount, int fragmentCount)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
for (int index = 0; index < totalCount; index++)
|
||||||
|
{
|
||||||
|
if (_data.RenderScale[1 + index].X != scales[index])
|
||||||
|
{
|
||||||
|
_data.RenderScale[1 + index].X = scales[index];
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only update fragment count if there are scales after it for the vertex stage.
|
||||||
|
if (fragmentCount != totalCount && fragmentCount != _data.FragmentRenderScaleCount.X)
|
||||||
|
{
|
||||||
|
_data.FragmentRenderScaleCount.X = fragmentCount;
|
||||||
|
DirtyFragmentRenderScaleCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
DirtyRenderScale(0, 1 + totalCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets whether the format of a given render target is a BGRA format.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">Render target index</param>
|
||||||
|
/// <param name="isBgra">True if the format is BGRA< false otherwise</param>
|
||||||
|
public void SetRenderTargetIsBgra(int index, bool isBgra)
|
||||||
|
{
|
||||||
|
bool isBgraChanged = (_data.FragmentIsBgra[index].X != 0) != isBgra;
|
||||||
|
|
||||||
|
if (isBgraChanged)
|
||||||
|
{
|
||||||
|
_data.FragmentIsBgra[index].X = isBgra ? 1 : 0;
|
||||||
|
DirtyFragmentIsBgra(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets whether a viewport has transform disabled.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="viewportWidth">Value used as viewport width</param>
|
||||||
|
/// <param name="viewportHeight">Value used as viewport height</param>
|
||||||
|
/// <param name="scale">Render target scale</param>
|
||||||
|
/// <param name="disableTransform">True if transform is disabled, false otherwise</param>
|
||||||
|
public void SetViewportTransformDisable(float viewportWidth, float viewportHeight, float scale, bool disableTransform)
|
||||||
|
{
|
||||||
|
float disableTransformF = disableTransform ? 1.0f : 0.0f;
|
||||||
|
if (_data.ViewportInverse.W != disableTransformF || disableTransform)
|
||||||
|
{
|
||||||
|
UpdateViewportInverse(new Vector4<float>
|
||||||
|
{
|
||||||
|
X = scale * 2f / viewportWidth,
|
||||||
|
Y = scale * 2f / viewportHeight,
|
||||||
|
Z = 1,
|
||||||
|
W = disableTransformF
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Submits all pending buffer updates to the GPU.
|
||||||
|
/// </summary>
|
||||||
|
public void Commit()
|
||||||
|
{
|
||||||
|
if (_startOffset != -1)
|
||||||
|
{
|
||||||
|
if (_handle == BufferHandle.Null)
|
||||||
|
{
|
||||||
|
_handle = _renderer.CreateBuffer(SupportBuffer.RequiredSize);
|
||||||
|
_renderer.Pipeline.ClearBuffer(_handle, 0, SupportBuffer.RequiredSize, 0);
|
||||||
|
|
||||||
|
var range = new BufferRange(_handle, 0, SupportBuffer.RequiredSize);
|
||||||
|
_renderer.Pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, range) });
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadOnlySpan<byte> data = MemoryMarshal.Cast<SupportBuffer, byte>(MemoryMarshal.CreateSpan(ref _data, 1));
|
||||||
|
|
||||||
|
_renderer.SetBufferData(_handle, _startOffset, data.Slice(_startOffset, _endOffset - _startOffset));
|
||||||
|
|
||||||
|
_startOffset = -1;
|
||||||
|
_endOffset = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Destroys the support buffer.
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_handle != BufferHandle.Null)
|
||||||
|
{
|
||||||
|
_renderer.DeleteBuffer(_handle);
|
||||||
|
_handle = BufferHandle.Null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -58,6 +58,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
}
|
}
|
||||||
|
|
||||||
AddDescriptor(SupportBufferStages, ResourceType.UniformBuffer, UniformSetIndex, 0, 1);
|
AddDescriptor(SupportBufferStages, ResourceType.UniformBuffer, UniformSetIndex, 0, 1);
|
||||||
|
AddUsage(SupportBufferStages, ResourceType.UniformBuffer, ResourceAccess.Read, UniformSetIndex, 0, 1);
|
||||||
|
|
||||||
_reservedConstantBuffers = 1; // For the support buffer.
|
_reservedConstantBuffers = 1; // For the support buffer.
|
||||||
|
|
||||||
|
|
|
@ -208,7 +208,16 @@ namespace Ryujinx.Graphics.Gpu
|
||||||
|
|
||||||
texture.SynchronizeMemory();
|
texture.SynchronizeMemory();
|
||||||
|
|
||||||
ImageCrop crop = pt.Crop;
|
ImageCrop crop = new ImageCrop(
|
||||||
|
(int)(pt.Crop.Left * texture.ScaleFactor),
|
||||||
|
(int)MathF.Ceiling(pt.Crop.Right * texture.ScaleFactor),
|
||||||
|
(int)(pt.Crop.Top * texture.ScaleFactor),
|
||||||
|
(int)MathF.Ceiling(pt.Crop.Bottom * texture.ScaleFactor),
|
||||||
|
pt.Crop.FlipX,
|
||||||
|
pt.Crop.FlipY,
|
||||||
|
pt.Crop.IsStretched,
|
||||||
|
pt.Crop.AspectRatioX,
|
||||||
|
pt.Crop.AspectRatioY);
|
||||||
|
|
||||||
if (texture.Info.Width > pt.Info.Width || texture.Info.Height > pt.Info.Height)
|
if (texture.Info.Width > pt.Info.Width || texture.Info.Height > pt.Info.Height)
|
||||||
{
|
{
|
||||||
|
|
|
@ -114,7 +114,7 @@ namespace Ryujinx.Graphics.OpenGL.Effects
|
||||||
originalInfo.SwizzleB,
|
originalInfo.SwizzleB,
|
||||||
originalInfo.SwizzleA);
|
originalInfo.SwizzleA);
|
||||||
|
|
||||||
_intermediaryTexture = new TextureStorage(_renderer, info, view.ScaleFactor);
|
_intermediaryTexture = new TextureStorage(_renderer, info);
|
||||||
_intermediaryTexture.CreateDefaultView();
|
_intermediaryTexture.CreateDefaultView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.OpenGL.Effects
|
||||||
if (_textureStorage == null || _textureStorage.Info.Width != view.Width || _textureStorage.Info.Height != view.Height)
|
if (_textureStorage == null || _textureStorage.Info.Width != view.Width || _textureStorage.Info.Height != view.Height)
|
||||||
{
|
{
|
||||||
_textureStorage?.Dispose();
|
_textureStorage?.Dispose();
|
||||||
_textureStorage = new TextureStorage(_renderer, view.Info, view.ScaleFactor);
|
_textureStorage = new TextureStorage(_renderer, view.Info);
|
||||||
_textureStorage.CreateDefaultView();
|
_textureStorage.CreateDefaultView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,8 +147,8 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
|
||||||
SwizzleComponent.Blue,
|
SwizzleComponent.Blue,
|
||||||
SwizzleComponent.Alpha);
|
SwizzleComponent.Alpha);
|
||||||
|
|
||||||
_areaTexture = new TextureStorage(_renderer, areaInfo, 1);
|
_areaTexture = new TextureStorage(_renderer, areaInfo);
|
||||||
_searchTexture = new TextureStorage(_renderer, searchInfo, 1);
|
_searchTexture = new TextureStorage(_renderer, searchInfo);
|
||||||
|
|
||||||
var areaTexture = EmbeddedResources.Read("Ryujinx.Graphics.OpenGL/Effects/Textures/SmaaAreaTexture.bin");
|
var areaTexture = EmbeddedResources.Read("Ryujinx.Graphics.OpenGL/Effects/Textures/SmaaAreaTexture.bin");
|
||||||
var searchTexture = EmbeddedResources.Read("Ryujinx.Graphics.OpenGL/Effects/Textures/SmaaSearchTexture.bin");
|
var searchTexture = EmbeddedResources.Read("Ryujinx.Graphics.OpenGL/Effects/Textures/SmaaSearchTexture.bin");
|
||||||
|
@ -165,11 +165,11 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
|
||||||
if (_outputTexture == null || _outputTexture.Info.Width != view.Width || _outputTexture.Info.Height != view.Height)
|
if (_outputTexture == null || _outputTexture.Info.Width != view.Width || _outputTexture.Info.Height != view.Height)
|
||||||
{
|
{
|
||||||
_outputTexture?.Dispose();
|
_outputTexture?.Dispose();
|
||||||
_outputTexture = new TextureStorage(_renderer, view.Info, view.ScaleFactor);
|
_outputTexture = new TextureStorage(_renderer, view.Info);
|
||||||
_outputTexture.CreateDefaultView();
|
_outputTexture.CreateDefaultView();
|
||||||
_edgeOutputTexture = new TextureStorage(_renderer, view.Info, view.ScaleFactor);
|
_edgeOutputTexture = new TextureStorage(_renderer, view.Info);
|
||||||
_edgeOutputTexture.CreateDefaultView();
|
_edgeOutputTexture.CreateDefaultView();
|
||||||
_blendOutputTexture = new TextureStorage(_renderer, view.Info, view.ScaleFactor);
|
_blendOutputTexture = new TextureStorage(_renderer, view.Info);
|
||||||
_blendOutputTexture.CreateDefaultView();
|
_blendOutputTexture.CreateDefaultView();
|
||||||
|
|
||||||
DeleteShaders();
|
DeleteShaders();
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
||||||
SwizzleComponent.Red,
|
SwizzleComponent.Red,
|
||||||
SwizzleComponent.Green,
|
SwizzleComponent.Green,
|
||||||
SwizzleComponent.Blue,
|
SwizzleComponent.Blue,
|
||||||
SwizzleComponent.Alpha), 1f);
|
SwizzleComponent.Alpha));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
|
@ -11,15 +11,13 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
||||||
|
|
||||||
public int Width => Info.Width;
|
public int Width => Info.Width;
|
||||||
public int Height => Info.Height;
|
public int Height => Info.Height;
|
||||||
public float ScaleFactor { get; }
|
|
||||||
|
|
||||||
public Target Target => Info.Target;
|
public Target Target => Info.Target;
|
||||||
public Format Format => Info.Format;
|
public Format Format => Info.Format;
|
||||||
|
|
||||||
public TextureBase(TextureCreateInfo info, float scaleFactor = 1f)
|
public TextureBase(TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
Info = info;
|
Info = info;
|
||||||
ScaleFactor = scaleFactor;
|
|
||||||
|
|
||||||
Handle = GL.GenTexture();
|
Handle = GL.GenTexture();
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,7 +349,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
||||||
|
|
||||||
public TextureView BgraSwap(TextureView from)
|
public TextureView BgraSwap(TextureView from)
|
||||||
{
|
{
|
||||||
TextureView to = (TextureView)_renderer.CreateTexture(from.Info, from.ScaleFactor);
|
TextureView to = (TextureView)_renderer.CreateTexture(from.Info);
|
||||||
|
|
||||||
EnsurePbo(from);
|
EnsurePbo(from);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
||||||
{
|
{
|
||||||
public ITextureInfo Storage => this;
|
public ITextureInfo Storage => this;
|
||||||
public int Handle { get; private set; }
|
public int Handle { get; private set; }
|
||||||
public float ScaleFactor { get; private set; }
|
|
||||||
|
|
||||||
public TextureCreateInfo Info { get; }
|
public TextureCreateInfo Info { get; }
|
||||||
|
|
||||||
|
@ -18,13 +17,12 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
||||||
|
|
||||||
internal ITexture DefaultView { get; private set; }
|
internal ITexture DefaultView { get; private set; }
|
||||||
|
|
||||||
public TextureStorage(OpenGLRenderer renderer, TextureCreateInfo info, float scaleFactor)
|
public TextureStorage(OpenGLRenderer renderer, TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
_renderer = renderer;
|
_renderer = renderer;
|
||||||
Info = info;
|
Info = info;
|
||||||
|
|
||||||
Handle = GL.GenTexture();
|
Handle = GL.GenTexture();
|
||||||
ScaleFactor = scaleFactor;
|
|
||||||
|
|
||||||
CreateImmutableStorage();
|
CreateImmutableStorage();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
||||||
TextureStorage parent,
|
TextureStorage parent,
|
||||||
TextureCreateInfo info,
|
TextureCreateInfo info,
|
||||||
int firstLayer,
|
int firstLayer,
|
||||||
int firstLevel) : base(info, parent.ScaleFactor)
|
int firstLevel) : base(info)
|
||||||
{
|
{
|
||||||
_renderer = renderer;
|
_renderer = renderer;
|
||||||
_parent = parent;
|
_parent = parent;
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
return new Sampler(info);
|
return new Sampler(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ITexture CreateTexture(TextureCreateInfo info, float scaleFactor)
|
public ITexture CreateTexture(TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
if (info.Target == Target.TextureBuffer)
|
if (info.Target == Target.TextureBuffer)
|
||||||
{
|
{
|
||||||
|
@ -103,7 +103,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return ResourcePool.GetTextureOrNull(info, scaleFactor) ?? new TextureStorage(this, info, scaleFactor).CreateDefaultView();
|
return ResourcePool.GetTextureOrNull(info) ?? new TextureStorage(this, info).CreateDefaultView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,9 +194,9 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
ResourcePool.Tick();
|
ResourcePool.Tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, bool hostReserved)
|
public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, float divisor, bool hostReserved)
|
||||||
{
|
{
|
||||||
return _counters.QueueReport(type, resultHandler, _pipeline.DrawCount, hostReserved);
|
return _counters.QueueReport(type, resultHandler, divisor, _pipeline.DrawCount, hostReserved);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(GraphicsDebugLevel glLogLevel)
|
public void Initialize(GraphicsDebugLevel glLogLevel)
|
||||||
|
@ -210,7 +210,6 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
GL.Arb.MaxShaderCompilerThreads(Math.Min(Environment.ProcessorCount, 8));
|
GL.Arb.MaxShaderCompilerThreads(Math.Min(Environment.ProcessorCount, 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
_pipeline.Initialize(this);
|
|
||||||
_counters.Initialize(_pipeline);
|
_counters.Initialize(_pipeline);
|
||||||
|
|
||||||
// This is required to disable [0, 1] clamping for SNorm outputs on compatibility profiles.
|
// This is required to disable [0, 1] clamping for SNorm outputs on compatibility profiles.
|
||||||
|
|
|
@ -44,9 +44,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
private CounterQueueEvent _activeConditionalRender;
|
private CounterQueueEvent _activeConditionalRender;
|
||||||
|
|
||||||
private readonly Vector4<int>[] _fpIsBgra = new Vector4<int>[SupportBuffer.FragmentIsBgraCount];
|
private Vector4<int>[] _fpIsBgra = new Vector4<int>[SupportBuffer.FragmentIsBgraCount];
|
||||||
private readonly Vector4<float>[] _renderScale = new Vector4<float>[73];
|
|
||||||
private int _fragmentScaleCount;
|
|
||||||
|
|
||||||
private readonly (TextureBase, Format)[] _images;
|
private readonly (TextureBase, Format)[] _images;
|
||||||
private TextureBase _unit0Texture;
|
private TextureBase _unit0Texture;
|
||||||
|
@ -66,7 +64,6 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
private bool _tfEnabled;
|
private bool _tfEnabled;
|
||||||
private TransformFeedbackPrimitiveType _tfTopology;
|
private TransformFeedbackPrimitiveType _tfTopology;
|
||||||
|
|
||||||
private SupportBufferUpdater _supportBuffer;
|
|
||||||
private readonly BufferHandle[] _tfbs;
|
private readonly BufferHandle[] _tfbs;
|
||||||
private readonly BufferRange[] _tfbTargets;
|
private readonly BufferRange[] _tfbTargets;
|
||||||
|
|
||||||
|
@ -84,22 +81,10 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
_images = new (TextureBase, Format)[SavedImages];
|
_images = new (TextureBase, Format)[SavedImages];
|
||||||
|
|
||||||
var defaultScale = new Vector4<float> { X = 1f, Y = 0f, Z = 0f, W = 0f };
|
|
||||||
new Span<Vector4<float>>(_renderScale).Fill(defaultScale);
|
|
||||||
|
|
||||||
_tfbs = new BufferHandle[Constants.MaxTransformFeedbackBuffers];
|
_tfbs = new BufferHandle[Constants.MaxTransformFeedbackBuffers];
|
||||||
_tfbTargets = new BufferRange[Constants.MaxTransformFeedbackBuffers];
|
_tfbTargets = new BufferRange[Constants.MaxTransformFeedbackBuffers];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(OpenGLRenderer renderer)
|
|
||||||
{
|
|
||||||
_supportBuffer = new SupportBufferUpdater(renderer);
|
|
||||||
GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 0, Unsafe.As<BufferHandle, int>(ref _supportBuffer.Handle));
|
|
||||||
|
|
||||||
_supportBuffer.UpdateFragmentIsBgra(_fpIsBgra, 0, SupportBuffer.FragmentIsBgraCount);
|
|
||||||
_supportBuffer.UpdateRenderScale(_renderScale, 0, SupportBuffer.RenderScaleMaxCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Barrier()
|
public void Barrier()
|
||||||
{
|
{
|
||||||
GL.MemoryBarrier(MemoryBarrierFlags.AllBarrierBits);
|
GL.MemoryBarrier(MemoryBarrierFlags.AllBarrierBits);
|
||||||
|
@ -684,8 +669,6 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
if (texture is TextureView view && sampler is Sampler samp)
|
if (texture is TextureView view && sampler is Sampler samp)
|
||||||
{
|
{
|
||||||
_supportBuffer.Commit();
|
|
||||||
|
|
||||||
if (HwCapabilities.SupportsDrawTexture)
|
if (HwCapabilities.SupportsDrawTexture)
|
||||||
{
|
{
|
||||||
GL.NV.DrawTexture(
|
GL.NV.DrawTexture(
|
||||||
|
@ -777,16 +760,6 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
_tfEnabled = false;
|
_tfEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double GetCounterDivisor(CounterType type)
|
|
||||||
{
|
|
||||||
if (type == CounterType.SamplesPassed)
|
|
||||||
{
|
|
||||||
return _renderScale[0].X * _renderScale[0].X;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAlphaTest(bool enable, float reference, CompareOp op)
|
public void SetAlphaTest(bool enable, float reference, CompareOp op)
|
||||||
{
|
{
|
||||||
if (!enable)
|
if (!enable)
|
||||||
|
@ -1172,12 +1145,6 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
_rasterizerDiscard = discard;
|
_rasterizerDiscard = discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRenderTargetScale(float scale)
|
|
||||||
{
|
|
||||||
_renderScale[0].X = scale;
|
|
||||||
_supportBuffer.UpdateRenderScale(_renderScale, 0, 1); // Just the first element.
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetRenderTargetColorMasks(ReadOnlySpan<uint> componentMasks)
|
public void SetRenderTargetColorMasks(ReadOnlySpan<uint> componentMasks)
|
||||||
{
|
{
|
||||||
_componentMasks = 0;
|
_componentMasks = 0;
|
||||||
|
@ -1194,8 +1161,6 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
EnsureFramebuffer();
|
EnsureFramebuffer();
|
||||||
|
|
||||||
bool isBgraChanged = false;
|
|
||||||
|
|
||||||
for (int index = 0; index < colors.Length; index++)
|
for (int index = 0; index < colors.Length; index++)
|
||||||
{
|
{
|
||||||
TextureView color = (TextureView)colors[index];
|
TextureView color = (TextureView)colors[index];
|
||||||
|
@ -1209,18 +1174,12 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
if (_fpIsBgra[index].X != isBgra)
|
if (_fpIsBgra[index].X != isBgra)
|
||||||
{
|
{
|
||||||
_fpIsBgra[index].X = isBgra;
|
_fpIsBgra[index].X = isBgra;
|
||||||
isBgraChanged = true;
|
|
||||||
|
|
||||||
RestoreComponentMask(index);
|
RestoreComponentMask(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBgraChanged)
|
|
||||||
{
|
|
||||||
_supportBuffer.UpdateFragmentIsBgra(_fpIsBgra, 0, SupportBuffer.FragmentIsBgraCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureView depthStencilView = (TextureView)depthStencil;
|
TextureView depthStencilView = (TextureView)depthStencil;
|
||||||
|
|
||||||
_framebuffer.AttachDepthStencil(depthStencilView);
|
_framebuffer.AttachDepthStencil(depthStencilView);
|
||||||
|
@ -1411,7 +1370,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
_vertexArray.SetVertexBuffers(vertexBuffers);
|
_vertexArray.SetVertexBuffers(vertexBuffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetViewports(ReadOnlySpan<Viewport> viewports, bool disableTransform)
|
public void SetViewports(ReadOnlySpan<Viewport> viewports)
|
||||||
{
|
{
|
||||||
Array.Resize(ref _viewportArray, viewports.Length * 4);
|
Array.Resize(ref _viewportArray, viewports.Length * 4);
|
||||||
Array.Resize(ref _depthRangeArray, viewports.Length * 2);
|
Array.Resize(ref _depthRangeArray, viewports.Length * 2);
|
||||||
|
@ -1450,19 +1409,6 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
GL.ViewportArray(0, viewports.Length, viewportArray);
|
GL.ViewportArray(0, viewports.Length, viewportArray);
|
||||||
GL.DepthRangeArray(0, viewports.Length, depthRangeArray);
|
GL.DepthRangeArray(0, viewports.Length, depthRangeArray);
|
||||||
|
|
||||||
float disableTransformF = disableTransform ? 1.0f : 0.0f;
|
|
||||||
if (_supportBuffer.Data.ViewportInverse.W != disableTransformF || disableTransform)
|
|
||||||
{
|
|
||||||
float scale = _renderScale[0].X;
|
|
||||||
_supportBuffer.UpdateViewportInverse(new Vector4<float>
|
|
||||||
{
|
|
||||||
X = scale * 2f / viewports[0].Region.Width,
|
|
||||||
Y = scale * 2f / viewports[0].Region.Height,
|
|
||||||
Z = 1,
|
|
||||||
W = disableTransformF
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TextureBarrier()
|
public void TextureBarrier()
|
||||||
|
@ -1552,36 +1498,9 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
return (_boundDrawFramebuffer, _boundReadFramebuffer);
|
return (_boundDrawFramebuffer, _boundReadFramebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateRenderScale(ReadOnlySpan<float> scales, int totalCount, int fragmentCount)
|
|
||||||
{
|
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
for (int index = 0; index < totalCount; index++)
|
|
||||||
{
|
|
||||||
if (_renderScale[1 + index].X != scales[index])
|
|
||||||
{
|
|
||||||
_renderScale[1 + index].X = scales[index];
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only update fragment count if there are scales after it for the vertex stage.
|
|
||||||
if (fragmentCount != totalCount && fragmentCount != _fragmentScaleCount)
|
|
||||||
{
|
|
||||||
_fragmentScaleCount = fragmentCount;
|
|
||||||
_supportBuffer.UpdateFragmentRenderScaleCount(_fragmentScaleCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changed)
|
|
||||||
{
|
|
||||||
_supportBuffer.UpdateRenderScale(_renderScale, 0, 1 + totalCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PrepareForDispatch()
|
private void PrepareForDispatch()
|
||||||
{
|
{
|
||||||
_unit0Texture?.Bind(0);
|
_unit0Texture?.Bind(0);
|
||||||
_supportBuffer.Commit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PreDraw(int vertexCount)
|
private void PreDraw(int vertexCount)
|
||||||
|
@ -1601,7 +1520,6 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
DrawCount++;
|
DrawCount++;
|
||||||
|
|
||||||
_unit0Texture?.Bind(0);
|
_unit0Texture?.Bind(0);
|
||||||
_supportBuffer.Commit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PostDraw()
|
private void PostDraw()
|
||||||
|
@ -1752,8 +1670,6 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_supportBuffer?.Dispose();
|
|
||||||
|
|
||||||
for (int i = 0; i < Constants.MaxTransformFeedbackBuffers; i++)
|
for (int i = 0; i < Constants.MaxTransformFeedbackBuffers; i++)
|
||||||
{
|
{
|
||||||
if (_tfbs[i] != BufferHandle.Null)
|
if (_tfbs[i] != BufferHandle.Null)
|
||||||
|
|
|
@ -107,7 +107,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CounterQueueEvent QueueReport(EventHandler<ulong> resultHandler, ulong lastDrawIndex, bool hostReserved)
|
public CounterQueueEvent QueueReport(EventHandler<ulong> resultHandler, float divisor, ulong lastDrawIndex, bool hostReserved)
|
||||||
{
|
{
|
||||||
CounterQueueEvent result;
|
CounterQueueEvent result;
|
||||||
ulong draws = lastDrawIndex - _current.DrawIndex;
|
ulong draws = lastDrawIndex - _current.DrawIndex;
|
||||||
|
@ -123,7 +123,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
||||||
_current.ReserveForHostAccess();
|
_current.ReserveForHostAccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
_current.Complete(draws > 0, _pipeline.GetCounterDivisor(Type));
|
_current.Complete(draws > 0, divisor);
|
||||||
_events.Enqueue(_current);
|
_events.Enqueue(_current);
|
||||||
|
|
||||||
_current.OnResult += resultHandler;
|
_current.OnResult += resultHandler;
|
||||||
|
|
|
@ -23,9 +23,9 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CounterQueueEvent QueueReport(CounterType type, EventHandler<ulong> resultHandler, ulong lastDrawIndex, bool hostReserved)
|
public CounterQueueEvent QueueReport(CounterType type, EventHandler<ulong> resultHandler, float divisor, ulong lastDrawIndex, bool hostReserved)
|
||||||
{
|
{
|
||||||
return _counterQueues[(int)type].QueueReport(resultHandler, lastDrawIndex, hostReserved);
|
return _counterQueues[(int)type].QueueReport(resultHandler, divisor, lastDrawIndex, hostReserved);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueueReset(CounterType type)
|
public void QueueReset(CounterType type)
|
||||||
|
|
|
@ -9,7 +9,6 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
public TextureCreateInfo Info;
|
public TextureCreateInfo Info;
|
||||||
public TextureView View;
|
public TextureView View;
|
||||||
public float ScaleFactor;
|
|
||||||
public int RemainingFrames;
|
public int RemainingFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +41,6 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
Info = view.Info,
|
Info = view.Info,
|
||||||
View = view,
|
View = view,
|
||||||
ScaleFactor = view.ScaleFactor,
|
|
||||||
RemainingFrames = DisposedLiveFrames
|
RemainingFrames = DisposedLiveFrames
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -52,9 +50,8 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
/// Attempt to obtain a texture from the resource cache with the desired parameters.
|
/// Attempt to obtain a texture from the resource cache with the desired parameters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="info">The creation info for the desired texture</param>
|
/// <param name="info">The creation info for the desired texture</param>
|
||||||
/// <param name="scaleFactor">The scale factor for the desired texture</param>
|
|
||||||
/// <returns>A TextureView with the description specified, or null if one was not found.</returns>
|
/// <returns>A TextureView with the description specified, or null if one was not found.</returns>
|
||||||
public TextureView GetTextureOrNull(TextureCreateInfo info, float scaleFactor)
|
public TextureView GetTextureOrNull(TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
|
@ -65,11 +62,8 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
foreach (DisposedTexture texture in list)
|
foreach (DisposedTexture texture in list)
|
||||||
{
|
{
|
||||||
if (scaleFactor == texture.ScaleFactor)
|
list.Remove(texture);
|
||||||
{
|
return texture.View;
|
||||||
list.Remove(texture);
|
|
||||||
return texture.View;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -111,12 +111,11 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
GL.Clear(ClearBufferMask.ColorBufferBit);
|
GL.Clear(ClearBufferMask.ColorBufferBit);
|
||||||
|
|
||||||
int srcX0, srcX1, srcY0, srcY1;
|
int srcX0, srcX1, srcY0, srcY1;
|
||||||
float scale = viewConverted.ScaleFactor;
|
|
||||||
|
|
||||||
if (crop.Left == 0 && crop.Right == 0)
|
if (crop.Left == 0 && crop.Right == 0)
|
||||||
{
|
{
|
||||||
srcX0 = 0;
|
srcX0 = 0;
|
||||||
srcX1 = (int)(viewConverted.Width / scale);
|
srcX1 = viewConverted.Width;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -127,7 +126,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
if (crop.Top == 0 && crop.Bottom == 0)
|
if (crop.Top == 0 && crop.Bottom == 0)
|
||||||
{
|
{
|
||||||
srcY0 = 0;
|
srcY0 = 0;
|
||||||
srcY1 = (int)(viewConverted.Height / scale);
|
srcY1 = viewConverted.Height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -135,14 +134,6 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
srcY1 = crop.Bottom;
|
srcY1 = crop.Bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scale != 1f)
|
|
||||||
{
|
|
||||||
srcX0 = (int)(srcX0 * scale);
|
|
||||||
srcY0 = (int)(srcY0 * scale);
|
|
||||||
srcX1 = (int)Math.Ceiling(srcX1 * scale);
|
|
||||||
srcY1 = (int)Math.Ceiling(srcY1 * scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
float ratioX = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _height * crop.AspectRatioX / (_width * crop.AspectRatioY));
|
float ratioX = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _height * crop.AspectRatioX / (_width * crop.AspectRatioY));
|
||||||
float ratioY = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _width * crop.AspectRatioY / (_height * crop.AspectRatioX));
|
float ratioY = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _width * crop.AspectRatioY / (_height * crop.AspectRatioX));
|
||||||
|
|
||||||
|
@ -408,7 +399,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
SwizzleComponent.Alpha);
|
SwizzleComponent.Alpha);
|
||||||
|
|
||||||
_isBgra = forceBgra;
|
_isBgra = forceBgra;
|
||||||
_upscaledTexture = _renderer.CreateTexture(info, 1) as TextureView;
|
_upscaledTexture = _renderer.CreateTexture(info) as TextureView;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetScalingFilterLevel(float level)
|
public void SetScalingFilterLevel(float level)
|
||||||
|
|
|
@ -35,7 +35,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
private readonly bool[] _uniformSet;
|
private readonly bool[] _uniformSet;
|
||||||
private readonly bool[] _storageSet;
|
private readonly bool[] _storageSet;
|
||||||
private Buffer _cachedSupportBuffer;
|
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
private enum DirtyFlags
|
private enum DirtyFlags
|
||||||
|
@ -115,7 +114,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SwizzleComponent.Red,
|
SwizzleComponent.Red,
|
||||||
SwizzleComponent.Green,
|
SwizzleComponent.Green,
|
||||||
SwizzleComponent.Blue,
|
SwizzleComponent.Blue,
|
||||||
SwizzleComponent.Alpha), 1f);
|
SwizzleComponent.Alpha));
|
||||||
|
|
||||||
_dummySampler = (SamplerHolder)gd.CreateSampler(new SamplerCreateInfo(
|
_dummySampler = (SamplerHolder)gd.CreateSampler(new SamplerCreateInfo(
|
||||||
MinFilter.Nearest,
|
MinFilter.Nearest,
|
||||||
|
@ -392,26 +391,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
Initialize(cbs, setIndex, dsc);
|
Initialize(cbs, setIndex, dsc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setIndex == PipelineBase.UniformSetIndex)
|
|
||||||
{
|
|
||||||
Span<DescriptorBufferInfo> uniformBuffer = stackalloc DescriptorBufferInfo[1];
|
|
||||||
|
|
||||||
if (!_uniformSet[0])
|
|
||||||
{
|
|
||||||
_cachedSupportBuffer = _gd.BufferManager.GetBuffer(cbs.CommandBuffer, _pipeline.SupportBufferUpdater.Handle, false).Get(cbs, 0, SupportBuffer.RequiredSize).Value;
|
|
||||||
_uniformSet[0] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
uniformBuffer[0] = new DescriptorBufferInfo
|
|
||||||
{
|
|
||||||
Offset = 0,
|
|
||||||
Range = (ulong)SupportBuffer.RequiredSize,
|
|
||||||
Buffer = _cachedSupportBuffer,
|
|
||||||
};
|
|
||||||
|
|
||||||
dsc.UpdateBuffers(0, 0, uniformBuffer, DescriptorType.UniformBuffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (ResourceBindingSegment segment in bindingSegments)
|
foreach (ResourceBindingSegment segment in bindingSegments)
|
||||||
|
@ -553,22 +532,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void UpdateAndBindUniformBufferPd(CommandBufferScoped cbs, PipelineBindPoint pbp)
|
private void UpdateAndBindUniformBufferPd(CommandBufferScoped cbs, PipelineBindPoint pbp)
|
||||||
{
|
{
|
||||||
if (!_uniformSet[0])
|
|
||||||
{
|
|
||||||
Span<DescriptorBufferInfo> uniformBuffer = stackalloc DescriptorBufferInfo[1];
|
|
||||||
|
|
||||||
uniformBuffer[0] = new DescriptorBufferInfo
|
|
||||||
{
|
|
||||||
Offset = 0,
|
|
||||||
Range = (ulong)SupportBuffer.RequiredSize,
|
|
||||||
Buffer = _gd.BufferManager.GetBuffer(cbs.CommandBuffer, _pipeline.SupportBufferUpdater.Handle, false).Get(cbs, 0, SupportBuffer.RequiredSize).Value,
|
|
||||||
};
|
|
||||||
|
|
||||||
_uniformSet[0] = true;
|
|
||||||
|
|
||||||
UpdateBuffers(cbs, pbp, 0, uniformBuffer, DescriptorType.UniformBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
var bindingSegments = _program.BindingSegments[PipelineBase.UniformSetIndex];
|
var bindingSegments = _program.BindingSegments[PipelineBase.UniformSetIndex];
|
||||||
var dummyBuffer = _dummyBuffer?.GetBuffer();
|
var dummyBuffer = _dummyBuffer?.GetBuffer();
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
originalInfo.SwizzleB,
|
originalInfo.SwizzleB,
|
||||||
originalInfo.SwizzleA);
|
originalInfo.SwizzleA);
|
||||||
_intermediaryTexture?.Dispose();
|
_intermediaryTexture?.Dispose();
|
||||||
_intermediaryTexture = _renderer.CreateTexture(info, view.ScaleFactor) as TextureView;
|
_intermediaryTexture = _renderer.CreateTexture(info) as TextureView;
|
||||||
}
|
}
|
||||||
|
|
||||||
_pipeline.SetCommandBuffer(cbs);
|
_pipeline.SetCommandBuffer(cbs);
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
if (_texture == null || _texture.Width != view.Width || _texture.Height != view.Height)
|
if (_texture == null || _texture.Width != view.Width || _texture.Height != view.Height)
|
||||||
{
|
{
|
||||||
_texture?.Dispose();
|
_texture?.Dispose();
|
||||||
_texture = _renderer.CreateTexture(view.Info, view.ScaleFactor) as TextureView;
|
_texture = _renderer.CreateTexture(view.Info) as TextureView;
|
||||||
}
|
}
|
||||||
|
|
||||||
_pipeline.SetCommandBuffer(cbs);
|
_pipeline.SetCommandBuffer(cbs);
|
||||||
|
|
|
@ -177,8 +177,8 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
var areaTexture = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Textures/SmaaAreaTexture.bin");
|
var areaTexture = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Textures/SmaaAreaTexture.bin");
|
||||||
var searchTexture = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Textures/SmaaSearchTexture.bin");
|
var searchTexture = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Textures/SmaaSearchTexture.bin");
|
||||||
|
|
||||||
_areaTexture = _renderer.CreateTexture(areaInfo, 1) as TextureView;
|
_areaTexture = _renderer.CreateTexture(areaInfo) as TextureView;
|
||||||
_searchTexture = _renderer.CreateTexture(searchInfo, 1) as TextureView;
|
_searchTexture = _renderer.CreateTexture(searchInfo) as TextureView;
|
||||||
|
|
||||||
_areaTexture.SetData(areaTexture);
|
_areaTexture.SetData(areaTexture);
|
||||||
_searchTexture.SetData(searchTexture);
|
_searchTexture.SetData(searchTexture);
|
||||||
|
@ -193,9 +193,9 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
_edgeOutputTexture?.Dispose();
|
_edgeOutputTexture?.Dispose();
|
||||||
_blendOutputTexture?.Dispose();
|
_blendOutputTexture?.Dispose();
|
||||||
|
|
||||||
_outputTexture = _renderer.CreateTexture(view.Info, view.ScaleFactor) as TextureView;
|
_outputTexture = _renderer.CreateTexture(view.Info) as TextureView;
|
||||||
_edgeOutputTexture = _renderer.CreateTexture(view.Info, view.ScaleFactor) as TextureView;
|
_edgeOutputTexture = _renderer.CreateTexture(view.Info) as TextureView;
|
||||||
_blendOutputTexture = _renderer.CreateTexture(view.Info, view.ScaleFactor) as TextureView;
|
_blendOutputTexture = _renderer.CreateTexture(view.Info) as TextureView;
|
||||||
}
|
}
|
||||||
|
|
||||||
_pipeline.SetCommandBuffer(cbs);
|
_pipeline.SetCommandBuffer(cbs);
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using Ryujinx.Graphics.Vulkan.Shaders;
|
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
||||||
using Format = Ryujinx.Graphics.GAL.Format;
|
using Format = Ryujinx.Graphics.GAL.Format;
|
||||||
|
@ -26,6 +27,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
class HelperShader : IDisposable
|
class HelperShader : IDisposable
|
||||||
{
|
{
|
||||||
private const int UniformBufferAlignment = 256;
|
private const int UniformBufferAlignment = 256;
|
||||||
|
private const string ShaderBinariesPath = "Ryujinx.Graphics.Vulkan/Shaders/SpirvBinaries";
|
||||||
|
|
||||||
private readonly PipelineHelperShader _pipeline;
|
private readonly PipelineHelperShader _pipeline;
|
||||||
private readonly ISampler _samplerLinear;
|
private readonly ISampler _samplerLinear;
|
||||||
|
@ -67,40 +69,40 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_programColorBlit = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorBlit = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorBlitVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.ColorBlitFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorBlitFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, blitResourceLayout);
|
}, blitResourceLayout);
|
||||||
|
|
||||||
_programColorBlitMs = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorBlitMs = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorBlitVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.ColorBlitMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorBlitMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, blitResourceLayout);
|
}, blitResourceLayout);
|
||||||
|
|
||||||
_programColorBlitClearAlpha = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorBlitClearAlpha = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorBlitVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.ColorBlitClearAlphaFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorBlitClearAlphaFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, blitResourceLayout);
|
}, blitResourceLayout);
|
||||||
|
|
||||||
var colorClearResourceLayout = new ResourceLayoutBuilder().Add(ResourceStages.Vertex, ResourceType.UniformBuffer, 1).Build();
|
var colorClearResourceLayout = new ResourceLayoutBuilder().Add(ResourceStages.Vertex, ResourceType.UniformBuffer, 1).Build();
|
||||||
|
|
||||||
_programColorClearF = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorClearF = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorClearVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorClearVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.ColorClearFFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorClearFFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, colorClearResourceLayout);
|
}, colorClearResourceLayout);
|
||||||
|
|
||||||
_programColorClearSI = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorClearSI = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorClearVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorClearVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.ColorClearSIFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorClearSIFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, colorClearResourceLayout);
|
}, colorClearResourceLayout);
|
||||||
|
|
||||||
_programColorClearUI = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorClearUI = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorClearVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorClearVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.ColorClearUIFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorClearUIFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, colorClearResourceLayout);
|
}, colorClearResourceLayout);
|
||||||
|
|
||||||
var strideChangeResourceLayout = new ResourceLayoutBuilder()
|
var strideChangeResourceLayout = new ResourceLayoutBuilder()
|
||||||
|
@ -110,7 +112,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_programStrideChange = gd.CreateProgramWithMinimalLayout(new[]
|
_programStrideChange = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ChangeBufferStrideShaderSource, ShaderStage.Compute, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ChangeBufferStride.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, strideChangeResourceLayout);
|
}, strideChangeResourceLayout);
|
||||||
|
|
||||||
var colorCopyResourceLayout = new ResourceLayoutBuilder()
|
var colorCopyResourceLayout = new ResourceLayoutBuilder()
|
||||||
|
@ -120,17 +122,17 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_programColorCopyShortening = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorCopyShortening = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorCopyShorteningComputeShaderSource, ShaderStage.Compute, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorCopyShorteningCompute.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, colorCopyResourceLayout);
|
}, colorCopyResourceLayout);
|
||||||
|
|
||||||
_programColorCopyToNonMs = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorCopyToNonMs = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorCopyToNonMsComputeShaderSource, ShaderStage.Compute, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorCopyToNonMsCompute.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, colorCopyResourceLayout);
|
}, colorCopyResourceLayout);
|
||||||
|
|
||||||
_programColorCopyWidening = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorCopyWidening = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorCopyWideningComputeShaderSource, ShaderStage.Compute, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorCopyWideningCompute.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, colorCopyResourceLayout);
|
}, colorCopyResourceLayout);
|
||||||
|
|
||||||
var colorDrawToMsResourceLayout = new ResourceLayoutBuilder()
|
var colorDrawToMsResourceLayout = new ResourceLayoutBuilder()
|
||||||
|
@ -139,8 +141,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_programColorDrawToMs = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorDrawToMs = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorDrawToMsVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorDrawToMsVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.ColorDrawToMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorDrawToMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, colorDrawToMsResourceLayout);
|
}, colorDrawToMsResourceLayout);
|
||||||
|
|
||||||
var convertD32S8ToD24S8ResourceLayout = new ResourceLayoutBuilder()
|
var convertD32S8ToD24S8ResourceLayout = new ResourceLayoutBuilder()
|
||||||
|
@ -150,7 +152,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_programConvertD32S8ToD24S8 = gd.CreateProgramWithMinimalLayout(new[]
|
_programConvertD32S8ToD24S8 = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ConvertD32S8ToD24S8ShaderSource, ShaderStage.Compute, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ConvertD32S8ToD24S8.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, convertD32S8ToD24S8ResourceLayout);
|
}, convertD32S8ToD24S8ResourceLayout);
|
||||||
|
|
||||||
var convertIndexBufferResourceLayout = new ResourceLayoutBuilder()
|
var convertIndexBufferResourceLayout = new ResourceLayoutBuilder()
|
||||||
|
@ -160,7 +162,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_programConvertIndexBuffer = gd.CreateProgramWithMinimalLayout(new[]
|
_programConvertIndexBuffer = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ConvertIndexBufferShaderSource, ShaderStage.Compute, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ConvertIndexBuffer.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, convertIndexBufferResourceLayout);
|
}, convertIndexBufferResourceLayout);
|
||||||
|
|
||||||
var convertIndirectDataResourceLayout = new ResourceLayoutBuilder()
|
var convertIndirectDataResourceLayout = new ResourceLayoutBuilder()
|
||||||
|
@ -171,61 +173,66 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_programConvertIndirectData = gd.CreateProgramWithMinimalLayout(new[]
|
_programConvertIndirectData = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ConvertIndirectDataShaderSource, ShaderStage.Compute, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ConvertIndirectData.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, convertIndirectDataResourceLayout);
|
}, convertIndirectDataResourceLayout);
|
||||||
|
|
||||||
_programDepthBlit = gd.CreateProgramWithMinimalLayout(new[]
|
_programDepthBlit = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorBlitVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.DepthBlitFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("DepthBlitFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, blitResourceLayout);
|
}, blitResourceLayout);
|
||||||
|
|
||||||
_programDepthBlitMs = gd.CreateProgramWithMinimalLayout(new[]
|
_programDepthBlitMs = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorBlitVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.DepthBlitMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("DepthBlitMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, blitResourceLayout);
|
}, blitResourceLayout);
|
||||||
|
|
||||||
_programDepthDrawToMs = gd.CreateProgramWithMinimalLayout(new[]
|
_programDepthDrawToMs = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorDrawToMsVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorDrawToMsVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.DepthDrawToMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("DepthDrawToMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, colorDrawToMsResourceLayout);
|
}, colorDrawToMsResourceLayout);
|
||||||
|
|
||||||
_programDepthDrawToNonMs = gd.CreateProgramWithMinimalLayout(new[]
|
_programDepthDrawToNonMs = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorDrawToMsVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorDrawToMsVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.DepthDrawToNonMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("DepthDrawToNonMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, colorDrawToMsResourceLayout);
|
}, colorDrawToMsResourceLayout);
|
||||||
|
|
||||||
if (gd.Capabilities.SupportsShaderStencilExport)
|
if (gd.Capabilities.SupportsShaderStencilExport)
|
||||||
{
|
{
|
||||||
_programStencilBlit = gd.CreateProgramWithMinimalLayout(new[]
|
_programStencilBlit = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorBlitVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.StencilBlitFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("StencilBlitFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, blitResourceLayout);
|
}, blitResourceLayout);
|
||||||
|
|
||||||
_programStencilBlitMs = gd.CreateProgramWithMinimalLayout(new[]
|
_programStencilBlitMs = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorBlitVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.StencilBlitMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("StencilBlitMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, blitResourceLayout);
|
}, blitResourceLayout);
|
||||||
|
|
||||||
_programStencilDrawToMs = gd.CreateProgramWithMinimalLayout(new[]
|
_programStencilDrawToMs = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorDrawToMsVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorDrawToMsVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.StencilDrawToMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("StencilDrawToMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, colorDrawToMsResourceLayout);
|
}, colorDrawToMsResourceLayout);
|
||||||
|
|
||||||
_programStencilDrawToNonMs = gd.CreateProgramWithMinimalLayout(new[]
|
_programStencilDrawToNonMs = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(ShaderBinaries.ColorDrawToMsVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorDrawToMsVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
|
||||||
new ShaderSource(ShaderBinaries.StencilDrawToNonMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("StencilDrawToNonMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, colorDrawToMsResourceLayout);
|
}, colorDrawToMsResourceLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static byte[] ReadSpirv(string fileName)
|
||||||
|
{
|
||||||
|
return EmbeddedResources.Read(string.Join('/', ShaderBinariesPath, fileName));
|
||||||
|
}
|
||||||
|
|
||||||
public void Blit(
|
public void Blit(
|
||||||
VulkanRenderer gd,
|
VulkanRenderer gd,
|
||||||
TextureView src,
|
TextureView src,
|
||||||
|
@ -470,7 +477,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_pipeline.ClearRenderTargetColor(0, 0, 1, new ColorF(0f, 0f, 0f, 1f));
|
_pipeline.ClearRenderTargetColor(0, 0, 1, new ColorF(0f, 0f, 0f, 1f));
|
||||||
}
|
}
|
||||||
|
|
||||||
_pipeline.SetViewports(viewports, false);
|
_pipeline.SetViewports(viewports);
|
||||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||||
_pipeline.Draw(4, 1, 0, 0);
|
_pipeline.Draw(4, 1, 0, 0);
|
||||||
|
|
||||||
|
@ -546,7 +553,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, (uint)dstSamples, true, dstFormat);
|
_pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, (uint)dstSamples, true, dstFormat);
|
||||||
_pipeline.SetScissors(scissors);
|
_pipeline.SetScissors(scissors);
|
||||||
_pipeline.SetViewports(viewports, false);
|
_pipeline.SetViewports(viewports);
|
||||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||||
|
|
||||||
var aspectFlags = src.Info.Format.ConvertAspectFlags();
|
var aspectFlags = src.Info.Format.ConvertAspectFlags();
|
||||||
|
@ -710,7 +717,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_pipeline.SetProgram(program);
|
_pipeline.SetProgram(program);
|
||||||
_pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false, dstFormat);
|
_pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false, dstFormat);
|
||||||
_pipeline.SetRenderTargetColorMasks(new[] { componentMask });
|
_pipeline.SetRenderTargetColorMasks(new[] { componentMask });
|
||||||
_pipeline.SetViewports(viewports, false);
|
_pipeline.SetViewports(viewports);
|
||||||
_pipeline.SetScissors(scissors);
|
_pipeline.SetScissors(scissors);
|
||||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||||
_pipeline.Draw(4, 1, 0, 0);
|
_pipeline.Draw(4, 1, 0, 0);
|
||||||
|
@ -774,7 +781,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Span<Rectangle<int>> scissors = stackalloc Rectangle<int>[1];
|
Span<Rectangle<int>> scissors = stackalloc Rectangle<int>[1];
|
||||||
|
|
||||||
pipeline.SetProgram(_programColorBlit);
|
pipeline.SetProgram(_programColorBlit);
|
||||||
pipeline.SetViewports(viewports, false);
|
pipeline.SetViewports(viewports);
|
||||||
pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||||
pipeline.Draw(4, 1, 0, 0);
|
pipeline.Draw(4, 1, 0, 0);
|
||||||
|
|
||||||
|
@ -1117,7 +1124,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
scissors[0] = new Rectangle<int>(0, 0, dst.Width, dst.Height);
|
scissors[0] = new Rectangle<int>(0, 0, dst.Width, dst.Height);
|
||||||
|
|
||||||
_pipeline.SetScissors(scissors);
|
_pipeline.SetScissors(scissors);
|
||||||
_pipeline.SetViewports(viewports, false);
|
_pipeline.SetViewports(viewports);
|
||||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||||
|
|
||||||
for (int z = 0; z < depth; z++)
|
for (int z = 0; z < depth; z++)
|
||||||
|
@ -1250,7 +1257,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_pipeline.SetRenderTargetColorMasks(new uint[] { 0xf });
|
_pipeline.SetRenderTargetColorMasks(new uint[] { 0xf });
|
||||||
_pipeline.SetScissors(scissors);
|
_pipeline.SetScissors(scissors);
|
||||||
_pipeline.SetViewports(viewports, false);
|
_pipeline.SetViewports(viewports);
|
||||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||||
|
|
||||||
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) });
|
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) });
|
||||||
|
|
|
@ -50,9 +50,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
private ShaderCollection _program;
|
private ShaderCollection _program;
|
||||||
|
|
||||||
private readonly Vector4<float>[] _renderScale = new Vector4<float>[73];
|
|
||||||
private int _fragmentScaleCount;
|
|
||||||
|
|
||||||
protected FramebufferParams FramebufferParams;
|
protected FramebufferParams FramebufferParams;
|
||||||
private Auto<DisposableFramebuffer> _framebuffer;
|
private Auto<DisposableFramebuffer> _framebuffer;
|
||||||
private Auto<DisposableRenderPass> _renderPass;
|
private Auto<DisposableRenderPass> _renderPass;
|
||||||
|
@ -74,7 +71,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
private readonly VertexBufferUpdater _vertexBufferUpdater;
|
private readonly VertexBufferUpdater _vertexBufferUpdater;
|
||||||
|
|
||||||
public SupportBufferUpdater SupportBufferUpdater;
|
|
||||||
public IndexBufferPattern QuadsToTrisPattern;
|
public IndexBufferPattern QuadsToTrisPattern;
|
||||||
public IndexBufferPattern TriFanToTrisPattern;
|
public IndexBufferPattern TriFanToTrisPattern;
|
||||||
|
|
||||||
|
@ -119,9 +115,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
ClearScissor = new Rectangle<int>(0, 0, 0xffff, 0xffff);
|
ClearScissor = new Rectangle<int>(0, 0, 0xffff, 0xffff);
|
||||||
|
|
||||||
var defaultScale = new Vector4<float> { X = 1f, Y = 0f, Z = 0f, W = 0f };
|
|
||||||
new Span<Vector4<float>>(_renderScale).Fill(defaultScale);
|
|
||||||
|
|
||||||
_storedBlend = new PipelineColorBlendAttachmentState[Constants.MaxRenderTargets];
|
_storedBlend = new PipelineColorBlendAttachmentState[Constants.MaxRenderTargets];
|
||||||
|
|
||||||
_newState.Initialize();
|
_newState.Initialize();
|
||||||
|
@ -131,9 +124,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
_descriptorSetUpdater.Initialize();
|
_descriptorSetUpdater.Initialize();
|
||||||
|
|
||||||
SupportBufferUpdater = new SupportBufferUpdater(Gd);
|
|
||||||
SupportBufferUpdater.UpdateRenderScale(_renderScale, 0, SupportBuffer.RenderScaleMaxCount);
|
|
||||||
|
|
||||||
QuadsToTrisPattern = new IndexBufferPattern(Gd, 4, 6, 0, new[] { 0, 1, 2, 0, 2, 3 }, 4, false);
|
QuadsToTrisPattern = new IndexBufferPattern(Gd, 4, 6, 0, new[] { 0, 1, 2, 0, 2, 3 }, 4, false);
|
||||||
TriFanToTrisPattern = new IndexBufferPattern(Gd, 3, 3, 2, new[] { int.MinValue, -1, 0 }, 1, true);
|
TriFanToTrisPattern = new IndexBufferPattern(Gd, 3, 3, 2, new[] { int.MinValue, -1, 0 }, 1, true);
|
||||||
}
|
}
|
||||||
|
@ -144,9 +134,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
_drawCountSinceBarrier = DrawCount;
|
_drawCountSinceBarrier = DrawCount;
|
||||||
|
|
||||||
// Barriers apparently have no effect inside a render pass on MoltenVK.
|
// Barriers are not supported inside a render pass on Apple GPUs.
|
||||||
// As a workaround, end the render pass.
|
// As a workaround, end the render pass.
|
||||||
if (Gd.IsMoltenVk)
|
if (Gd.Vendor == Vendor.Apple)
|
||||||
{
|
{
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
}
|
}
|
||||||
|
@ -666,8 +656,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
if (texture is TextureView srcTexture)
|
if (texture is TextureView srcTexture)
|
||||||
{
|
{
|
||||||
SupportBufferUpdater.Commit();
|
|
||||||
|
|
||||||
var oldCullMode = _newState.CullMode;
|
var oldCullMode = _newState.CullMode;
|
||||||
var oldStencilTestEnable = _newState.StencilTestEnable;
|
var oldStencilTestEnable = _newState.StencilTestEnable;
|
||||||
var oldDepthTestEnable = _newState.DepthTestEnable;
|
var oldDepthTestEnable = _newState.DepthTestEnable;
|
||||||
|
@ -709,16 +697,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_tfEnabled = false;
|
_tfEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double GetCounterDivisor(CounterType type)
|
|
||||||
{
|
|
||||||
if (type == CounterType.SamplesPassed)
|
|
||||||
{
|
|
||||||
return _renderScale[0].X * _renderScale[0].X;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsCommandBufferActive(CommandBuffer cb)
|
public bool IsCommandBufferActive(CommandBuffer cb)
|
||||||
{
|
{
|
||||||
return CommandBuffer.Handle == cb.Handle;
|
return CommandBuffer.Handle == cb.Handle;
|
||||||
|
@ -1050,12 +1028,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SetRenderTargetsInternal(colors, depthStencil, Gd.IsTBDR);
|
SetRenderTargetsInternal(colors, depthStencil, Gd.IsTBDR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRenderTargetScale(float scale)
|
|
||||||
{
|
|
||||||
_renderScale[0].X = scale;
|
|
||||||
SupportBufferUpdater.UpdateRenderScale(_renderScale, 0, 1); // Just the first element.
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetScissors(ReadOnlySpan<Rectangle<int>> regions)
|
public void SetScissors(ReadOnlySpan<Rectangle<int>> regions)
|
||||||
{
|
{
|
||||||
int maxScissors = Gd.Capabilities.SupportsMultiView ? Constants.MaxViewports : 1;
|
int maxScissors = Gd.Capabilities.SupportsMultiView ? Constants.MaxViewports : 1;
|
||||||
|
@ -1303,7 +1275,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetViewports(ReadOnlySpan<Viewport> viewports, bool disableTransform)
|
public void SetViewports(ReadOnlySpan<Viewport> viewports)
|
||||||
{
|
{
|
||||||
int maxViewports = Gd.Capabilities.SupportsMultiView ? Constants.MaxViewports : 1;
|
int maxViewports = Gd.Capabilities.SupportsMultiView ? Constants.MaxViewports : 1;
|
||||||
int count = Math.Min(maxViewports, viewports.Length);
|
int count = Math.Min(maxViewports, viewports.Length);
|
||||||
|
@ -1328,19 +1300,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Clamp(viewport.DepthFar)));
|
Clamp(viewport.DepthFar)));
|
||||||
}
|
}
|
||||||
|
|
||||||
float disableTransformF = disableTransform ? 1.0f : 0.0f;
|
|
||||||
if (SupportBufferUpdater.Data.ViewportInverse.W != disableTransformF || disableTransform)
|
|
||||||
{
|
|
||||||
float scale = _renderScale[0].X;
|
|
||||||
SupportBufferUpdater.UpdateViewportInverse(new Vector4<float>
|
|
||||||
{
|
|
||||||
X = scale * 2f / viewports[0].Region.Width,
|
|
||||||
Y = scale * 2f / viewports[0].Region.Height,
|
|
||||||
Z = 1,
|
|
||||||
W = disableTransformF,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_newState.ViewportsCount = (uint)count;
|
_newState.ViewportsCount = (uint)count;
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
@ -1391,32 +1350,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
TextureBarrier();
|
TextureBarrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateRenderScale(ReadOnlySpan<float> scales, int totalCount, int fragmentCount)
|
|
||||||
{
|
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
for (int index = 0; index < totalCount; index++)
|
|
||||||
{
|
|
||||||
if (_renderScale[1 + index].X != scales[index])
|
|
||||||
{
|
|
||||||
_renderScale[1 + index].X = scales[index];
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only update fragment count if there are scales after it for the vertex stage.
|
|
||||||
if (fragmentCount != totalCount && fragmentCount != _fragmentScaleCount)
|
|
||||||
{
|
|
||||||
_fragmentScaleCount = fragmentCount;
|
|
||||||
SupportBufferUpdater.UpdateFragmentRenderScaleCount(_fragmentScaleCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changed)
|
|
||||||
{
|
|
||||||
SupportBufferUpdater.UpdateRenderScale(_renderScale, 0, 1 + totalCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void SignalCommandBufferChange()
|
protected void SignalCommandBufferChange()
|
||||||
{
|
{
|
||||||
_needsIndexBufferRebind = true;
|
_needsIndexBufferRebind = true;
|
||||||
|
@ -1614,9 +1547,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
DynamicState.ReplayIfDirty(Gd.Api, CommandBuffer);
|
DynamicState.ReplayIfDirty(Gd.Api, CommandBuffer);
|
||||||
|
|
||||||
// Commit changes to the support buffer before drawing.
|
|
||||||
SupportBufferUpdater.Commit();
|
|
||||||
|
|
||||||
if (_needsIndexBufferRebind && _indexBufferPattern == null)
|
if (_needsIndexBufferRebind && _indexBufferPattern == null)
|
||||||
{
|
{
|
||||||
_indexBuffer.BindIndexBuffer(Gd, Cbs);
|
_indexBuffer.BindIndexBuffer(Gd, Cbs);
|
||||||
|
@ -1777,8 +1707,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
Gd.Api.DestroyPipelineCache(Device, PipelineCache, null);
|
Gd.Api.DestroyPipelineCache(Device, PipelineCache, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
SupportBufferUpdater.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CounterQueueEvent QueueReport(EventHandler<ulong> resultHandler, ulong lastDrawIndex, bool hostReserved)
|
public CounterQueueEvent QueueReport(EventHandler<ulong> resultHandler, float divisor, ulong lastDrawIndex, bool hostReserved)
|
||||||
{
|
{
|
||||||
CounterQueueEvent result;
|
CounterQueueEvent result;
|
||||||
ulong draws = lastDrawIndex - _current.DrawIndex;
|
ulong draws = lastDrawIndex - _current.DrawIndex;
|
||||||
|
@ -146,7 +146,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
_current.ReserveForHostAccess();
|
_current.ReserveForHostAccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
_current.Complete(draws > 0 && Type != CounterType.TransformFeedbackPrimitivesWritten, _pipeline.GetCounterDivisor(Type));
|
_current.Complete(draws > 0 && Type != CounterType.TransformFeedbackPrimitivesWritten, divisor);
|
||||||
_events.Enqueue(_current);
|
_events.Enqueue(_current);
|
||||||
|
|
||||||
_current.OnResult += resultHandler;
|
_current.OnResult += resultHandler;
|
||||||
|
|
|
@ -37,9 +37,9 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
_counterQueues[(int)CounterType.SamplesPassed].ResetFutureCounters(cmd, count);
|
_counterQueues[(int)CounterType.SamplesPassed].ResetFutureCounters(cmd, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CounterQueueEvent QueueReport(CounterType type, EventHandler<ulong> resultHandler, bool hostReserved)
|
public CounterQueueEvent QueueReport(CounterType type, EventHandler<ulong> resultHandler, float divisor, bool hostReserved)
|
||||||
{
|
{
|
||||||
return _counterQueues[(int)type].QueueReport(resultHandler, _pipeline.DrawCount, hostReserved);
|
return _counterQueues[(int)type].QueueReport(resultHandler, divisor, _pipeline.DrawCount, hostReserved);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueueReset(CounterType type)
|
public void QueueReset(CounterType type)
|
||||||
|
|
|
@ -21,6 +21,31 @@
|
||||||
<EmbeddedResource Include="Effects\Shaders\SmaaBlend.spv" />
|
<EmbeddedResource Include="Effects\Shaders\SmaaBlend.spv" />
|
||||||
<EmbeddedResource Include="Effects\Shaders\SmaaEdge.spv" />
|
<EmbeddedResource Include="Effects\Shaders\SmaaEdge.spv" />
|
||||||
<EmbeddedResource Include="Effects\Shaders\SmaaNeighbour.spv" />
|
<EmbeddedResource Include="Effects\Shaders\SmaaNeighbour.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ChangeBufferStride.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorBlitClearAlphaFragment.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorBlitFragment.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorBlitMsFragment.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorBlitVertex.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorClearFFragment.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorClearSIFragment.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorClearUIFragment.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorClearVertex.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorCopyShorteningCompute.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorCopyToNonMsCompute.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorCopyWideningCompute.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorDrawToMsFragment.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorDrawToMsVertex.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ConvertD32S8ToD24S8.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ConvertIndexBuffer.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\ConvertIndirectData.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\DepthBlitFragment.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\DepthBlitMsFragment.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\DepthDrawToMsFragment.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\DepthDrawToNonMsFragment.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\StencilBlitFragment.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\StencilBlitMsFragment.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\StencilDrawToMsFragment.spv" />
|
||||||
|
<EmbeddedResource Include="Shaders\SpirvBinaries\StencilDrawToNonMsFragment.spv" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -25,15 +25,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public VkFormat VkFormat { get; }
|
public VkFormat VkFormat { get; }
|
||||||
|
|
||||||
public float ScaleFactor { get; }
|
public TextureBuffer(VulkanRenderer gd, TextureCreateInfo info)
|
||||||
|
|
||||||
public TextureBuffer(VulkanRenderer gd, TextureCreateInfo info, float scale)
|
|
||||||
{
|
{
|
||||||
_gd = gd;
|
_gd = gd;
|
||||||
Width = info.Width;
|
Width = info.Width;
|
||||||
Height = info.Height;
|
Height = info.Height;
|
||||||
VkFormat = FormatTable.GetFormat(info.Format);
|
VkFormat = FormatTable.GetFormat(info.Format);
|
||||||
ScaleFactor = scale;
|
|
||||||
|
|
||||||
gd.Textures.Add(this);
|
gd.Textures.Add(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,19 +54,16 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private readonly ulong _size;
|
private readonly ulong _size;
|
||||||
|
|
||||||
public VkFormat VkFormat { get; }
|
public VkFormat VkFormat { get; }
|
||||||
public float ScaleFactor { get; }
|
|
||||||
|
|
||||||
public unsafe TextureStorage(
|
public unsafe TextureStorage(
|
||||||
VulkanRenderer gd,
|
VulkanRenderer gd,
|
||||||
Device device,
|
Device device,
|
||||||
TextureCreateInfo info,
|
TextureCreateInfo info,
|
||||||
float scaleFactor,
|
|
||||||
Auto<MemoryAllocation> foreignAllocation = null)
|
Auto<MemoryAllocation> foreignAllocation = null)
|
||||||
{
|
{
|
||||||
_gd = gd;
|
_gd = gd;
|
||||||
_device = device;
|
_device = device;
|
||||||
_info = info;
|
_info = info;
|
||||||
ScaleFactor = scaleFactor;
|
|
||||||
|
|
||||||
var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format);
|
var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format);
|
||||||
var levels = (uint)info.Levels;
|
var levels = (uint)info.Levels;
|
||||||
|
@ -175,7 +172,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
var info = NewCreateInfoWith(ref _info, format, _info.BytesPerPixel);
|
var info = NewCreateInfoWith(ref _info, format, _info.BytesPerPixel);
|
||||||
|
|
||||||
storage = new TextureStorage(_gd, _device, info, ScaleFactor, _allocationAuto);
|
storage = new TextureStorage(_gd, _device, info, _allocationAuto);
|
||||||
|
|
||||||
_aliasedStorages.Add(format, storage);
|
_aliasedStorages.Add(format, storage);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public int Layers => Info.GetDepthOrLayers();
|
public int Layers => Info.GetDepthOrLayers();
|
||||||
public int FirstLayer { get; }
|
public int FirstLayer { get; }
|
||||||
public int FirstLevel { get; }
|
public int FirstLevel { get; }
|
||||||
public float ScaleFactor => Storage.ScaleFactor;
|
|
||||||
public VkFormat VkFormat { get; }
|
public VkFormat VkFormat { get; }
|
||||||
public bool Valid { get; private set; }
|
public bool Valid { get; private set; }
|
||||||
|
|
||||||
|
|
|
@ -315,7 +315,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
features2.Features.ShaderStorageImageMultisample,
|
features2.Features.ShaderStorageImageMultisample,
|
||||||
_physicalDevice.IsDeviceExtensionPresent(ExtConditionalRendering.ExtensionName),
|
_physicalDevice.IsDeviceExtensionPresent(ExtConditionalRendering.ExtensionName),
|
||||||
_physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState.ExtensionName),
|
_physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState.ExtensionName),
|
||||||
features2.Features.MultiViewport,
|
features2.Features.MultiViewport && !(IsMoltenVk && Vendor == Vendor.Amd), // Workaround for AMD on MoltenVK issue
|
||||||
featuresRobustness2.NullDescriptor || IsMoltenVk,
|
featuresRobustness2.NullDescriptor || IsMoltenVk,
|
||||||
_physicalDevice.IsDeviceExtensionPresent(KhrPushDescriptor.ExtensionName),
|
_physicalDevice.IsDeviceExtensionPresent(KhrPushDescriptor.ExtensionName),
|
||||||
featuresPrimitiveTopologyListRestart.PrimitiveTopologyListRestart,
|
featuresPrimitiveTopologyListRestart.PrimitiveTopologyListRestart,
|
||||||
|
@ -432,26 +432,26 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return new SamplerHolder(this, _device, info);
|
return new SamplerHolder(this, _device, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ITexture CreateTexture(TextureCreateInfo info, float scale)
|
public ITexture CreateTexture(TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
if (info.Target == Target.TextureBuffer)
|
if (info.Target == Target.TextureBuffer)
|
||||||
{
|
{
|
||||||
return new TextureBuffer(this, info, scale);
|
return new TextureBuffer(this, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CreateTextureView(info, scale);
|
return CreateTextureView(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TextureView CreateTextureView(TextureCreateInfo info, float scale)
|
internal TextureView CreateTextureView(TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
// This should be disposed when all views are destroyed.
|
// This should be disposed when all views are destroyed.
|
||||||
var storage = CreateTextureStorage(info, scale);
|
var storage = CreateTextureStorage(info);
|
||||||
return storage.CreateView(info, 0, 0);
|
return storage.CreateView(info, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TextureStorage CreateTextureStorage(TextureCreateInfo info, float scale)
|
internal TextureStorage CreateTextureStorage(TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
return new TextureStorage(this, _device, info, scale);
|
return new TextureStorage(this, _device, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteBuffer(BufferHandle buffer)
|
public void DeleteBuffer(BufferHandle buffer)
|
||||||
|
@ -680,7 +680,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
IsAmdWindows = Vendor == Vendor.Amd && OperatingSystem.IsWindows();
|
IsAmdWindows = Vendor == Vendor.Amd && OperatingSystem.IsWindows();
|
||||||
IsIntelWindows = Vendor == Vendor.Intel && OperatingSystem.IsWindows();
|
IsIntelWindows = Vendor == Vendor.Intel && OperatingSystem.IsWindows();
|
||||||
IsTBDR = IsMoltenVk ||
|
IsTBDR =
|
||||||
|
Vendor == Vendor.Apple ||
|
||||||
Vendor == Vendor.Qualcomm ||
|
Vendor == Vendor.Qualcomm ||
|
||||||
Vendor == Vendor.ARM ||
|
Vendor == Vendor.ARM ||
|
||||||
Vendor == Vendor.Broadcom ||
|
Vendor == Vendor.Broadcom ||
|
||||||
|
@ -752,9 +753,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SyncManager.Cleanup();
|
SyncManager.Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, bool hostReserved)
|
public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, float divisor, bool hostReserved)
|
||||||
{
|
{
|
||||||
return _counters.QueueReport(type, resultHandler, hostReserved);
|
return _counters.QueueReport(type, resultHandler, divisor, hostReserved);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetCounter(CounterType type)
|
public void ResetCounter(CounterType type)
|
||||||
|
|
|
@ -294,12 +294,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
|
|
||||||
int srcX0, srcX1, srcY0, srcY1;
|
int srcX0, srcX1, srcY0, srcY1;
|
||||||
float scale = view.ScaleFactor;
|
|
||||||
|
|
||||||
if (crop.Left == 0 && crop.Right == 0)
|
if (crop.Left == 0 && crop.Right == 0)
|
||||||
{
|
{
|
||||||
srcX0 = 0;
|
srcX0 = 0;
|
||||||
srcX1 = (int)(view.Width / scale);
|
srcX1 = view.Width;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -310,7 +309,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
if (crop.Top == 0 && crop.Bottom == 0)
|
if (crop.Top == 0 && crop.Bottom == 0)
|
||||||
{
|
{
|
||||||
srcY0 = 0;
|
srcY0 = 0;
|
||||||
srcY1 = (int)(view.Height / scale);
|
srcY1 = view.Height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -318,14 +317,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
srcY1 = crop.Bottom;
|
srcY1 = crop.Bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scale != 1f)
|
|
||||||
{
|
|
||||||
srcX0 = (int)(srcX0 * scale);
|
|
||||||
srcY0 = (int)(srcY0 * scale);
|
|
||||||
srcX1 = (int)Math.Ceiling(srcX1 * scale);
|
|
||||||
srcY1 = (int)Math.Ceiling(srcY1 * scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ScreenCaptureRequested)
|
if (ScreenCaptureRequested)
|
||||||
{
|
{
|
||||||
if (_effect != null)
|
if (_effect != null)
|
||||||
|
|
Loading…
Reference in a new issue