I have some code created in 2010 I'm trying to bring to life. The source didnt include slimDX.dll so I have to use the latest. I get errors on ShaderBytecode as its not in the the same namespace anymore. also this line
_effect = new Effect( D3D11Device, _effectBytecode, EffectFlags.None );
no longer takes the 3 parms
I tried adding the D3DCompiler and omiting that last parm ( and it compiles ) but that crashes the app on MapSubresource
"E_INVALIDARG: An invalid parameter was passed to the returning function (-2147024809)"
Here is the source I'm having troubles with.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using System.Windows.Threading;
using System.Windows.Forms;
using System.Drawing;
using System.Configuration;
using SlimDX;
using SlimDX.DXGI;
using SlimDX.Direct3D11;
using LibSnesDotNet.Core;
using LibSnesDotNet.Threading;
using Device = SlimDX.Direct3D11.Device;
using Buffer = SlimDX.Direct3D11.Buffer;
using Configuration = System.Configuration.Configuration;
//using SlimDX.Direct3D9;
namespace LibSnesDotNet.Video
{
class Direct3D11Driver : Direct3D11Base, IVideoDriver
{
WorkerThread _workerThread;
WaitableBool _isBusy;
DeviceContext _context;
RenderTargetView _backBufferView;
ShaderBytecode _effectBytecode;
Effect _effect;
EffectTechnique _technique;
EffectPass _pass;
InputLayout _layout;
Buffer _vertices;
Texture2D _texture;
ShaderResourceView _textureView;
public Direct3D11Driver(Form form, Configuration config)
: base(form, new SwapChainDescription()
{
IsWindowed = true,
BufferCount = 1,
SwapEffect = SwapEffect.Discard,
Usage = Usage.RenderTargetOutput,
Flags = SwapChainFlags.None,
SampleDescription = new SampleDescription(1, 0),
ModeDescription = new ModeDescription(form.ClientSize.Width, form.ClientSize.Height, new Rational(), Format.R8G8B8A8_UNorm)
})
{
IsDisposed = false;
try
{
_workerThread = new WorkerThread();
_isBusy = new WaitableBool(false);
_context = D3D11Device.ImmediateContext;
_backBufferView = GetBackBufferView();
_context.OutputMerger.SetTargets(_backBufferView);
Viewport viewPort = new Viewport()
{
X = 0,
Y = 0,
Width = form.ClientSize.Width,
Height = form.ClientSize.Height,
MinZ = 0.0F,
MaxZ = 1.0F
};
_context.Rasterizer.SetViewports(viewPort);
_effectBytecode = ShaderBytecode.CompileFromFile( "Effect.fx", " ", "fx_5_0", ShaderFlags.None,EffectFlags.None, null, null );
_effect = new Effect( D3D11Device, _effectBytecode, EffectFlags.None );
_technique = _effect.GetTechniqueByIndex(0);
_pass = _technique.GetPassByIndex(0);
InputElement[] elements = new InputElement[]
{
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
new InputElement("TEXCOORD", 0, Format.R32G32_Float, 16, 0)
};
_layout = new InputLayout(D3D11Device, _pass.Description.Signature, elements);
DataStream stream = new DataStream(4 * Marshal.SizeOf(typeof(Vertex)), true, true);
stream.Write(new Vector4(-1.0F, 1.0F, 0.5F, 1.0F));
stream.Write(new Vector2(0.0F, 0.0F));
stream.Write(new Vector4(1.0F, 1.0F, 0.5F, 1.0F));
stream.Write(new Vector2(1.0F, 0.0F));
stream.Write(new Vector4(-1.0F, -1.0F, 0.5F, 1.0F));
stream.Write(new Vector2(0.0F, 1.0F));
stream.Write(new Vector4(1.0F, -1.0F, 0.5F, 1.0F));
stream.Write(new Vector2(1.0F, 1.0F));
stream.Position = 0;
_vertices = new Buffer(D3D11Device, stream, new BufferDescription()
{
SizeInBytes = (int)stream.Length,
BindFlags = BindFlags.VertexBuffer,
Usage = ResourceUsage.Default,
CpuAccessFlags = CpuAccessFlags.None,
OptionFlags = ResourceOptionFlags.None
});
stream.Close();
_texture = new Texture2D(D3D11Device, new Texture2DDescription()
{
Width = 512,
Height = 512,
Format = Format.R8G8B8A8_UNorm,
ArraySize = 1,
MipLevels = 1,
Usage = ResourceUsage.Dynamic,
CpuAccessFlags = CpuAccessFlags.Write,
BindFlags = BindFlags.ShaderResource,
SampleDescription = SwapChainDescription.SampleDescription
});
_textureView = new ShaderResourceView(D3D11Device, _texture);
_effect.GetVariableByName("InputTexture").AsResource().SetResource(_textureView);
}
catch
{
Dispose();
throw;
}
}
public IWaitableBool IsBusy { get { return new ReadOnlyWaitableBool(_isBusy); } }
bool IVideoDriver.IsFullscreen
{
get { return IsFullscreen; }
set
{
_isBusy.Acquire(true);
ChangeMode(value);
_isBusy.Value = false;
}
}
public void Render(VideoUpdatedEventArgs e)
{
while (!TryRender(e))
{
_isBusy.WaitWhile();
}
}
public bool TryRender(VideoUpdatedEventArgs e)
{
AssertUndisposed();
if (!_isBusy.TryAcquire(true)) { return false; }
DataBox dataBox = _context.MapSubresource(_texture, 0, 512 * 512 * 4, MapMode.WriteDiscard, SlimDX.Direct3D11.MapFlags.None);
unsafe
{
ushort* snesBuffer = (ushort*)e.VideoBuffer.DataPointer;
byte* textureBuffer = (byte*)dataBox.Data.DataPointer;
for (int j = 0; j < e.Height; j++)
{
for (int i = 0; i < e.Width; i++)
{
ushort color = *snesBuffer++;
int b;
b = ((color >> 10) & 31) * 8;
*textureBuffer++ = (byte)(b + b / 35);
b = ((color >> 5) & 31) * 8;
*textureBuffer++ = (byte)(b + b / 35);
b = ((color >> 0) & 31) * 8;
*textureBuffer++ = (byte)(b + b / 35);
*textureBuffer++ = 255;
}
textureBuffer += dataBox.RowPitch - e.Width * 4;
snesBuffer += e.Height > 256 ? 512 - e.Width : 1024 - e.Width;
}
}
dataBox.Data.Close();
_context.UnmapSubresource(_texture, 0);
_workerThread.DoWork(new Action(() =>
{
AssertUndisposed();
_context.ClearRenderTargetView(_backBufferView, new Color4(0.0F, 0.0F, 0.0F));
_context.InputAssembler.InputLayout = _layout;
_context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;
_context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(_vertices, Marshal.SizeOf(typeof(Vertex)), 0));
_effect.GetVariableByName("TexelRange").AsVector().Set(new Vector2(e.Width / 512.0F, e.Height / 512.0F));
_pass.Apply(_context);
_context.Draw(4, 0);
Present(IsComposited && !IsFullscreen ? 0 : 1, PresentFlags.None);
_isBusy.Value = false;
}));
return true;
}
protected override void OnFullscreenToggled()
{
_isBusy.Acquire(true);
base.OnFullscreenToggled();
_isBusy.Value = false;
}
protected override void OnBuffersChanging()
{
_isBusy.Acquire(true);
_backBufferView.Resource.Dispose();
_backBufferView.Dispose();
base.OnBuffersChanging();
}
protected override void OnBuffersChanged()
{
_backBufferView = GetBackBufferView();
_context.OutputMerger.SetTargets(_backBufferView);
Rectangle viewRect = new Rectangle();
if (Form.ClientSize.Height * (4.0F / 3.0F) + 2 < Form.ClientSize.Width)
{
viewRect.Width = (int)(Form.ClientSize.Height * (4.0F / 3.0F));
viewRect.Height = Form.ClientSize.Height;
viewRect.X = (Form.ClientSize.Width - viewRect.Width) / 2;
viewRect.Y = 0;
}
else if (Form.ClientSize.Width * (3.0F / 4.0F) + 2 < Form.ClientSize.Height)
{
viewRect.Width = Form.ClientSize.Width;
viewRect.Height = (int)(Form.ClientSize.Width * (3.0F / 4.0F));
viewRect.X = 0;
viewRect.Y = (Form.ClientSize.Height - viewRect.Height) / 2;
}
else
{
viewRect.Width = Form.ClientSize.Width;
viewRect.Height = Form.ClientSize.Height;
viewRect.X = 0;
viewRect.Y = 0;
}
_context.Rasterizer.SetViewports(new Viewport()
{
X = viewRect.X,
Y = viewRect.Y,
Width = viewRect.Width,
Height = viewRect.Height,
MinZ = 0.0F,
MaxZ = 1.0F
});
base.OnBuffersChanged();
_isBusy.Value = false;
}
public new bool IsDisposed { get; private set; }
public new void Dispose()
{
AssertUndisposed();
IsDisposed = true;
if (_workerThread != null)
{
_workerThread.WaitFor();
_workerThread.Dispose();
}
if (_context != null) { _context.Dispose(); }
if (_backBufferView != null)
{
_backBufferView.Resource.Dispose();
_backBufferView.Dispose();
}
if (_effectBytecode != null) { _effectBytecode.Dispose(); }
if (_effect != null) { _effect.Dispose(); }
if (_layout != null) { _layout.Dispose(); }
if (_vertices != null) { _vertices.Dispose(); }
if (_texture != null) { _texture.Dispose(); }
if (_textureView != null) { _textureView.Dispose(); }
base.Dispose();
}
public new void AssertUndisposed()
{
if (IsDisposed) { throw new ObjectDisposedException(ToString()); }
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct Vertex
{
public Vector4 Position;
public Vector2 TexCoord;
}
}