d3d12: Fix some warning and start adding IALayout support

This commit is contained in:
vlj 2015-05-11 20:20:58 +02:00 committed by Vincent Lejeune
parent d2889786a2
commit 722e6b8ac5
7 changed files with 315 additions and 42 deletions

View File

@ -0,0 +1,4 @@
#include "stdafx.h"
#if defined(DX12_SUPPORT)
#endif

View File

@ -0,0 +1,4 @@
#pragma once
#if defined(DX12_SUPPORT)
#endif

View File

@ -194,6 +194,267 @@ void D3D12GSRender::ExecCMD(u32 cmd)
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**) &commandList);
}
// Where are these type defined ???
static
DXGI_FORMAT getFormat(u8 type, u8 size)
{
/*static const u32 gl_types[] =
{
GL_SHORT,
GL_FLOAT,
GL_HALF_FLOAT,
GL_UNSIGNED_BYTE,
GL_SHORT,
GL_FLOAT, // Needs conversion
GL_UNSIGNED_BYTE,
};
static const bool gl_normalized[] =
{
GL_TRUE,
GL_FALSE,
GL_FALSE,
GL_TRUE,
GL_FALSE,
GL_TRUE,
GL_FALSE,
};*/
static const DXGI_FORMAT typeX1[] =
{
DXGI_FORMAT_R16_SNORM,
DXGI_FORMAT_R32_FLOAT,
DXGI_FORMAT_R16_FLOAT,
DXGI_FORMAT_R8_UNORM,
DXGI_FORMAT_R16_SINT,
DXGI_FORMAT_R32_FLOAT,
DXGI_FORMAT_R8_UINT
};
static const DXGI_FORMAT typeX2[] =
{
DXGI_FORMAT_R16G16_SNORM,
DXGI_FORMAT_R32G32_FLOAT,
DXGI_FORMAT_R16G16_FLOAT,
DXGI_FORMAT_R8G8_UNORM,
DXGI_FORMAT_R16G16_SINT,
DXGI_FORMAT_R32G32_FLOAT,
DXGI_FORMAT_R8G8_UINT
};
static const DXGI_FORMAT typeX3[] =
{
DXGI_FORMAT_R16G16B16A16_SNORM,
DXGI_FORMAT_R32G32B32_FLOAT,
DXGI_FORMAT_R16G16B16A16_FLOAT,
DXGI_FORMAT_R8G8B8A8_UNORM,
DXGI_FORMAT_R16G16B16A16_SINT,
DXGI_FORMAT_R32G32B32_FLOAT,
DXGI_FORMAT_R8G8B8A8_UINT
};
static const DXGI_FORMAT typeX4[] =
{
DXGI_FORMAT_R16G16B16A16_SNORM,
DXGI_FORMAT_R32G32B32A32_FLOAT,
DXGI_FORMAT_R16G16B16A16_FLOAT,
DXGI_FORMAT_R8G8B8A8_UNORM,
DXGI_FORMAT_R16G16B16A16_SINT,
DXGI_FORMAT_R32G32B32A32_FLOAT,
DXGI_FORMAT_R8G8B8A8_UINT
};
switch (size)
{
case 1:
return typeX1[type];
case 2:
return typeX2[type];
case 3:
return typeX3[type];
case 4:
return typeX4[type];
}
}
void D3D12GSRender::EnableVertexData(bool indexed_draw)
{
static u32 offset_list[m_vertex_count];
u32 cur_offset = 0;
const u32 data_offset = indexed_draw ? 0 : m_draw_array_first;
for (u32 i = 0; i < m_vertex_count; ++i)
{
offset_list[i] = cur_offset;
if (!m_vertex_data[i].IsEnabled()) continue;
const size_t item_size = m_vertex_data[i].GetTypeSize() * m_vertex_data[i].size;
const size_t data_size = m_vertex_data[i].data.size() - data_offset * item_size;
const u32 pos = m_vdata.size();
cur_offset += data_size;
m_vdata.resize(m_vdata.size() + data_size);
memcpy(&m_vdata[pos], &m_vertex_data[i].data[data_offset * item_size], data_size);
}
/* m_vao.Create();
m_vao.Bind();
checkForGlError("initializing vao");
m_vbo.Create(indexed_draw ? 2 : 1);
m_vbo.Bind(0);
m_vbo.SetData(m_vdata.data(), m_vdata.size());*/
if (indexed_draw)
{
// TODO: Use default heap and upload data
D3D12_HEAP_PROPERTIES heapProp = {};
heapProp.Type = D3D12_HEAP_TYPE_UPLOAD;
D3D12_RESOURCE_DESC resDesc = {};
resDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
resDesc.Width = (UINT)m_indexed_array.m_data.size();
resDesc.Height = 1;
resDesc.DepthOrArraySize = 1;
resDesc.SampleDesc.Count = 1;
check(m_device->CreateCommittedResource(
&heapProp,
D3D12_HEAP_FLAG_NONE,
&resDesc,
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&m_indexBuffer)
));
void *indexBufferMap;
check(m_indexBuffer->Map(0, nullptr, (void**)indexBufferMap));
memcpy(indexBufferMap, m_indexed_array.m_data.data(), m_indexed_array.m_data.size());
m_indexBuffer->Unmap(0, nullptr);
D3D12_INDEX_BUFFER_VIEW indexBufferView = {};
indexBufferView.SizeInBytes = (UINT)m_indexed_array.m_data.size();
indexBufferView.BufferLocation = m_indexBuffer->GetGPUVirtualAddress();
}
#if DUMP_VERTEX_DATA
rFile dump("VertexDataArray.dump", rFile::write);
#endif
m_IASet.clear();
for (u32 i = 0; i < m_vertex_count; ++i)
{
if (!m_vertex_data[i].IsEnabled()) continue;
#if DUMP_VERTEX_DATA
dump.Write(wxString::Format("VertexData[%d]:\n", i));
switch (m_vertex_data[i].type)
{
case CELL_GCM_VERTEX_S1:
for (u32 j = 0; j < m_vertex_data[i].data.size(); j += 2)
{
dump.Write(wxString::Format("%d\n", *(u16*)&m_vertex_data[i].data[j]));
if (!(((j + 2) / 2) % m_vertex_data[i].size)) dump.Write("\n");
}
break;
case CELL_GCM_VERTEX_F:
for (u32 j = 0; j < m_vertex_data[i].data.size(); j += 4)
{
dump.Write(wxString::Format("%.01f\n", *(float*)&m_vertex_data[i].data[j]));
if (!(((j + 4) / 4) % m_vertex_data[i].size)) dump.Write("\n");
}
break;
case CELL_GCM_VERTEX_SF:
for (u32 j = 0; j < m_vertex_data[i].data.size(); j += 2)
{
dump.Write(wxString::Format("%.01f\n", *(float*)&m_vertex_data[i].data[j]));
if (!(((j + 2) / 2) % m_vertex_data[i].size)) dump.Write("\n");
}
break;
case CELL_GCM_VERTEX_UB:
for (u32 j = 0; j < m_vertex_data[i].data.size(); ++j)
{
dump.Write(wxString::Format("%d\n", m_vertex_data[i].data[j]));
if (!((j + 1) % m_vertex_data[i].size)) dump.Write("\n");
}
break;
case CELL_GCM_VERTEX_S32K:
for (u32 j = 0; j < m_vertex_data[i].data.size(); j += 2)
{
dump.Write(wxString::Format("%d\n", *(u16*)&m_vertex_data[i].data[j]));
if (!(((j + 2) / 2) % m_vertex_data[i].size)) dump.Write("\n");
}
break;
// case CELL_GCM_VERTEX_CMP:
case CELL_GCM_VERTEX_UB256:
for (u32 j = 0; j < m_vertex_data[i].data.size(); ++j)
{
dump.Write(wxString::Format("%d\n", m_vertex_data[i].data[j]));
if (!((j + 1) % m_vertex_data[i].size)) dump.Write("\n");
}
break;
default:
LOG_ERROR(HLE, "Bad cv type! %d", m_vertex_data[i].type);
return;
}
dump.Write("\n");
#endif
if (m_vertex_data[i].type < 1 || m_vertex_data[i].type > 7)
{
LOG_ERROR(RSX, "GLGSRender::EnableVertexData: Bad vertex data type (%d)!", m_vertex_data[i].type);
}
D3D12_INPUT_ELEMENT_DESC IAElement = {};
/* if (!m_vertex_data[i].addr)
{
switch (m_vertex_data[i].type)
{
case CELL_GCM_VERTEX_S32K:
case CELL_GCM_VERTEX_S1:
switch (m_vertex_data[i].size)
{
case 1: glVertexAttrib1s(i, (GLshort&)m_vertex_data[i].data[0]); break;
case 2: glVertexAttrib2sv(i, (GLshort*)&m_vertex_data[i].data[0]); break;
case 3: glVertexAttrib3sv(i, (GLshort*)&m_vertex_data[i].data[0]); break;
case 4: glVertexAttrib4sv(i, (GLshort*)&m_vertex_data[i].data[0]); break;
}
break;
case CELL_GCM_VERTEX_F:
switch (m_vertex_data[i].size)
{
case 1: glVertexAttrib1f(i, (GLfloat&)m_vertex_data[i].data[0]); break;
case 2: glVertexAttrib2fv(i, (GLfloat*)&m_vertex_data[i].data[0]); break;
case 3: glVertexAttrib3fv(i, (GLfloat*)&m_vertex_data[i].data[0]); break;
case 4: glVertexAttrib4fv(i, (GLfloat*)&m_vertex_data[i].data[0]); break;
}
break;
case CELL_GCM_VERTEX_CMP:
case CELL_GCM_VERTEX_UB:
glVertexAttrib4ubv(i, (GLubyte*)&m_vertex_data[i].data[0]);
break;
}
checkForGlError("glVertexAttrib");
}
else*/
{
IAElement.SemanticName = "TEXCOORD";
IAElement.SemanticIndex = i;
IAElement.Format = getFormat(m_vertex_data[i].type - 1, m_vertex_data[i].size);
IAElement.AlignedByteOffset = offset_list[i];
}
m_IASet.push_back(IAElement);
}
}
bool D3D12GSRender::LoadProgram()
{
@ -211,12 +472,25 @@ bool D3D12GSRender::LoadProgram()
return false;
}
m_PSO = cachePSO.getGraphicPipelineState(m_device, m_cur_vertex_prog, m_cur_fragment_prog);
m_PSO = m_cachePSO.getGraphicPipelineState(m_device, m_cur_vertex_prog, m_cur_fragment_prog, m_IASet);
return true;
}
void D3D12GSRender::ExecCMD()
{
if (m_indexed_array.m_count)
{
// LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1);
}
if (m_indexed_array.m_count || m_draw_array_count)
{
EnableVertexData(m_indexed_array.m_count ? true : false);
// InitVertexData();
// InitFragmentData();
}
if (!LoadProgram())
{
LOG_ERROR(RSX, "LoadProgram failed.");
@ -520,24 +794,9 @@ void D3D12GSRender::ExecCMD()
m_program.SetVTex(i);
m_gl_vertex_textures[i].Init(m_vertex_textures[i]);
checkForGlError(fmt::Format("m_gl_vertex_textures[%d].Init", i));
}
}*/
m_vao.Bind();
if (m_indexed_array.m_count)
{
LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1);
}
if (m_indexed_array.m_count || m_draw_array_count)
{
EnableVertexData(m_indexed_array.m_count ? true : false);
InitVertexData();
InitFragmentData();
}
if (m_indexed_array.m_count)
/* if (m_indexed_array.m_count)
{
switch (m_indexed_array.m_type)
{

View File

@ -12,6 +12,7 @@
#include "D3D12RenderTargetSets.h"
#include "D3D12PipelineState.h"
#include "D3D12Buffer.h"
#pragma comment (lib, "d3d12.lib")
#pragma comment (lib, "dxgi.lib")
@ -39,18 +40,14 @@ typedef GSFrameBase2*(*GetGSFrameCb2)();
void SetGetD3DGSFrameCallback(GetGSFrameCb2 value);
class D3D12GSRender //TODO: find out why this used to inherit from wxWindow
: //public wxWindow
/*,*/ public GSRender
class D3D12GSRender : public GSRender
{
private:
// std::vector<u8> m_vdata;
std::vector<u8> m_vdata;
// std::vector<PostDrawObj> m_post_draw_objs;
PipelineStateObjectCache cachePSO;
PipelineStateObjectCache m_cachePSO;
ID3D12PipelineState *m_PSO;
int m_fp_buf_num;
int m_vp_buf_num;
// GLProgramBuffer m_prog_buffer;
// GLFragmentProgram m_fragment_prog;
@ -59,6 +56,8 @@ private:
// GLTexture m_gl_textures[m_textures_count];
// GLTexture m_gl_vertex_textures[m_textures_count];
ID3D12Resource *m_indexBuffer;
std::vector<D3D12_INPUT_ELEMENT_DESC> m_IASet;
// GLvao m_vao;
// GLvbo m_vbo;
D3D12RenderTargetSets *m_fbo;
@ -73,9 +72,6 @@ private:
ID3D12DescriptorHeap *m_backbufferAsRendertarget[2];
size_t m_lastWidth, m_lastHeight, m_lastDepth;
void* m_context;
public:
GSFrameBase2 *m_frame;
u32 m_draw_frames;
@ -88,8 +84,8 @@ private:
virtual void Close() override;
bool LoadProgram();
/* void EnableVertexData(bool indexed_draw = false);
void DisableVertexData();
void EnableVertexData(bool indexed_draw = false);
/*void DisableVertexData();
void InitVertexData();
void InitFragmentData();

View File

@ -57,7 +57,8 @@ bool PipelineStateObjectCache::SearchVp(const RSXVertexProgram& rsx_vp, Shader&
ID3D12PipelineState *PipelineStateObjectCache::GetProg(u32 fp, u32 vp) const
{
u64 key = vp << 32 | fp;
u64 vpLong = vp;
u64 key = vpLong << 32 | fp;
std::unordered_map<u64, ID3D12PipelineState *>::const_iterator It = cachePSO.find(key);
if (It == cachePSO.end())
return nullptr;
@ -69,7 +70,7 @@ void PipelineStateObjectCache::AddVertexProgram(Shader& vp, RSXVertexProgram& rs
size_t actualVPSize = rsx_vp.data.size() * 4;
void *fpShadowCopy = malloc(actualVPSize);
memcpy(fpShadowCopy, rsx_vp.data.data(), actualVPSize);
vp.Id = currentShaderId++;
vp.Id = (u32)currentShaderId++;
cacheVS.insert(std::make_pair(fpShadowCopy, vp));
}
@ -78,17 +79,18 @@ void PipelineStateObjectCache::AddFragmentProgram(Shader& fp, RSXFragmentProgram
size_t actualFPSize = getFPBinarySize(vm::get_ptr<u8>(rsx_fp.addr));
void *fpShadowCopy = malloc(actualFPSize);
memcpy(fpShadowCopy, vm::get_ptr<u8>(rsx_fp.addr), actualFPSize);
fp.Id = currentShaderId++;
fp.Id = (u32)currentShaderId++;
cacheFS.insert(std::make_pair(fpShadowCopy, fp));
}
void PipelineStateObjectCache::Add(ID3D12PipelineState *prog, Shader& fp, Shader& vp)
{
u64 key = vp.Id << 32 | fp.Id;
u64 vpLong = vp.Id;
u64 key = vpLong << 32 | fp.Id;
cachePSO.insert(std::make_pair(key, prog));
}
ID3D12PipelineState *PipelineStateObjectCache::getGraphicPipelineState(ID3D12Device *device, RSXVertexProgram *vertexShader, RSXFragmentProgram *fragmentShader)
ID3D12PipelineState *PipelineStateObjectCache::getGraphicPipelineState(ID3D12Device *device, RSXVertexProgram *vertexShader, RSXFragmentProgram *fragmentShader, const std::vector<D3D12_INPUT_ELEMENT_DESC> &IASet)
{
ID3D12PipelineState *result = nullptr;
Shader m_vertex_prog, m_fragment_prog;
@ -199,9 +201,9 @@ ID3D12PipelineState *PipelineStateObjectCache::getGraphicPipelineState(ID3D12Dev
{
FALSE,FALSE,
D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
D3D12_LOGIC_OP_NOOP,
D3D12_COLOR_WRITE_ENABLE_ALL,
D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
D3D12_LOGIC_OP_NOOP,
D3D12_COLOR_WRITE_ENABLE_ALL,
}
};
@ -214,8 +216,8 @@ ID3D12PipelineState *PipelineStateObjectCache::getGraphicPipelineState(ID3D12Dev
graphicPipelineStateDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
graphicPipelineStateDesc.DSVFormat = DXGI_FORMAT_D16_UNORM;
// graphicPipelineStateDesc.InputLayout.pInputElementDescs = VTXLayout::getInputAssemblyLayout();
// graphicPipelineStateDesc.InputLayout.NumElements = (UINT)VTXLayout::getInputAssemblySize();
graphicPipelineStateDesc.InputLayout.pInputElementDescs = IASet.data();
graphicPipelineStateDesc.InputLayout.NumElements = (UINT)IASet.size();
graphicPipelineStateDesc.SampleDesc.Count = 1;
graphicPipelineStateDesc.SampleMask = UINT_MAX;
graphicPipelineStateDesc.NodeMask = 1;
@ -235,6 +237,7 @@ ID3D12PipelineState *PipelineStateObjectCache::getGraphicPipelineState(ID3D12Dev
m_debug_programs.push_back(program);
}*/
}
return result;
}
@ -245,7 +248,7 @@ void Shader::Compile(SHADER_TYPE st)
static const char VSstring[] =
"#define RS \"RootFlags( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT)\"\n"
"[RootSignature(RS)]\n"
"float4 main(float4 pos : POSITION) : SV_POSITION\n"
"float4 main(float4 pos : TEXCOORD0) : SV_POSITION\n"
"{\n"
" return pos;\n"
"}";

View File

@ -160,7 +160,8 @@ private:
public:
PipelineStateObjectCache();
~PipelineStateObjectCache();
ID3D12PipelineState *getGraphicPipelineState(ID3D12Device *device, RSXVertexProgram *vertexShader, RSXFragmentProgram *fragmentShader);
// Note: the last param is not taken into account if the PSO is not regenerated
ID3D12PipelineState *getGraphicPipelineState(ID3D12Device *device, RSXVertexProgram *vertexShader, RSXFragmentProgram *fragmentShader, const std::vector<D3D12_INPUT_ELEMENT_DESC> &IASet);
};

View File

@ -971,6 +971,9 @@
<ClCompile Include="Emu\RSX\D3D12\D3D12GSRender.cpp">
<Filter>Emu\GPU\RSX\D3D12</Filter>
</ClCompile>
<ClCompile Include="Emu\RSX\D3D12\D3D12Buffer.cpp">
<Filter>Emu\GPU\RSX\D3D12</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Crypto\aes.h">
@ -1840,5 +1843,8 @@
<ClInclude Include="Emu\RSX\D3D12\D3D12RenderTargetSets.h">
<Filter>Emu\GPU\RSX\D3D12</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\D3D12\D3D12Buffer.h">
<Filter>Emu\GPU\RSX\D3D12</Filter>
</ClInclude>
</ItemGroup>
</Project>