RenderTargetGroup GetData, Shader uint support

This commit is contained in:
Simon Lübeß
2022-05-25 22:00:11 +02:00
parent 1418063d68
commit 28f1fad464
19 changed files with 354 additions and 44 deletions
@@ -12,20 +12,14 @@ namespace ImGui
{
static List<ID3D11ShaderResourceView*> _resourceViews = new .() ~ delete _;
public static override void Image(Texture2D texture, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 tint_col = Vec4.Ones, Vec4 border_col = Vec4.Zero)
public static override void Image(TextureViewBinding textureViewBinding, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 tint_col = Vec4.Ones, Vec4 border_col = Vec4.Zero)
{
var view = texture._nativeResourceView..AddRef();
var view = textureViewBinding._nativeShaderResourceView..AddRef();
_resourceViews.Add(view);
ImGui.Image(view, size, uv0, uv1, tint_col, border_col);
}
public static override void Image(RenderTarget2D texture, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 tint_col = Vec4.Ones, Vec4 border_col = Vec4.Zero)
{
var view = texture._nativeResourceView..AddRef();
_resourceViews.Add(view);
ImGui.Image(view, size, uv0, uv1, tint_col, border_col);
textureViewBinding.ReleaseRef();
}
protected internal static override void CleanupFrame()
@@ -37,6 +37,8 @@ namespace GlitchyEngine.Renderer
_type = .Float;
case .Int:
_type = .Int;
case .UInt:
_type = .UInt;
default:
Log.EngineLogger.Assert(false, scope $"Unhandled shader variable type: {shaderTypeDescription.Type}");
}
@@ -4,6 +4,7 @@ using DirectX.Common;
using DirectX.D3D11;
using GlitchyEngine.Platform.DX11;
using DirectX.DXGI.DXGI1_2;
using System;
using internal GlitchyEngine.Platform.DX11;
@@ -131,6 +132,11 @@ namespace GlitchyEngine.Renderer
{
switch(this)
{
case .R8_SInt:
return .R8_SInt;
case .R32_UInt:
return .R32_UInt;
case .R8G8B8A8_UNorm:
return .R8G8B8A8_UNorm;
case .R8G8B8A8_SNorm:
@@ -179,6 +185,7 @@ namespace GlitchyEngine.Renderer
extension RenderTargetGroup
{
protected uint32 _mipLevels;
internal ID3D11Texture2D*[] _nativeTextures;
internal ID3D11RenderTargetView*[] _renderTargetViews;
internal ID3D11ShaderResourceView*[] _nativeResourceViews;
@@ -218,6 +225,11 @@ namespace GlitchyEngine.Renderer
var result = NativeDevice.CreateTexture2D(ref desc, null, &texture);
Log.EngineLogger.Assert(result.Succeeded, "Failed to create RenderTarget2D");
// TODO: calculate the max mip level
// Read back the description to get the actual mip level count.
texture.GetDescription(let actualDesc);
_mipLevels = actualDesc.MipLevels;
return texture;
}
@@ -374,6 +386,63 @@ namespace GlitchyEngine.Renderer
return .(_nativeResourceViews[index], _colorSamplerStates[index].nativeSamplerState);
}
}
protected override Result<void> PlatformGetData(void* destination, uint32 elementSize, uint32 x, uint32 y, uint32 width, uint32 height, int renderTarget, uint32 arraySlice, uint32 mipLevel) // mapType?
{
Debug.Profiler.ProfileResourceFunction!();
ID3D11Texture2D* texture = renderTarget == -1 ? _nativeDepthTexture : _nativeTextures[renderTarget];
if (texture == null)
return .Err;
// TODO: Dynamic textures with CPU read access don't need a staging texture.
ID3D11Texture2D* stagingTexture = null;
Texture2DDescription stagingDesc = .();
stagingDesc.Width = width;
stagingDesc.Height = height;
stagingDesc.MipLevels = 1;
stagingDesc.ArraySize = 1;
stagingDesc.Format = _colorTargetDescriptions[renderTarget].Format.GetTextureFormat();
stagingDesc.SampleDesc = .(_description.Samples, 0);
stagingDesc.Usage = .Staging;
stagingDesc.BindFlags = .None;
stagingDesc.CpuAccessFlags = .Read;
stagingDesc.MiscFlags = .None;
var result = NativeDevice.CreateTexture2D(ref stagingDesc, null, &stagingTexture);
if (result != 0)
return .Err;
defer stagingTexture.Release();
uint32 srcSubResource = D3D11.CalcSubresource(mipLevel, arraySlice, _mipLevels);
Box srcBox = .(x, y, arraySlice, x + width, y + height, arraySlice + 1);
NativeContext.CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, texture, srcSubResource, &srcBox);
MappedSubresource subresource = ?;
result = NativeContext.Map(stagingTexture, 0, .Read, .None, &subresource);
defer NativeContext.Unmap(stagingTexture, 0);
if (result != 0)
return .Err;
for (int i < height)
{
uint32 destRowLength = elementSize * width;
uint32 count = Math.Min(destRowLength, subresource.RowPitch);
Internal.MemCpy((uint8*)destination + i * destRowLength, (uint8*)subresource.Data + i * subresource.RowPitch,
count);
}
return .Ok;
}
}
}
@@ -2,6 +2,7 @@
using GlitchyEngine.Math;
using GlitchyEngine.Platform.DX11;
using System;
using internal GlitchyEngine.Renderer;
using internal GlitchyEngine.Platform.DX11;
@@ -61,14 +62,31 @@ namespace GlitchyEngine.Renderer
NativeContext.ClearDepthStencilView(target.nativeView, flags, depth, stencil);
}
public override void Clear(RenderTargetGroup renderTarget, ClearOptions options, ColorRGBA? color = null, float? depth = null, uint8? stencil = null)
private void ClearRtv(DirectX.D3D11.ID3D11RenderTargetView* rtv, ClearColor clearColor)
{
switch(clearColor)
{
case .Color(let color):
NativeContext.ClearRenderTargetView(rtv, color);
case .UInt(let value):
/*#unwarn
NativeContext.OutputMerger.SetRenderTargets(1, &rtv, null);
BindRenderTargets();*/
default:
Runtime.NotImplemented();
}
}
public override void Clear(RenderTargetGroup renderTarget, ClearOptions options, ClearColor? color = null, float? depth = null, uint8? stencil = null)
{
if (options.HasFlag(.Color) && renderTarget._renderTargetViews != null)
{
for (int i < renderTarget._renderTargetViews.Count)
{
NativeContext.ClearRenderTargetView(renderTarget._renderTargetViews[i],
color ?? renderTarget._colorTargetDescriptions[i].ClearColor);
ClearRtv(renderTarget._renderTargetViews[i], color ?? renderTarget._colorTargetDescriptions[i].ClearColor);
}
}
@@ -88,9 +106,24 @@ namespace GlitchyEngine.Renderer
if (flags != default)
{
NativeContext.ClearDepthStencilView(renderTarget._nativeDepthTargetView, flags,
renderTarget._depthTargetDescription.ClearColor.R,
(uint8)renderTarget._depthTargetDescription.ClearColor.G);
float clearDepth = 0.0f;
uint8 clearStencil = 0;
if (renderTarget._depthTargetDescription.ClearColor case .DepthStencil(let d, let s))
{
clearDepth = d;
clearStencil = s;
}
else
{
Log.EngineLogger.Error("Clear color of depth stencil target must be of type DepthStencil.");
Log.EngineLogger.AssertDebug(false);
}
clearDepth = depth ?? clearDepth;
clearStencil = stencil ?? clearStencil;
NativeContext.ClearDepthStencilView(renderTarget._nativeDepthTargetView, flags, clearDepth, clearStencil);
}
}
}