Permalink
Browse files

Use main buffers for utility draws

  • Loading branch information...
stenzek committed Nov 27, 2018
1 parent 5ca18ff commit 7afd5cc2fb7e45f2c497e5aed007a017b8461335
Showing with 533 additions and 681 deletions.
  1. +0 −33 Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp
  2. +2 −1 Source/Core/VideoBackends/D3D/GeometryShaderCache.h
  3. +0 −34 Source/Core/VideoBackends/D3D/PixelShaderCache.cpp
  4. +0 −2 Source/Core/VideoBackends/D3D/PixelShaderCache.h
  5. +12 −79 Source/Core/VideoBackends/D3D/Render.cpp
  6. +2 −11 Source/Core/VideoBackends/D3D/Render.h
  7. +106 −59 Source/Core/VideoBackends/D3D/VertexManager.cpp
  8. +18 −18 Source/Core/VideoBackends/D3D/VertexManager.h
  9. +0 −31 Source/Core/VideoBackends/D3D/VertexShaderCache.cpp
  10. +0 −2 Source/Core/VideoBackends/D3D/VertexShaderCache.h
  11. +16 −3 Source/Core/VideoBackends/Null/VertexManager.cpp
  12. +7 −2 Source/Core/VideoBackends/Null/VertexManager.h
  13. +20 −0 Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp
  14. +2 −0 Source/Core/VideoBackends/OGL/ProgramShaderCache.h
  15. +21 −48 Source/Core/VideoBackends/OGL/Render.cpp
  16. +4 −7 Source/Core/VideoBackends/OGL/Render.h
  17. +2 −0 Source/Core/VideoBackends/OGL/StreamBuffer.h
  18. +39 −84 Source/Core/VideoBackends/OGL/VertexManager.cpp
  19. +11 −12 Source/Core/VideoBackends/OGL/VertexManager.h
  20. +17 −2 Source/Core/VideoBackends/Software/SWVertexLoader.cpp
  21. +8 −3 Source/Core/VideoBackends/Software/SWVertexLoader.h
  22. +17 −152 Source/Core/VideoBackends/Vulkan/Renderer.cpp
  23. +2 −5 Source/Core/VideoBackends/Vulkan/Renderer.h
  24. +89 −6 Source/Core/VideoBackends/Vulkan/StateTracker.cpp
  25. +8 −5 Source/Core/VideoBackends/Vulkan/StateTracker.h
  26. +39 −48 Source/Core/VideoBackends/Vulkan/VertexManager.cpp
  27. +7 −8 Source/Core/VideoBackends/Vulkan/VertexManager.h
  28. +8 −0 Source/Core/VideoCommon/IndexGenerator.cpp
  29. +2 −0 Source/Core/VideoCommon/IndexGenerator.h
  30. +4 −10 Source/Core/VideoCommon/RenderBase.h
  31. +48 −10 Source/Core/VideoCommon/VertexManagerBase.cpp
  32. +22 −6 Source/Core/VideoCommon/VertexManagerBase.h
@@ -4,7 +4,6 @@

#include <string>

#include "Common/Align.h"
#include "Common/FileUtil.h"
#include "Common/StringUtil.h"

@@ -18,8 +17,6 @@

#include "VideoCommon/Debugger.h"
#include "VideoCommon/GeometryShaderGen.h"
#include "VideoCommon/GeometryShaderManager.h"
#include "VideoCommon/Statistics.h"
#include "VideoCommon/VideoConfig.h"

namespace DX11
@@ -36,25 +33,6 @@ ID3D11GeometryShader* GeometryShaderCache::GetCopyGeometryShader()
return (g_ActiveConfig.stereo_mode != StereoMode::Off) ? CopyGeometryShader : nullptr;
}

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;
}

const char clear_shader_code[] = {
"struct VSOUTPUT\n"
"{\n"
@@ -116,15 +94,6 @@ const char copy_shader_code[] = {

void GeometryShaderCache::Init()
{
unsigned int gbsize = Common::AlignUp(static_cast<unsigned int>(sizeof(GeometryShaderConstants)),
16); // 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(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");
@@ -138,8 +107,6 @@ void GeometryShaderCache::Init()

void GeometryShaderCache::Shutdown()
{
SAFE_RELEASE(gscbuf);

SAFE_RELEASE(ClearGeometryShader);
SAFE_RELEASE(CopyGeometryShader);
}
@@ -20,7 +20,8 @@ class GeometryShaderCache
static ID3D11GeometryShader* GetClearGeometryShader();
static ID3D11GeometryShader* GetCopyGeometryShader();

static ID3D11Buffer*& GetConstantBuffer();
static ID3D11Buffer* GetConstantBuffer();
static void UpdateConstantBuffer(const void* data, u32 data_size);
};

} // namespace DX11
@@ -4,7 +4,6 @@

#include <string>

#include "Common/Align.h"
#include "Common/CommonTypes.h"
#include "Common/FileUtil.h"
#include "Common/MsgHandler.h"
@@ -20,8 +19,6 @@

#include "VideoCommon/Debugger.h"
#include "VideoCommon/PixelShaderGen.h"
#include "VideoCommon/PixelShaderManager.h"
#include "VideoCommon/Statistics.h"
#include "VideoCommon/VideoConfig.h"

namespace DX11
@@ -32,7 +29,6 @@ ID3D11PixelShader* s_AnaglyphProgram = nullptr;
ID3D11PixelShader* s_DepthResolveProgram = nullptr;
ID3D11PixelShader* s_rgba6_to_rgb8[2] = {nullptr};
ID3D11PixelShader* s_rgb8_to_rgba6[2] = {nullptr};
ID3D11Buffer* pscbuf = nullptr;

const char clear_program_code[] = {"void main(\n"
"out float4 ocol0 : SV_Target,\n"
@@ -277,36 +273,8 @@ ID3D11PixelShader* PixelShaderCache::GetDepthResolveProgram()
return s_DepthResolveProgram;
}

static void UpdateConstantBuffers()
{
if (PixelShaderManager::dirty)
{
D3D11_MAPPED_SUBRESOURCE map;
D3D::context->Map(pscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
memcpy(map.pData, &PixelShaderManager::constants, sizeof(PixelShaderConstants));
D3D::context->Unmap(pscbuf, 0);
PixelShaderManager::dirty = false;

ADDSTAT(stats.thisFrame.bytesUniformStreamed, sizeof(PixelShaderConstants));
}
}

ID3D11Buffer* PixelShaderCache::GetConstantBuffer()
{
UpdateConstantBuffers();
return pscbuf;
}

void PixelShaderCache::Init()
{
unsigned int cbsize = Common::AlignUp(static_cast<unsigned int>(sizeof(PixelShaderConstants)),
16); // must be a multiple of 16
D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER,
D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
D3D::device->CreateBuffer(&cbdesc, nullptr, &pscbuf);
CHECK(pscbuf != nullptr, "Create pixel shader constant buffer");
D3D::SetDebugObjectName(pscbuf, "pixel shader constant buffer used to emulate the GX pipeline");

// used when drawing clear quads
s_ClearProgram = D3D::CompileAndCreatePixelShader(clear_program_code);
CHECK(s_ClearProgram != nullptr, "Create clear pixel shader");
@@ -334,8 +302,6 @@ void PixelShaderCache::InvalidateMSAAShaders()

void PixelShaderCache::Shutdown()
{
SAFE_RELEASE(pscbuf);

SAFE_RELEASE(s_ClearProgram);
SAFE_RELEASE(s_AnaglyphProgram);
SAFE_RELEASE(s_DepthResolveProgram);
@@ -21,8 +21,6 @@ class PixelShaderCache
static void Init();
static void Shutdown();

static ID3D11Buffer* GetConstantBuffer();

static ID3D11PixelShader* GetColorCopyProgram(bool multisampled);
static ID3D11PixelShader* GetClearProgram();
static ID3D11PixelShader* GetAnaglyphProgram();
@@ -167,16 +167,6 @@ void Renderer::SetupDeviceObjects()
D3D::SetDebugObjectName(m_reset_rast_state, "rasterizer state for Renderer::ResetAPIState");

m_screenshot_texture = nullptr;

CD3D11_BUFFER_DESC vbo_desc(UTILITY_VBO_SIZE, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC,
D3D11_CPU_ACCESS_WRITE);
hr = D3D::device->CreateBuffer(&vbo_desc, nullptr, &m_utility_vertex_buffer);
CHECK(SUCCEEDED(hr), "Create utility VBO");

CD3D11_BUFFER_DESC ubo_desc(UTILITY_UBO_SIZE, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC,
D3D11_CPU_ACCESS_WRITE);
hr = D3D::device->CreateBuffer(&ubo_desc, nullptr, &m_utility_uniform_buffer);
CHECK(SUCCEEDED(hr), "Create utility UBO");
}

// Kill off all device objects
@@ -196,8 +186,6 @@ void Renderer::TeardownDeviceObjects()
SAFE_RELEASE(m_reset_rast_state);
SAFE_RELEASE(m_screenshot_texture);
SAFE_RELEASE(m_3d_vision_texture);
SAFE_RELEASE(m_utility_vertex_buffer);
SAFE_RELEASE(m_utility_uniform_buffer);
}

void Renderer::Create3DVisionTexture(int width, int height)
@@ -273,25 +261,6 @@ std::unique_ptr<AbstractPipeline> Renderer::CreatePipeline(const AbstractPipelin
return DXPipeline::Create(config);
}

void Renderer::UpdateUtilityUniformBuffer(const void* uniforms, u32 uniforms_size)
{
DEBUG_ASSERT(uniforms_size > 0 && uniforms_size < UTILITY_UBO_SIZE);
D3D11_MAPPED_SUBRESOURCE mapped;
HRESULT hr = D3D::context->Map(m_utility_uniform_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
CHECK(SUCCEEDED(hr), "Map utility UBO");
std::memcpy(mapped.pData, uniforms, uniforms_size);
D3D::context->Unmap(m_utility_uniform_buffer, 0);
}

void Renderer::UpdateUtilityVertexBuffer(const void* vertices, u32 vertex_stride, u32 num_vertices)
{
D3D11_MAPPED_SUBRESOURCE mapped;
HRESULT hr = D3D::context->Map(m_utility_vertex_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
CHECK(SUCCEEDED(hr), "Map utility VBO");
std::memcpy(mapped.pData, vertices, num_vertices * vertex_stride);
D3D::context->Unmap(m_utility_vertex_buffer, 0);
}

void Renderer::SetPipeline(const AbstractPipeline* pipeline)
{
const DXPipeline* dx_pipeline = static_cast<const DXPipeline*>(pipeline);
@@ -308,54 +277,6 @@ void Renderer::SetPipeline(const AbstractPipeline* pipeline)
D3D::stateman->SetPixelShader(dx_pipeline->GetPixelShader());
}

void Renderer::DrawUtilityPipeline(const void* uniforms, u32 uniforms_size, const void* vertices,
u32 vertex_stride, u32 num_vertices)
{
// Copy in uniforms.
if (uniforms_size > 0)
{
UpdateUtilityUniformBuffer(uniforms, uniforms_size);
D3D::stateman->SetVertexConstants(m_utility_uniform_buffer);
D3D::stateman->SetPixelConstants(m_utility_uniform_buffer);
D3D::stateman->SetGeometryConstants(m_utility_uniform_buffer);
}

// If the vertices are larger than our buffer, we need to break it up into multiple draws.
const char* vertices_ptr = static_cast<const char*>(vertices);
while (num_vertices > 0)
{
u32 vertices_this_draw = num_vertices;
if (vertices_ptr)
{
vertices_this_draw = std::min(vertices_this_draw, UTILITY_VBO_SIZE / vertex_stride);
DEBUG_ASSERT(vertices_this_draw > 0);
UpdateUtilityVertexBuffer(vertices_ptr, vertex_stride, vertices_this_draw);
D3D::stateman->SetVertexBuffer(m_utility_vertex_buffer, vertex_stride, 0);
}

// Apply pending state and draw.
D3D::stateman->Apply();
D3D::context->Draw(vertices_this_draw, 0);
vertices_ptr += vertex_stride * vertices_this_draw;
num_vertices -= vertices_this_draw;
}
}

void Renderer::DispatchComputeShader(const AbstractShader* shader, const void* uniforms,
u32 uniforms_size, u32 groups_x, u32 groups_y, u32 groups_z)
{
D3D::stateman->SetComputeShader(static_cast<const DXShader*>(shader)->GetD3DComputeShader());

if (uniforms_size > 0)
{
UpdateUtilityUniformBuffer(uniforms, uniforms_size);
D3D::stateman->SetComputeConstants(m_utility_uniform_buffer);
}

D3D::stateman->Apply();
D3D::context->Dispatch(groups_x, groups_y, groups_z);
}

TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
{
TargetRectangle result;
@@ -560,6 +481,18 @@ void Renderer::SetViewport(float x, float y, float width, float height, float ne
D3D::context->RSSetViewports(1, &vp);
}

void Renderer::Draw(u32 base_vertex, u32 num_vertices)
{
D3D::stateman->Apply();
D3D::context->Draw(num_vertices, base_vertex);
}

void Renderer::DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex)
{
D3D::stateman->Apply();
D3D::context->DrawIndexed(num_indices, base_index, base_vertex);
}

void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable,
u32 color, u32 z)
{
@@ -50,6 +50,8 @@ class Renderer : public ::Renderer
void SetInterlacingMode() override;
void SetViewport(float x, float y, float width, float height, float near_depth,
float far_depth) override;
void Draw(u32 base_vertex, u32 num_vertices) override;
void DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex) override;
void SetFullscreen(bool enable_fullscreen) override;
bool IsFullscreen() const override;

@@ -73,11 +75,6 @@ class Renderer : public ::Renderer

void ReinterpretPixelData(unsigned int convtype) override;

void DrawUtilityPipeline(const void* uniforms, u32 uniforms_size, const void* vertices,
u32 vertex_stride, u32 num_vertices) override;
void DispatchComputeShader(const AbstractShader* shader, const void* uniforms, u32 uniforms_size,
u32 groups_x, u32 groups_y, u32 groups_z) override;

private:
void SetupDeviceObjects();
void TeardownDeviceObjects();
@@ -89,9 +86,6 @@ class Renderer : public ::Renderer
void BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D* src_texture,
u32 src_width, u32 src_height);

void UpdateUtilityUniformBuffer(const void* uniforms, u32 uniforms_size);
void UpdateUtilityVertexBuffer(const void* vertices, u32 vertex_stride, u32 num_vertices);

StateCache m_state_cache;

std::array<ID3D11BlendState*, 4> m_clear_blend_states{};
@@ -103,9 +97,6 @@ class Renderer : public ::Renderer
ID3D11Texture2D* m_screenshot_texture = nullptr;
D3DTexture2D* m_3d_vision_texture = nullptr;

ID3D11Buffer* m_utility_vertex_buffer = nullptr;
ID3D11Buffer* m_utility_uniform_buffer = nullptr;

u32 m_last_multisamples = 1;
bool m_last_stereo_mode = false;
bool m_last_fullscreen_state = false;
Oops, something went wrong.

0 comments on commit 7afd5cc

Please sign in to comment.