mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-02-21 00:23:36 +00:00
DrawTexture support
This commit is contained in:
parent
e9222a426a
commit
5fbfa9a9bd
3 changed files with 144 additions and 6 deletions
|
@ -155,6 +155,20 @@ void main()
|
|||
region[2] = (float)srcRegion.Y1 / src.Height;
|
||||
region[3] = (float)srcRegion.Y2 / src.Height;
|
||||
|
||||
if (dstRegion.X1 > dstRegion.X2)
|
||||
{
|
||||
float temp = region[0];
|
||||
region[0] = region[1];
|
||||
region[1] = temp;
|
||||
}
|
||||
|
||||
if (dstRegion.Y1 > dstRegion.Y2)
|
||||
{
|
||||
float temp = region[2];
|
||||
region[2] = region[3];
|
||||
region[3] = temp;
|
||||
}
|
||||
|
||||
var bufferHandle = gd.BufferManager.CreateWithHandle(gd, RegionBufferSize);
|
||||
|
||||
gd.BufferManager.SetData<float>(bufferHandle, 0, region);
|
||||
|
@ -167,8 +181,14 @@ void main()
|
|||
|
||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
||||
|
||||
var rect = new Rectangle<float>(
|
||||
MathF.Min(dstRegion.X1, dstRegion.X2),
|
||||
MathF.Min(dstRegion.Y1, dstRegion.Y2),
|
||||
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
||||
MathF.Abs(dstRegion.Y2 - dstRegion.Y1));
|
||||
|
||||
viewports[0] = new GAL.Viewport(
|
||||
new Rectangle<float>(dstRegion.X1, dstRegion.Y1, dstRegion.X2 - dstRegion.X1, dstRegion.Y2 - dstRegion.Y1),
|
||||
rect,
|
||||
ViewportSwizzle.PositiveX,
|
||||
ViewportSwizzle.PositiveY,
|
||||
ViewportSwizzle.PositiveZ,
|
||||
|
@ -198,6 +218,76 @@ void main()
|
|||
gd.BufferManager.Delete(bufferHandle);
|
||||
}
|
||||
|
||||
public void DrawTexture(
|
||||
VulkanGraphicsDevice gd,
|
||||
PipelineBase pipeline,
|
||||
TextureView src,
|
||||
ISampler srcSampler,
|
||||
Extents2DF srcRegion,
|
||||
Extents2DF dstRegion)
|
||||
{
|
||||
const int RegionBufferSize = 16;
|
||||
|
||||
pipeline.SetTextureAndSampler(32, src, srcSampler);
|
||||
|
||||
Span<float> region = stackalloc float[RegionBufferSize / sizeof(float)];
|
||||
|
||||
region[0] = srcRegion.X1 / src.Width;
|
||||
region[1] = srcRegion.X2 / src.Width;
|
||||
region[2] = srcRegion.Y1 / src.Height;
|
||||
region[3] = srcRegion.Y2 / src.Height;
|
||||
|
||||
if (dstRegion.X1 > dstRegion.X2)
|
||||
{
|
||||
float temp = region[0];
|
||||
region[0] = region[1];
|
||||
region[1] = temp;
|
||||
}
|
||||
|
||||
if (dstRegion.Y1 > dstRegion.Y2)
|
||||
{
|
||||
float temp = region[2];
|
||||
region[2] = region[3];
|
||||
region[3] = temp;
|
||||
}
|
||||
|
||||
var bufferHandle = gd.BufferManager.CreateWithHandle(gd, RegionBufferSize);
|
||||
|
||||
gd.BufferManager.SetData<float>(bufferHandle, 0, region);
|
||||
|
||||
Span<BufferRange> bufferRanges = stackalloc BufferRange[1];
|
||||
|
||||
bufferRanges[0] = new BufferRange(bufferHandle, 0, RegionBufferSize);
|
||||
|
||||
pipeline.SetUniformBuffers(1, bufferRanges);
|
||||
|
||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
||||
|
||||
var rect = new Rectangle<float>(
|
||||
MathF.Min(dstRegion.X1, dstRegion.X2),
|
||||
MathF.Min(dstRegion.Y1, dstRegion.Y2),
|
||||
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
||||
MathF.Abs(dstRegion.Y2 - dstRegion.Y1));
|
||||
|
||||
viewports[0] = new GAL.Viewport(
|
||||
rect,
|
||||
ViewportSwizzle.PositiveX,
|
||||
ViewportSwizzle.PositiveY,
|
||||
ViewportSwizzle.PositiveZ,
|
||||
ViewportSwizzle.PositiveW,
|
||||
0f,
|
||||
1f);
|
||||
|
||||
Span<Rectangle<int>> scissors = stackalloc Rectangle<int>[1];
|
||||
|
||||
pipeline.SetProgram(_programColorBlit);
|
||||
pipeline.SetViewports(0, viewports);
|
||||
pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
||||
pipeline.Draw(4, 1, 0, 0);
|
||||
|
||||
gd.BufferManager.Delete(bufferHandle);
|
||||
}
|
||||
|
||||
public unsafe void ConvertI8ToI16(VulkanGraphicsDevice gd, CommandBufferScoped cbs, BufferHolder src, BufferHolder dst, int srcOffset, int size)
|
||||
{
|
||||
// TODO: Do this with a compute shader?
|
||||
|
|
|
@ -292,7 +292,50 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
public void DrawTexture(ITexture texture, ISampler sampler, Extents2DF srcRegion, Extents2DF dstRegion)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (texture is TextureView srcTexture)
|
||||
{
|
||||
var oldCullMode = _newState.CullMode;
|
||||
var oldStencilTestEnable = _newState.StencilTestEnable;
|
||||
var oldDepthTestEnable = _newState.DepthTestEnable;
|
||||
var oldDepthWriteEnable = _newState.DepthWriteEnable;
|
||||
var oldTopology = _newState.Topology;
|
||||
var oldViewports = VulkanConfiguration.UseDynamicState ? _dynamicState.Viewports : _newState.Internal.Viewports;
|
||||
var oldViewportsCount = _newState.ViewportsCount;
|
||||
|
||||
_newState.CullMode = CullModeFlags.CullModeNone;
|
||||
_newState.StencilTestEnable = false;
|
||||
_newState.DepthTestEnable = false;
|
||||
_newState.DepthWriteEnable = false;
|
||||
SignalStateChange();
|
||||
|
||||
Gd.HelperShader.DrawTexture(
|
||||
Gd,
|
||||
this,
|
||||
srcTexture,
|
||||
sampler,
|
||||
srcRegion,
|
||||
dstRegion);
|
||||
|
||||
_newState.CullMode = oldCullMode;
|
||||
_newState.StencilTestEnable = oldStencilTestEnable;
|
||||
_newState.DepthTestEnable = oldDepthTestEnable;
|
||||
_newState.DepthWriteEnable = oldDepthWriteEnable;
|
||||
_newState.Topology = oldTopology;
|
||||
|
||||
if (VulkanConfiguration.UseDynamicState)
|
||||
{
|
||||
_dynamicState.Viewports = oldViewports;
|
||||
_dynamicState.ViewportsCount = (int)oldViewportsCount;
|
||||
_dynamicState.SetViewportsDirty();
|
||||
}
|
||||
else
|
||||
{
|
||||
_newState.Internal.Viewports = oldViewports;
|
||||
}
|
||||
|
||||
_newState.ViewportsCount = oldViewportsCount;
|
||||
SignalStateChange();
|
||||
}
|
||||
}
|
||||
|
||||
public void EndTransformFeedback()
|
||||
|
@ -425,7 +468,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
public void SetFaceCulling(bool enable, Face face)
|
||||
{
|
||||
_newState.CullMode = enable ? face.Convert() : 0;
|
||||
_newState.CullMode = enable ? face.Convert() : CullModeFlags.CullModeNone;
|
||||
SignalStateChange();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
private uint _frontReference;
|
||||
|
||||
public int ViewportsCount;
|
||||
private Array16<Viewport> _viewports;
|
||||
public Array16<Viewport> Viewports;
|
||||
|
||||
private enum DirtyFlags
|
||||
{
|
||||
|
@ -70,11 +70,16 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
public void SetViewport(int index, Viewport viewport)
|
||||
{
|
||||
_viewports[index] = viewport;
|
||||
Viewports[index] = viewport;
|
||||
|
||||
_dirty |= DirtyFlags.Viewport;
|
||||
}
|
||||
|
||||
public void SetViewportsDirty()
|
||||
{
|
||||
_dirty |= DirtyFlags.Viewport;
|
||||
}
|
||||
|
||||
public void ForceAllDirty()
|
||||
{
|
||||
_dirty = DirtyFlags.All;
|
||||
|
@ -127,7 +132,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
private void RecordViewport(Vk api, CommandBuffer commandBuffer)
|
||||
{
|
||||
api.CmdSetViewport(commandBuffer, 0, (uint)ViewportsCount, _viewports.ToSpan());
|
||||
api.CmdSetViewport(commandBuffer, 0, (uint)ViewportsCount, Viewports.ToSpan());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue