Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reinterpret framebuffer formats as needed. Outrun reflections partial fix #13636

Merged
merged 9 commits into from
Nov 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,8 @@ set(GPU_SOURCES
GPU/Common/DrawEngineCommon.h
GPU/Common/PresentationCommon.cpp
GPU/Common/PresentationCommon.h
GPU/Common/ReinterpretFramebuffer.cpp
GPU/Common/ReinterpretFramebuffer.h
GPU/Common/ShaderId.cpp
GPU/Common/ShaderId.h
GPU/Common/ShaderUniforms.cpp
Expand Down
1 change: 1 addition & 0 deletions Common/Common.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@
<ClInclude Include="Data\Collections\ConstMap.h" />
<ClInclude Include="Data\Collections\FixedSizeQueue.h" />
<ClInclude Include="Data\Collections\Hashmaps.h" />
<ClInclude Include="Data\Collections\Slice.h" />
<ClInclude Include="Data\Collections\ThreadSafeList.h" />
<ClInclude Include="Data\Collections\TinySet.h" />
<ClInclude Include="Data\Color\RGBAUtil.h" />
Expand Down
5 changes: 4 additions & 1 deletion Common/Common.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,9 @@
<ClInclude Include="GPU\ShaderWriter.h">
<Filter>GPU</Filter>
</ClInclude>
<ClInclude Include="Data\Collections\Slice.h">
<Filter>Data\Collections</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ABI.cpp" />
Expand Down Expand Up @@ -850,4 +853,4 @@
<Filter>Math\fast</Filter>
</None>
</ItemGroup>
</Project>
</Project>
48 changes: 48 additions & 0 deletions Common/Data/Collections/Slice.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#pragma once

#include <vector>

// Like a const begin/end pair, just more convenient to use (and can only be used for linear array data).
// Inspired by Rust's slices and Google's StringPiece.
template <class T>
struct Slice {
// View some memory as a slice.
Slice(const T *data, size_t size) : data_(data), size_(size) {}

// Intentionally non-explicit.
// View a const array as a slice.
template<size_t N>
Slice(const T(&data)[N]) : data_(data), size_(N) {}

// Intentionally non-explicit.
// View a const array as a slice.
Slice(const std::vector<T> &data) : data_(data.data()), size_(data.size()) {}

const T &operator[](size_t index) const {
return data_[index];
}

size_t size() const {
return size_;
}

// "Iterators"
const T *begin() const {
return data_;
}
const T *end() const {
return data_ + size_;
}

static Slice empty() {
return Slice<T>(nullptr, 0);
}

bool is_empty() const {
return size_ == 0;
}

private:
const T *data_;
size_t size_;
};
33 changes: 24 additions & 9 deletions Common/GPU/D3D11/thin3d_d3d11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,8 @@ InputLayout *D3D11DrawContext::CreateInputLayout(const InputLayoutDesc &desc) {
return inputLayout;
}

class D3D11ShaderModule;

class D3D11Pipeline : public Pipeline {
public:
~D3D11Pipeline() {
Expand All @@ -680,7 +682,7 @@ class D3D11Pipeline : public Pipeline {
if (dynamicUniforms)
dynamicUniforms->Release();
}
bool RequiresBuffer() {
bool RequiresBuffer() override {
return true;
}

Expand All @@ -694,6 +696,8 @@ class D3D11Pipeline : public Pipeline {
ID3D11GeometryShader *gs = nullptr;
D3D11_PRIMITIVE_TOPOLOGY topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;

std::vector<D3D11ShaderModule *> shaderModules;

size_t dynamicUniformsSize = 0;
ID3D11Buffer *dynamicUniforms = nullptr;
};
Expand Down Expand Up @@ -966,7 +970,9 @@ Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
dPipeline->raster = (D3D11RasterState *)desc.raster;
dPipeline->blend->AddRef();
dPipeline->depth->AddRef();
dPipeline->input->AddRef();
if (dPipeline->input) {
dPipeline->input->AddRef();
}
dPipeline->raster->AddRef();
dPipeline->topology = primToD3D11[(int)desc.prim];
if (desc.uniformDesc) {
Expand All @@ -983,6 +989,8 @@ Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
std::vector<D3D11ShaderModule *> shaders;
D3D11ShaderModule *vshader = nullptr;
for (auto iter : desc.shaders) {
iter->AddRef();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, seems like we'd need a Release() for this in the destructor of the pipeline?

-[Unknown]

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is right! Thanks for the catch!


D3D11ShaderModule *module = (D3D11ShaderModule *)iter;
shaders.push_back(module);
switch (module->GetStage()) {
Expand All @@ -998,6 +1006,7 @@ Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
break;
}
}
dPipeline->shaderModules = shaders;

if (!vshader) {
// No vertex shader - no graphics
Expand All @@ -1006,11 +1015,15 @@ Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
}

// Can finally create the input layout
auto &inputDesc = dPipeline->input->desc;
const std::vector<D3D11_INPUT_ELEMENT_DESC> &elements = dPipeline->input->elements;
HRESULT hr = device_->CreateInputLayout(elements.data(), (UINT)elements.size(), vshader->byteCode_.data(), vshader->byteCode_.size(), &dPipeline->il);
if (!SUCCEEDED(hr)) {
Crash();
if (dPipeline->input) {
auto &inputDesc = dPipeline->input->desc;
const std::vector<D3D11_INPUT_ELEMENT_DESC> &elements = dPipeline->input->elements;
HRESULT hr = device_->CreateInputLayout(elements.data(), (UINT)elements.size(), vshader->byteCode_.data(), vshader->byteCode_.size(), &dPipeline->il);
if (!SUCCEEDED(hr)) {
Crash();
}
} else {
dPipeline->il = nullptr;
}
return dPipeline;
}
Expand Down Expand Up @@ -1081,8 +1094,10 @@ void D3D11DrawContext::ApplyCurrentState() {
curTopology_ = curPipeline_->topology;
}

int numVBs = (int)curPipeline_->input->strides.size();
context_->IASetVertexBuffers(0, 1, nextVertexBuffers_, (UINT *)curPipeline_->input->strides.data(), (UINT *)nextVertexBufferOffsets_);
if (curPipeline_->input) {
int numVBs = (int)curPipeline_->input->strides.size();
context_->IASetVertexBuffers(0, numVBs, nextVertexBuffers_, (UINT *)curPipeline_->input->strides.data(), (UINT *)nextVertexBufferOffsets_);
}
if (dirtyIndexBuffer_) {
context_->IASetIndexBuffer(nextIndexBuffer_, DXGI_FORMAT_R16_UINT, nextIndexBufferOffset_);
dirtyIndexBuffer_ = false;
Expand Down
29 changes: 21 additions & 8 deletions Common/GPU/OpenGL/thin3d_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ class OpenGLPipeline : public Pipeline {
bool LinkShaders();

bool RequiresBuffer() override {
return inputLayout->RequiresBuffer();
return inputLayout && inputLayout->RequiresBuffer();
}

GLuint prim = 0;
Expand Down Expand Up @@ -1051,7 +1051,7 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
ERROR_LOG(G3D, "Invalid primitive type");
return nullptr;
}
if (!desc.depthStencil || !desc.blend || !desc.raster || !desc.inputLayout) {
if (!desc.depthStencil || !desc.blend || !desc.raster) {
ERROR_LOG(G3D, "Incomplete prim desciption");
return nullptr;
}
Expand Down Expand Up @@ -1081,7 +1081,9 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
pipeline->depthStencil->AddRef();
pipeline->blend->AddRef();
pipeline->raster->AddRef();
pipeline->inputLayout->AddRef();
if (pipeline->inputLayout) {
pipeline->inputLayout->AddRef();
}
return pipeline;
} else {
ERROR_LOG(G3D, "Failed to create pipeline - shaders failed to link");
Expand Down Expand Up @@ -1219,20 +1221,25 @@ void OpenGLContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) {
void OpenGLContext::Draw(int vertexCount, int offset) {
_dbg_assert_msg_(curVBuffers_[0], "Can't call Draw without a vertex buffer");
ApplySamplers();
renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0]);
if (curPipeline_->inputLayout) {
renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0]);
}
renderManager_.Draw(curPipeline_->prim, offset, vertexCount);
}

void OpenGLContext::DrawIndexed(int vertexCount, int offset) {
_dbg_assert_msg_(curVBuffers_[0], "Can't call DrawIndexed without a vertex buffer");
_dbg_assert_msg_(curIBuffer_, "Can't call DrawIndexed without an index buffer");
ApplySamplers();
renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0]);
if (curPipeline_->inputLayout) {
renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0]);
}
renderManager_.BindIndexBuffer(curIBuffer_->buffer_);
renderManager_.DrawIndexed(curPipeline_->prim, vertexCount, GL_UNSIGNED_SHORT, (void *)((intptr_t)curIBufferOffset_ + offset * sizeof(uint32_t)));
}

void OpenGLContext::DrawUP(const void *vdata, int vertexCount) {
_assert_(curPipeline_->inputLayout);
int stride = curPipeline_->inputLayout->stride;
size_t dataSize = stride * vertexCount;

Expand All @@ -1242,7 +1249,9 @@ void OpenGLContext::DrawUP(const void *vdata, int vertexCount) {
size_t offset = frameData.push->Push(vdata, dataSize, &buf);

ApplySamplers();
renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, buf, offset);
if (curPipeline_->inputLayout) {
renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, buf, offset);
}
renderManager_.Draw(curPipeline_->prim, 0, vertexCount);
}

Expand Down Expand Up @@ -1273,7 +1282,7 @@ OpenGLInputLayout::~OpenGLInputLayout() {
void OpenGLInputLayout::Compile(const InputLayoutDesc &desc) {
// TODO: This is only accurate if there's only one stream. But whatever, for now we
// never use multiple streams anyway.
stride = (GLsizei)desc.bindings[0].stride;
stride = desc.bindings.empty() ? 0 : (GLsizei)desc.bindings[0].stride;

std::vector<GLRInputLayout::Entry> entries;
for (auto &attr : desc.attributes) {
Expand Down Expand Up @@ -1310,7 +1319,11 @@ void OpenGLInputLayout::Compile(const InputLayoutDesc &desc) {

entries.push_back(entry);
}
inputLayout_ = render_->CreateInputLayout(entries);
if (!entries.empty()) {
inputLayout_ = render_->CreateInputLayout(entries);
} else {
inputLayout_ = nullptr;
}
}

Framebuffer *OpenGLContext::CreateFramebuffer(const FramebufferDesc &desc) {
Expand Down
10 changes: 5 additions & 5 deletions Common/GPU/Shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,12 @@ void ShaderLanguageDesc::Init(ShaderLanguage lang) {
fragColor0 = "fragColor0";
fragColor1 = "fragColor1";
texture = "texture";
texelFetch = nullptr;
bitwiseOps = false;
texelFetch = "texelFetch";
bitwiseOps = true;
lastFragData = nullptr;
gles = false;
gles = true;
forceMatrix4x4 = true;
glslES30 = true;
bitwiseOps = true;
texelFetch = "texelFetch";
break;
case GLSL_VULKAN:
Expand Down Expand Up @@ -67,14 +66,15 @@ void ShaderLanguageDesc::Init(ShaderLanguage lang) {
bitwiseOps = lang == HLSL_D3D11;
framebufferFetchExtension = nullptr;
gles = false;
glslES30 = true;
glslES30 = true; // Hm, D3D9 too?
glslVersionNumber = 0;
lastFragData = nullptr;
texture = "texture";
texelFetch = "texelFetch";
forceMatrix4x4 = false;
coefsFromBuffers = true;
vsOutPrefix = "Out.";
viewportYSign = "-";
break;
}
}
Expand Down
31 changes: 30 additions & 1 deletion Common/GPU/Shader.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#pragma once

#include <vector>
#include <cstdint>
#include <cstddef> // for size_t

// GLSL_1xx and GLSL_3xx each cover a lot of sub variants. All the little quirks
// that differ are covered in ShaderLanguageDesc.
// Defined as a bitmask so stuff like GetSupportedShaderLanguages can return combinations.
Expand Down Expand Up @@ -41,12 +45,37 @@ struct ShaderLanguageDesc {
const char *lastFragData = nullptr;
const char *framebufferFetchExtension = nullptr;
const char *vsOutPrefix = "";
bool glslES30 = false;
const char *viewportYSign = "";
bool glslES30 = false; // really glslES30Features. TODO: Clean this up.
bool bitwiseOps = false;
bool forceMatrix4x4 = false;
bool coefsFromBuffers = false;
};

enum class UniformType : int8_t {
FLOAT1,
FLOAT2,
FLOAT3,
FLOAT4,
MATRIX4X4,
};

// Describe uniforms intricately enough that we can support them on all backends.
// This will generate a uniform struct on the newer backends and individual uniforms on the older ones.
struct UniformDesc {
const char *name; // For GL
int16_t vertexReg; // For D3D
int16_t fragmentReg; // For D3D
UniformType type;
int16_t offset;
// TODO: Support array elements etc.
};

struct UniformBufferDesc {
size_t uniformBufferSize;
std::vector<UniformDesc> uniforms;
};

// For passing error messages from shader compilation (and other critical issues) back to the host.
// This can run on any thread - be aware!
// TODO: See if we can find a less generic name for this.
Expand Down
Loading