VideoCommon: Add a separate constants buffer for the geometry shader.

This commit is contained in:
Jules Blok
2014-12-14 21:23:13 +01:00
parent 21ac9aa715
commit b406e4e1f2
19 changed files with 189 additions and 23 deletions

View File

@ -17,6 +17,8 @@
#include "VideoCommon/Debugger.h"
#include "VideoCommon/GeometryShaderGen.h"
#include "VideoCommon/GeometryShaderManager.h"
#include "VideoCommon/Statistics.h"
#include "VideoCommon/VideoConfig.h"
namespace DX11
@ -37,6 +39,22 @@ ID3D11GeometryShader* GeometryShaderCache::GetCopyGeometryShader() { return Copy
ID3D11Buffer* gscbuf = nullptr;
ID3D11Buffer* &GeometryShaderCache::GetConstantBuffer()
{
// TODO: divide the global variables of the generated shaders into about 5 constant buffers to speed this up
if (GeometryShaderManager::dirty)
{
D3D11_MAPPED_SUBRESOURCE map;
D3D::context->Map(gscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
memcpy(map.pData, &GeometryShaderManager::constants, sizeof(GeometryShaderConstants));
D3D::context->Unmap(gscbuf, 0);
GeometryShaderManager::dirty = false;
ADDSTAT(stats.thisFrame.bytesUniformStreamed, sizeof(GeometryShaderConstants));
}
return gscbuf;
}
// this class will load the precompiled shaders into our cache
class GeometryShaderCacheInserter : public LinearDiskCacheReader<GeometryShaderUid, u8>
{
@ -113,6 +131,12 @@ const char copy_shader_code[] = {
void GeometryShaderCache::Init()
{
unsigned int gbsize = ((sizeof(GeometryShaderConstants))&(~0xf)) + 0x10; // must be a multiple of 16
D3D11_BUFFER_DESC gbdesc = CD3D11_BUFFER_DESC(gbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
HRESULT hr = D3D::device->CreateBuffer(&gbdesc, nullptr, &gscbuf);
CHECK(hr == S_OK, "Create geometry shader constant buffer (size=%u)", gbsize);
D3D::SetDebugObjectName((ID3D11DeviceChild*)gscbuf, "geometry shader constant buffer used to emulate the GX pipeline");
// used when drawing clear quads
ClearGeometryShader = D3D::CompileAndCreateGeometryShader(clear_shader_code);
CHECK(ClearGeometryShader != nullptr, "Create clear geometry shader");
@ -152,6 +176,8 @@ void GeometryShaderCache::Clear()
void GeometryShaderCache::Shutdown()
{
SAFE_RELEASE(gscbuf);
SAFE_RELEASE(ClearGeometryShader);
SAFE_RELEASE(CopyGeometryShader);

View File

@ -25,6 +25,7 @@ public:
static ID3D11GeometryShader* GeometryShaderCache::GetCopyGeometryShader();
static ID3D11GeometryShader* GetActiveShader() { return last_entry->shader; }
static ID3D11Buffer* &GetConstantBuffer();
private:
struct GSCacheEntry

View File

@ -140,7 +140,7 @@ void VertexManager::Draw(u32 stride)
if (current_primitive_type == PRIMITIVE_TRIANGLES)
{
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
D3D::stateman->SetGeometryConstants(VertexShaderCache::GetConstantBuffer());
D3D::stateman->SetGeometryConstants(GeometryShaderCache::GetConstantBuffer());
D3D::stateman->SetGeometryShader(g_ActiveConfig.iStereoMode > 0 ? GeometryShaderCache::GetActiveShader() : nullptr);
D3D::stateman->Apply();

View File

@ -28,6 +28,7 @@
#include "VideoCommon/BPStructs.h"
#include "VideoCommon/CommandProcessor.h"
#include "VideoCommon/Fifo.h"
#include "VideoCommon/GeometryShaderManager.h"
#include "VideoCommon/IndexGenerator.h"
#include "VideoCommon/OnScreenDisplay.h"
#include "VideoCommon/OpcodeDecoding.h"
@ -187,6 +188,7 @@ void VideoBackend::Video_Prepare()
OpcodeDecoder_Init();
VertexShaderManager::Init();
PixelShaderManager::Init();
GeometryShaderManager::Init();
CommandProcessor::Init();
PixelEngine::Init();
BBox::Init();
@ -205,6 +207,7 @@ void VideoBackend::Shutdown()
// VideoCommon
Fifo_Shutdown();
CommandProcessor::Shutdown();
GeometryShaderManager::Shutdown();
PixelShaderManager::Shutdown();
VertexShaderManager::Shutdown();
OpcodeDecoder_Shutdown();

View File

@ -13,6 +13,7 @@
#include "VideoCommon/Debugger.h"
#include "VideoCommon/DriverDetails.h"
#include "VideoCommon/GeometryShaderManager.h"
#include "VideoCommon/ImageWrite.h"
#include "VideoCommon/PixelShaderManager.h"
#include "VideoCommon/Statistics.h"
@ -71,11 +72,14 @@ void SHADER::SetProgramVariables()
GLint PSBlock_id = glGetUniformBlockIndex(glprogid, "PSBlock");
GLint VSBlock_id = glGetUniformBlockIndex(glprogid, "VSBlock");
GLint GSBlock_id = glGetUniformBlockIndex(glprogid, "GSBlock");
if (PSBlock_id != -1)
glUniformBlockBinding(glprogid, PSBlock_id, 1);
if (VSBlock_id != -1)
glUniformBlockBinding(glprogid, VSBlock_id, 2);
if (GSBlock_id != -1)
glUniformBlockBinding(glprogid, GSBlock_id, 3);
// Bind Texture Sampler
for (int a = 0; a <= 9; ++a)
@ -133,7 +137,7 @@ void SHADER::Bind()
void ProgramShaderCache::UploadConstants()
{
if (PixelShaderManager::dirty || VertexShaderManager::dirty)
if (PixelShaderManager::dirty || VertexShaderManager::dirty || GeometryShaderManager::dirty)
{
auto buffer = s_buffer->Map(s_ubo_buffer_size, s_ubo_align);
@ -143,14 +147,20 @@ void ProgramShaderCache::UploadConstants()
memcpy(buffer.first + ROUND_UP(sizeof(PixelShaderConstants), s_ubo_align),
&VertexShaderManager::constants, sizeof(VertexShaderConstants));
memcpy(buffer.first + ROUND_UP(sizeof(PixelShaderConstants), s_ubo_align) + ROUND_UP(sizeof(VertexShaderConstants), s_ubo_align),
&GeometryShaderManager::constants, sizeof(GeometryShaderConstants));
s_buffer->Unmap(s_ubo_buffer_size);
glBindBufferRange(GL_UNIFORM_BUFFER, 1, s_buffer->m_buffer, buffer.second,
sizeof(PixelShaderConstants));
glBindBufferRange(GL_UNIFORM_BUFFER, 2, s_buffer->m_buffer, buffer.second + ROUND_UP(sizeof(PixelShaderConstants), s_ubo_align),
sizeof(VertexShaderConstants));
glBindBufferRange(GL_UNIFORM_BUFFER, 3, s_buffer->m_buffer, buffer.second + ROUND_UP(sizeof(PixelShaderConstants), s_ubo_align) + ROUND_UP(sizeof(VertexShaderConstants), s_ubo_align),
sizeof(GeometryShaderConstants));
PixelShaderManager::dirty = false;
VertexShaderManager::dirty = false;
GeometryShaderManager::dirty = false;
ADDSTAT(stats.thisFrame.bytesUniformStreamed, s_ubo_buffer_size);
}
@ -419,7 +429,7 @@ void ProgramShaderCache::Init()
// then the UBO will fail.
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &s_ubo_align);
s_ubo_buffer_size = ROUND_UP(sizeof(PixelShaderConstants), s_ubo_align) + ROUND_UP(sizeof(VertexShaderConstants), s_ubo_align);
s_ubo_buffer_size = ROUND_UP(sizeof(PixelShaderConstants), s_ubo_align) + ROUND_UP(sizeof(VertexShaderConstants), s_ubo_align) + ROUND_UP(sizeof(GeometryShaderConstants), s_ubo_align);
// We multiply by *4*4 because we need to get down to basic machine units.
// So multiply by four to get how many floats we have from vec4s

View File

@ -65,6 +65,7 @@ Make AA apply instantly during gameplay if possible
#include "VideoCommon/BPStructs.h"
#include "VideoCommon/CommandProcessor.h"
#include "VideoCommon/Fifo.h"
#include "VideoCommon/GeometryShaderManager.h"
#include "VideoCommon/ImageWrite.h"
#include "VideoCommon/IndexGenerator.h"
#include "VideoCommon/LookUpTables.h"
@ -202,6 +203,7 @@ void VideoBackend::Video_Prepare()
IndexGenerator::Init();
VertexShaderManager::Init();
PixelShaderManager::Init();
GeometryShaderManager::Init();
ProgramShaderCache::Init();
g_texture_cache = new TextureCache();
g_sampler_cache = new SamplerCache();
@ -243,6 +245,7 @@ void VideoBackend::Video_Cleanup()
ProgramShaderCache::Shutdown();
VertexShaderManager::Shutdown();
PixelShaderManager::Shutdown();
GeometryShaderManager::Shutdown();
delete g_perf_query;
g_perf_query = nullptr;
delete g_vertex_manager;