diff --git a/Common/GPU/D3D11/thin3d_d3d11.cpp b/Common/GPU/D3D11/thin3d_d3d11.cpp index 4f8a4f53731a..1559a3cbe8e5 100644 --- a/Common/GPU/D3D11/thin3d_d3d11.cpp +++ b/Common/GPU/D3D11/thin3d_d3d11.cpp @@ -106,7 +106,7 @@ class D3D11DrawContext : public DrawContext { void BindTextures(int start, int count, Texture **textures, TextureBindFlags flags) override; void BindNativeTexture(int index, void *nativeTexture) override; void BindSamplerStates(int start, int count, SamplerState **states) override; - void BindVertexBuffers(int start, int count, Buffer **buffers, const int *offsets) override; + void BindVertexBuffer(Buffer *buffers, int offset) override; void BindIndexBuffer(Buffer *indexBuffer, int offset) override; void BindPipeline(Pipeline *pipeline) override; @@ -214,12 +214,12 @@ class D3D11DrawContext : public DrawContext { ID3D11GeometryShader *curGS_ = nullptr; D3D11_PRIMITIVE_TOPOLOGY curTopology_ = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; - ID3D11Buffer *nextVertexBuffers_[4]{}; - int nextVertexBufferOffsets_[4]{}; + ID3D11Buffer *nextVertexBuffer_ = nullptr; + UINT nextVertexBufferOffset_ = 0; bool dirtyIndexBuffer_ = false; ID3D11Buffer *nextIndexBuffer_ = nullptr; - int nextIndexBufferOffset_ = 0; + UINT nextIndexBufferOffset_ = 0; InvalidationCallback invalidationCallback_; int frameCount_ = FRAME_TIME_HISTORY_LENGTH; @@ -725,7 +725,7 @@ class D3D11InputLayout : public InputLayout { D3D11InputLayout() {} InputLayoutDesc desc; std::vector elements; - std::vector strides; + UINT stride; // type to match function parameter }; const char *semanticToD3D11(int semantic, UINT *index) { @@ -752,15 +752,13 @@ InputLayout *D3D11DrawContext::CreateInputLayout(const InputLayoutDesc &desc) { D3D11_INPUT_ELEMENT_DESC el; el.AlignedByteOffset = desc.attributes[i].offset; el.Format = dataFormatToD3D11(desc.attributes[i].format); - el.InstanceDataStepRate = desc.bindings[desc.attributes[i].binding].instanceRate ? 1 : 0; - el.InputSlot = desc.attributes[i].binding; + el.InstanceDataStepRate = 0; + el.InputSlot = 0; el.SemanticName = semanticToD3D11(desc.attributes[i].location, &el.SemanticIndex); - el.InputSlotClass = desc.bindings[desc.attributes[i].binding].instanceRate ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; + el.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; inputLayout->elements.push_back(el); } - for (size_t i = 0; i < desc.bindings.size(); i++) { - inputLayout->strides.push_back(desc.bindings[i].stride); - } + inputLayout->stride = desc.stride; return inputLayout; } @@ -1253,8 +1251,7 @@ void D3D11DrawContext::ApplyCurrentState() { } if (curPipeline_->input != nullptr) { - int numVBs = (int)curPipeline_->input->strides.size(); - context_->IASetVertexBuffers(0, numVBs, nextVertexBuffers_, (UINT *)curPipeline_->input->strides.data(), (UINT *)nextVertexBufferOffsets_); + context_->IASetVertexBuffers(0, 1, &nextVertexBuffer_, &curPipeline_->input->stride, &nextVertexBufferOffset_); } if (dirtyIndexBuffer_) { context_->IASetIndexBuffer(nextIndexBuffer_, DXGI_FORMAT_R16_UINT, nextIndexBufferOffset_); @@ -1323,14 +1320,11 @@ void D3D11DrawContext::UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t context_->UpdateSubresource(buf->buf, 0, &box, data, 0, 0); } -void D3D11DrawContext::BindVertexBuffers(int start, int count, Buffer **buffers, const int *offsets) { - _assert_(start + count <= ARRAY_SIZE(nextVertexBuffers_)); +void D3D11DrawContext::BindVertexBuffer(Buffer *buffer, int offset) { // Lazy application - for (int i = 0; i < count; i++) { - D3D11Buffer *buf = (D3D11Buffer *)buffers[i]; - nextVertexBuffers_[start + i] = buf->buf; - nextVertexBufferOffsets_[start + i] = offsets ? offsets[i] : 0; - } + D3D11Buffer *buf = (D3D11Buffer *)buffer; + nextVertexBuffer_ = buf->buf; + nextVertexBufferOffset_ = offset; } void D3D11DrawContext::BindIndexBuffer(Buffer *indexBuffer, int offset) { @@ -1354,10 +1348,10 @@ void D3D11DrawContext::DrawIndexed(int indexCount, int offset) { void D3D11DrawContext::DrawUP(const void *vdata, int vertexCount) { ApplyCurrentState(); - int byteSize = vertexCount * curPipeline_->input->strides[0]; + int byteSize = vertexCount * curPipeline_->input->stride; UpdateBuffer(upBuffer_, (const uint8_t *)vdata, 0, byteSize, Draw::UPDATE_DISCARD); - BindVertexBuffers(0, 1, &upBuffer_, nullptr); + BindVertexBuffer(upBuffer_, 0); int offset = 0; Draw(vertexCount, offset); } @@ -1565,7 +1559,7 @@ void D3D11DrawContext::BeginFrame(DebugFlags debugFlags) { context_->IASetPrimitiveTopology(curTopology_); } if (curPipeline_ != nullptr) { - context_->IASetVertexBuffers(0, 1, nextVertexBuffers_, (UINT *)curPipeline_->input->strides.data(), (UINT *)nextVertexBufferOffsets_); + context_->IASetVertexBuffers(0, 1, &nextVertexBuffer_, &curPipeline_->input->stride, &nextVertexBufferOffset_); context_->IASetIndexBuffer(nextIndexBuffer_, DXGI_FORMAT_R16_UINT, nextIndexBufferOffset_); if (curPipeline_->dynamicUniforms) { context_->VSSetConstantBuffers(0, 1, &curPipeline_->dynamicUniforms); diff --git a/Common/GPU/D3D9/thin3d_d3d9.cpp b/Common/GPU/D3D9/thin3d_d3d9.cpp index 2c6acc243fd2..dadf67eaadff 100644 --- a/Common/GPU/D3D9/thin3d_d3d9.cpp +++ b/Common/GPU/D3D9/thin3d_d3d9.cpp @@ -231,14 +231,14 @@ class D3D9InputLayout : public InputLayout { decl_->Release(); } } - int GetStride(int binding) const { return stride_[binding]; } + int GetStride() const { return stride_; } void Apply(LPDIRECT3DDEVICE9 device) { device->SetVertexDeclaration(decl_); } private: LPDIRECT3DVERTEXDECLARATION9 decl_; - int stride_[4]; + int stride_; }; class D3D9ShaderModule : public ShaderModule { @@ -560,12 +560,9 @@ class D3D9Context : public DrawContext { s->Apply(device_, start + i); } } - void BindVertexBuffers(int start, int count, Buffer **buffers, const int *offsets) override { - _assert_(start + count <= ARRAY_SIZE(curVBuffers_)); - for (int i = 0; i < count; i++) { - curVBuffers_[i + start] = (D3D9Buffer *)buffers[i]; - curVBufferOffsets_[i + start] = offsets ? offsets[i] : 0; - } + void BindVertexBuffer(Buffer *vertexBuffer, int offset) override { + curVBuffer_ = (D3D9Buffer *)vertexBuffer; + curVBufferOffset_ = offset; } void BindIndexBuffer(Buffer *indexBuffer, int offset) override { curIBuffer_ = (D3D9Buffer *)indexBuffer; @@ -645,8 +642,8 @@ class D3D9Context : public DrawContext { // Bound state AutoRef curPipeline_; - AutoRef curVBuffers_[4]; - int curVBufferOffsets_[4]{}; + AutoRef curVBuffer_; + int curVBufferOffset_ = 0; AutoRef curIBuffer_; int curIBufferOffset_ = 0; AutoRef curRenderTarget_; @@ -1028,7 +1025,7 @@ D3D9InputLayout::D3D9InputLayout(LPDIRECT3DDEVICE9 device, const InputLayoutDesc D3DVERTEXELEMENT9 *elements = new D3DVERTEXELEMENT9[desc.attributes.size() + 1]; size_t i; for (i = 0; i < desc.attributes.size(); i++) { - elements[i].Stream = desc.attributes[i].binding; + elements[i].Stream = 0; elements[i].Offset = desc.attributes[i].offset; elements[i].Method = D3DDECLMETHOD_DEFAULT; SemanticToD3D9UsageAndIndex(desc.attributes[i].location, &elements[i].Usage, &elements[i].UsageIndex); @@ -1038,9 +1035,7 @@ D3D9InputLayout::D3D9InputLayout(LPDIRECT3DDEVICE9 device, const InputLayoutDesc // Zero the last one. memcpy(&elements[i], &end, sizeof(elements[i])); - for (i = 0; i < desc.bindings.size(); i++) { - stride_[i] = desc.bindings[i].stride; - } + stride_ = desc.stride; HRESULT hr = device->CreateVertexDeclaration(elements, &decl_); if (FAILED(hr)) { @@ -1174,7 +1169,7 @@ inline int D3DPrimCount(D3DPRIMITIVETYPE prim, int size) { } void D3D9Context::Draw(int vertexCount, int offset) { - device_->SetStreamSource(0, curVBuffers_[0]->vbuffer_, curVBufferOffsets_[0], curPipeline_->inputLayout->GetStride(0)); + device_->SetStreamSource(0, curVBuffer_->vbuffer_, curVBufferOffset_, curPipeline_->inputLayout->GetStride()); curPipeline_->inputLayout->Apply(device_); curPipeline_->Apply(device_, stencilRef_, stencilWriteMask_, stencilCompareMask_); ApplyDynamicState(); @@ -1185,7 +1180,7 @@ void D3D9Context::DrawIndexed(int vertexCount, int offset) { curPipeline_->inputLayout->Apply(device_); curPipeline_->Apply(device_, stencilRef_, stencilWriteMask_, stencilCompareMask_); ApplyDynamicState(); - device_->SetStreamSource(0, curVBuffers_[0]->vbuffer_, curVBufferOffsets_[0], curPipeline_->inputLayout->GetStride(0)); + device_->SetStreamSource(0, curVBuffer_->vbuffer_, curVBufferOffset_, curPipeline_->inputLayout->GetStride()); device_->SetIndices(curIBuffer_->ibuffer_); device_->DrawIndexedPrimitive(curPipeline_->prim, 0, 0, vertexCount, offset, D3DPrimCount(curPipeline_->prim, vertexCount)); } @@ -1195,7 +1190,7 @@ void D3D9Context::DrawUP(const void *vdata, int vertexCount) { curPipeline_->Apply(device_, stencilRef_, stencilWriteMask_, stencilCompareMask_); ApplyDynamicState(); - device_->DrawPrimitiveUP(curPipeline_->prim, D3DPrimCount(curPipeline_->prim, vertexCount), vdata, curPipeline_->inputLayout->GetStride(0)); + device_->DrawPrimitiveUP(curPipeline_->prim, D3DPrimCount(curPipeline_->prim, vertexCount), vdata, curPipeline_->inputLayout->GetStride()); } static uint32_t SwapRB(uint32_t c) { diff --git a/Common/GPU/OpenGL/GLQueueRunner.cpp b/Common/GPU/OpenGL/GLQueueRunner.cpp index cce2d1a4e3ee..0419b0d88501 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.cpp +++ b/Common/GPU/OpenGL/GLQueueRunner.cpp @@ -1251,7 +1251,7 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last } for (size_t i = 0; i < layout->entries.size(); i++) { auto &entry = layout->entries[i]; - glVertexAttribPointer(entry.location, entry.count, entry.type, entry.normalized, entry.stride, (const void *)(c.draw.vertexOffset + entry.offset)); + glVertexAttribPointer(entry.location, entry.count, entry.type, entry.normalized, layout->stride, (const void *)(c.draw.vertexOffset + entry.offset)); } if (c.draw.indexBuffer) { GLuint buf = c.draw.indexBuffer->buffer_; diff --git a/Common/GPU/OpenGL/GLRenderManager.h b/Common/GPU/OpenGL/GLRenderManager.h index 8aed292758cf..fb31fdfe3dbb 100644 --- a/Common/GPU/OpenGL/GLRenderManager.h +++ b/Common/GPU/OpenGL/GLRenderManager.h @@ -190,10 +190,10 @@ class GLRInputLayout { int count; GLenum type; GLboolean normalized; - int stride; intptr_t offset; }; std::vector entries; + int stride; int semanticsMask_ = 0; }; @@ -331,11 +331,12 @@ class GLRenderManager { return step.create_program.program; } - GLRInputLayout *CreateInputLayout(const std::vector &entries) { + GLRInputLayout *CreateInputLayout(const std::vector &entries, int stride) { GLRInitStep &step = initSteps_.push_uninitialized(); step.stepType = GLRInitStepType::CREATE_INPUT_LAYOUT; step.create_input_layout.inputLayout = new GLRInputLayout(); step.create_input_layout.inputLayout->entries = entries; + step.create_input_layout.inputLayout->stride = stride; for (auto &iter : step.create_input_layout.inputLayout->entries) { step.create_input_layout.inputLayout->semanticsMask_ |= 1 << iter.location; } diff --git a/Common/GPU/OpenGL/thin3d_gl.cpp b/Common/GPU/OpenGL/thin3d_gl.cpp index 59cd3eba3c6a..47f63d02c995 100644 --- a/Common/GPU/OpenGL/thin3d_gl.cpp +++ b/Common/GPU/OpenGL/thin3d_gl.cpp @@ -421,12 +421,9 @@ class OpenGLContext : public DrawContext { void BindNativeTexture(int sampler, void *nativeTexture) override; void BindPipeline(Pipeline *pipeline) override; - void BindVertexBuffers(int start, int count, Buffer **buffers, const int *offsets) override { - _assert_(start + count <= ARRAY_SIZE(curVBuffers_)); - for (int i = 0; i < count; i++) { - curVBuffers_[i + start] = (OpenGLBuffer *)buffers[i]; - curVBufferOffsets_[i + start] = offsets ? offsets[i] : 0; - } + void BindVertexBuffer(Buffer *buffer, int offset) override { + curVBuffer_ = (OpenGLBuffer *)buffer; + curVBufferOffset_ = offset; } void BindIndexBuffer(Buffer *indexBuffer, int offset) override { curIBuffer_ = (OpenGLBuffer *)indexBuffer; @@ -505,9 +502,9 @@ class OpenGLContext : public DrawContext { const GLRTexture *boundTextures_[MAX_TEXTURE_SLOTS]{}; AutoRef curPipeline_; - AutoRef curVBuffers_[4]{}; - int curVBufferOffsets_[4]{}; + AutoRef curVBuffer_; AutoRef curIBuffer_; + int curVBufferOffset_ = 0; int curIBufferOffset_ = 0; AutoRef curRenderTarget_; @@ -1370,20 +1367,20 @@ void OpenGLContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) { } void OpenGLContext::Draw(int vertexCount, int offset) { - _dbg_assert_msg_(curVBuffers_[0] != nullptr, "Can't call Draw without a vertex buffer"); + _dbg_assert_msg_(curVBuffer_ != nullptr, "Can't call Draw without a vertex buffer"); ApplySamplers(); _assert_(curPipeline_->inputLayout); - renderManager_.Draw(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0], curPipeline_->prim, offset, vertexCount); + renderManager_.Draw(curPipeline_->inputLayout->inputLayout_, curVBuffer_->buffer_, curVBufferOffset_, curPipeline_->prim, offset, vertexCount); } void OpenGLContext::DrawIndexed(int vertexCount, int offset) { - _dbg_assert_msg_(curVBuffers_[0] != nullptr, "Can't call DrawIndexed without a vertex buffer"); + _dbg_assert_msg_(curVBuffer_ != nullptr, "Can't call DrawIndexed without a vertex buffer"); _dbg_assert_msg_(curIBuffer_ != nullptr, "Can't call DrawIndexed without an index buffer"); ApplySamplers(); _assert_(curPipeline_->inputLayout); renderManager_.DrawIndexed( curPipeline_->inputLayout->inputLayout_, - curVBuffers_[0]->buffer_, curVBufferOffsets_[0], + curVBuffer_->buffer_, curVBufferOffset_, curIBuffer_->buffer_, curIBufferOffset_ + offset * sizeof(uint32_t), curPipeline_->prim, vertexCount, GL_UNSIGNED_SHORT); } @@ -1432,13 +1429,12 @@ 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 = desc.bindings.empty() ? 0 : (GLsizei)desc.bindings[0].stride; + stride = desc.stride; std::vector entries; for (auto &attr : desc.attributes) { GLRInputLayout::Entry entry; entry.location = attr.location; - entry.stride = (GLsizei)desc.bindings[attr.binding].stride; entry.offset = attr.offset; switch (attr.format) { case DataFormat::R32G32_FLOAT: @@ -1470,7 +1466,7 @@ void OpenGLInputLayout::Compile(const InputLayoutDesc &desc) { entries.push_back(entry); } if (!entries.empty()) { - inputLayout_ = render_->CreateInputLayout(entries); + inputLayout_ = render_->CreateInputLayout(entries, stride); } else { inputLayout_ = nullptr; } diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index 0c296adbd38e..ee6cf399d6a6 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -247,7 +247,7 @@ bool VKShaderModule::Compile(VulkanContext *vulkan, ShaderLanguage language, con class VKInputLayout : public InputLayout { public: - std::vector bindings; + VkVertexInputBindingDescription binding; std::vector attributes; VkPipelineVertexInputStateCreateInfo visc; }; @@ -290,7 +290,7 @@ class VKPipeline : public Pipeline { std::vector deps; - int stride[4]{}; + int stride = 0; int dynamicUniformSize = 0; bool usesStencil = false; @@ -446,13 +446,9 @@ class VKContext : public DrawContext { curPipeline_ = (VKPipeline *)pipeline; } - // TODO: Make VKBuffers proper buffers, and do a proper binding model. This is just silly. - void BindVertexBuffers(int start, int count, Buffer **buffers, const int *offsets) override { - _assert_(start + count <= ARRAY_SIZE(curVBuffers_)); - for (int i = 0; i < count; i++) { - curVBuffers_[i + start] = (VKBuffer *)buffers[i]; - curVBufferOffsets_[i + start] = offsets ? offsets[i] : 0; - } + void BindVertexBuffer(Buffer *vertexBuffer, int offset) override { + curVBuffer_ = (VKBuffer *)vertexBuffer; + curVBufferOffset_ = offset; } void BindIndexBuffer(Buffer *indexBuffer, int offset) override { curIBuffer_ = (VKBuffer *)indexBuffer; @@ -535,8 +531,8 @@ class VKContext : public DrawContext { VulkanTexture *nullTexture_ = nullptr; AutoRef curPipeline_; - AutoRef curVBuffers_[4]; - int curVBufferOffsets_[4]{}; + AutoRef curVBuffer_; + int curVBufferOffset_ = 0; AutoRef curIBuffer_; int curIBufferOffset_ = 0; @@ -1149,13 +1145,11 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc, const char } } - _dbg_assert_(input && input->bindings.size() == 1); + _dbg_assert_(input); _dbg_assert_((int)input->attributes.size() == (int)input->visc.vertexAttributeDescriptionCount); - for (int i = 0; i < (int)input->bindings.size(); i++) { - pipeline->stride[i] = input->bindings[i].stride; - } - gDesc.ibd = input->bindings[0]; + pipeline->stride = input->binding.stride; + gDesc.ibd = input->binding; for (size_t i = 0; i < input->attributes.size(); i++) { gDesc.attrs[i] = input->attributes[i]; } @@ -1237,23 +1231,20 @@ InputLayout *VKContext::CreateInputLayout(const InputLayoutDesc &desc) { VKInputLayout *vl = new VKInputLayout(); vl->visc = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; vl->visc.flags = 0; + vl->visc.vertexBindingDescriptionCount = 1; vl->visc.vertexAttributeDescriptionCount = (uint32_t)desc.attributes.size(); - vl->visc.vertexBindingDescriptionCount = (uint32_t)desc.bindings.size(); - vl->bindings.resize(vl->visc.vertexBindingDescriptionCount); vl->attributes.resize(vl->visc.vertexAttributeDescriptionCount); - vl->visc.pVertexBindingDescriptions = vl->bindings.data(); + vl->visc.pVertexBindingDescriptions = &vl->binding; vl->visc.pVertexAttributeDescriptions = vl->attributes.data(); for (size_t i = 0; i < desc.attributes.size(); i++) { - vl->attributes[i].binding = (uint32_t)desc.attributes[i].binding; + vl->attributes[i].binding = 0; vl->attributes[i].format = DataFormatToVulkan(desc.attributes[i].format); vl->attributes[i].location = desc.attributes[i].location; vl->attributes[i].offset = desc.attributes[i].offset; } - for (size_t i = 0; i < desc.bindings.size(); i++) { - vl->bindings[i].inputRate = desc.bindings[i].instanceRate ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; - vl->bindings[i].binding = (uint32_t)i; - vl->bindings[i].stride = desc.bindings[i].stride; - } + vl->binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + vl->binding.binding = 0; + vl->binding.stride = desc.stride; return vl; } @@ -1408,7 +1399,7 @@ void VKContext::ApplyDynamicState() { } void VKContext::Draw(int vertexCount, int offset) { - VKBuffer *vbuf = curVBuffers_[0]; + VKBuffer *vbuf = curVBuffer_; VkBuffer vulkanVbuf; VkBuffer vulkanUBObuf; @@ -1420,12 +1411,12 @@ void VKContext::Draw(int vertexCount, int offset) { int descSetIndex; PackedDescriptor *descriptors = renderManager_.PushDescriptorSet(4, &descSetIndex); BindDescriptors(vulkanUBObuf, descriptors); - renderManager_.Draw(descSetIndex, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vertexCount, offset); + renderManager_.Draw(descSetIndex, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffset_, vertexCount, offset); } void VKContext::DrawIndexed(int vertexCount, int offset) { VKBuffer *ibuf = curIBuffer_; - VKBuffer *vbuf = curVBuffers_[0]; + VKBuffer *vbuf = curVBuffer_; VkBuffer vulkanVbuf, vulkanIbuf, vulkanUBObuf; uint32_t ubo_offset = (uint32_t)curPipeline_->PushUBO(push_, vulkan_, &vulkanUBObuf); @@ -1437,7 +1428,7 @@ void VKContext::DrawIndexed(int vertexCount, int offset) { int descSetIndex; PackedDescriptor *descriptors = renderManager_.PushDescriptorSet(4, &descSetIndex); BindDescriptors(vulkanUBObuf, descriptors); - renderManager_.DrawIndexed(descSetIndex, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vulkanIbuf, (int)ibBindOffset + offset * sizeof(uint32_t), vertexCount, 1); + renderManager_.DrawIndexed(descSetIndex, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffset_, vulkanIbuf, (int)ibBindOffset + offset * sizeof(uint32_t), vertexCount, 1); } void VKContext::DrawUP(const void *vdata, int vertexCount) { @@ -1447,7 +1438,7 @@ void VKContext::DrawUP(const void *vdata, int vertexCount) { } VkBuffer vulkanVbuf, vulkanUBObuf; - size_t dataSize = vertexCount * curPipeline_->stride[0]; + size_t dataSize = vertexCount * curPipeline_->stride; uint32_t vbBindOffset; uint8_t *dataPtr = push_->Allocate(dataSize, 4, &vulkanVbuf, &vbBindOffset); _assert_(dataPtr != nullptr); @@ -1460,7 +1451,7 @@ void VKContext::DrawUP(const void *vdata, int vertexCount) { int descSetIndex; PackedDescriptor *descriptors = renderManager_.PushDescriptorSet(4, &descSetIndex); BindDescriptors(vulkanUBObuf, descriptors); - renderManager_.Draw(descSetIndex, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vertexCount); + renderManager_.Draw(descSetIndex, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffset_, vertexCount); } void VKContext::BindCurrentPipeline() { diff --git a/Common/GPU/thin3d.h b/Common/GPU/thin3d.h index e40918cd927b..fb6f402e49c4 100644 --- a/Common/GPU/thin3d.h +++ b/Common/GPU/thin3d.h @@ -475,20 +475,14 @@ class Texture : public RefCountedObject { DataFormat format_ = DataFormat::UNDEFINED; }; -struct BindingDesc { - int stride; - bool instanceRate; -}; - struct AttributeDesc { - int binding; int location; // corresponds to semantic DataFormat format; int offset; }; struct InputLayoutDesc { - std::vector bindings; + int stride; std::vector attributes; }; @@ -787,7 +781,7 @@ class DrawContext { virtual void BindSamplerStates(int start, int count, SamplerState **state) = 0; virtual void BindTextures(int start, int count, Texture **textures, TextureBindFlags flags = TextureBindFlags::NONE) = 0; - virtual void BindVertexBuffers(int start, int count, Buffer **buffers, const int *offsets) = 0; + virtual void BindVertexBuffer(Buffer *vertexBuffer, int offset) = 0; virtual void BindIndexBuffer(Buffer *indexBuffer, int offset) = 0; // Sometimes it's necessary to bind a texture not created by thin3d, and use with a thin3d pipeline. diff --git a/Common/Render/DrawBuffer.cpp b/Common/Render/DrawBuffer.cpp index f8d388f074d0..8e297323946d 100644 --- a/Common/Render/DrawBuffer.cpp +++ b/Common/Render/DrawBuffer.cpp @@ -39,13 +39,11 @@ void DrawBuffer::Init(Draw::DrawContext *t3d, Draw::Pipeline *pipeline) { Draw::InputLayout *DrawBuffer::CreateInputLayout(Draw::DrawContext *t3d) { using namespace Draw; InputLayoutDesc desc = { + sizeof(Vertex), { - { sizeof(Vertex), false }, - }, - { - { 0, SEM_POSITION, DataFormat::R32G32B32_FLOAT, 0 }, - { 0, SEM_TEXCOORD0, DataFormat::R32G32_FLOAT, 12 }, - { 0, SEM_COLOR0, DataFormat::R8G8B8A8_UNORM, 20 }, + { SEM_POSITION, DataFormat::R32G32B32_FLOAT, 0 }, + { SEM_TEXCOORD0, DataFormat::R32G32_FLOAT, 12 }, + { SEM_COLOR0, DataFormat::R8G8B8A8_UNORM, 20 }, }, }; diff --git a/GPU/Common/DepthBufferCommon.cpp b/GPU/Common/DepthBufferCommon.cpp index a29c99577575..a52a9e38590c 100644 --- a/GPU/Common/DepthBufferCommon.cpp +++ b/GPU/Common/DepthBufferCommon.cpp @@ -131,12 +131,10 @@ Draw::Pipeline *CreateReadbackPipeline(Draw::DrawContext *draw, const char *tag, ShaderModule *readbackVs = draw->CreateShaderModule(ShaderStage::Vertex, shaderLanguageDesc.shaderLanguage, (const uint8_t *)vs, strlen(vs), vsTag); _assert_(readbackFs && readbackVs); - InputLayoutDesc desc = { + static const InputLayoutDesc desc = { + 8, { - { 8, false }, - }, - { - { 0, SEM_POSITION, DataFormat::R32G32_FLOAT, 0 }, + { SEM_POSITION, DataFormat::R32G32_FLOAT, 0 }, }, }; InputLayout *inputLayout = draw->CreateInputLayout(desc); diff --git a/GPU/Common/Draw2D.cpp b/GPU/Common/Draw2D.cpp index 95a53bf2c9d5..ebf9dec6838a 100644 --- a/GPU/Common/Draw2D.cpp +++ b/GPU/Common/Draw2D.cpp @@ -265,12 +265,10 @@ Draw2DPipeline *Draw2D::Create2DPipeline(std::functionCreateInputLayout(desc); diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index cc8c728c9f22..d86db4bd9e6d 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -480,13 +480,11 @@ Draw::Pipeline *PresentationCommon::CreatePipeline(std::vectorusePreviousFrame) draw_->BindSamplerStates(2, 1, &sampler); - draw_->BindVertexBuffers(0, 1, &vdata_, &vertsOffset); + draw_->BindVertexBuffer(vdata_, vertsOffset); draw_->Draw(4, 0); postShaderOutput = postShaderFramebuffer; @@ -898,7 +896,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u draw_->UpdateDynamicUniformBuffer(&ub, sizeof(ub)); } - draw_->BindVertexBuffers(0, 1, &vdata_, nullptr); + draw_->BindVertexBuffer(vdata_, 0); Draw::SamplerState *sampler = useNearest ? samplerNearest_ : samplerLinear_; draw_->BindSamplerStates(0, 1, &sampler); diff --git a/GPU/Common/StencilCommon.cpp b/GPU/Common/StencilCommon.cpp index e146a01110af..07c191e465ac 100644 --- a/GPU/Common/StencilCommon.cpp +++ b/GPU/Common/StencilCommon.cpp @@ -230,11 +230,9 @@ bool FramebufferManagerCommon::PerformWriteStencilFromMemory(u32 addr, int size, _assert_(stencilUploadFs && stencilUploadVs); InputLayoutDesc desc = { + 8, { - { 8, false }, - }, - { - { 0, SEM_POSITION, DataFormat::R32G32_FLOAT, 0 }, + { SEM_POSITION, DataFormat::R32G32_FLOAT, 0 }, }, }; InputLayout *inputLayout = draw_->CreateInputLayout(desc); diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 240bc73a59e3..4d6de3d202f2 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -101,14 +101,14 @@ void DrawEngineGLES::InitDeviceObjects() { frameData_[i].pushIndex = render_->CreatePushBuffer(i, GL_ELEMENT_ARRAY_BUFFER, 256 * 1024, "game_index"); } - int vertexSize = sizeof(TransformedVertex); + int stride = sizeof(TransformedVertex); std::vector entries; - entries.push_back({ ATTR_POSITION, 4, GL_FLOAT, GL_FALSE, vertexSize, offsetof(TransformedVertex, x) }); - entries.push_back({ ATTR_TEXCOORD, 3, GL_FLOAT, GL_FALSE, vertexSize, offsetof(TransformedVertex, u) }); - entries.push_back({ ATTR_COLOR0, 4, GL_UNSIGNED_BYTE, GL_TRUE, vertexSize, offsetof(TransformedVertex, color0) }); - entries.push_back({ ATTR_COLOR1, 3, GL_UNSIGNED_BYTE, GL_TRUE, vertexSize, offsetof(TransformedVertex, color1) }); - entries.push_back({ ATTR_NORMAL, 1, GL_FLOAT, GL_FALSE, vertexSize, offsetof(TransformedVertex, fog) }); - softwareInputLayout_ = render_->CreateInputLayout(entries); + entries.push_back({ ATTR_POSITION, 4, GL_FLOAT, GL_FALSE, offsetof(TransformedVertex, x) }); + entries.push_back({ ATTR_TEXCOORD, 3, GL_FLOAT, GL_FALSE, offsetof(TransformedVertex, u) }); + entries.push_back({ ATTR_COLOR0, 4, GL_UNSIGNED_BYTE, GL_TRUE, offsetof(TransformedVertex, color0) }); + entries.push_back({ ATTR_COLOR1, 3, GL_UNSIGNED_BYTE, GL_TRUE, offsetof(TransformedVertex, color1) }); + entries.push_back({ ATTR_NORMAL, 1, GL_FLOAT, GL_FALSE, offsetof(TransformedVertex, fog) }); + softwareInputLayout_ = render_->CreateInputLayout(entries, stride); draw_->SetInvalidationCallback(std::bind(&DrawEngineGLES::Invalidate, this, std::placeholders::_1)); } @@ -187,7 +187,7 @@ static const GlTypeInfo GLComp[] = { {GL_UNSIGNED_SHORT, 4, GL_TRUE},// DEC_U16_4, }; -static inline void VertexAttribSetup(int attrib, int fmt, int stride, int offset, std::vector &entries) { +static inline void VertexAttribSetup(int attrib, int fmt, int offset, std::vector &entries) { if (fmt) { const GlTypeInfo &type = GLComp[fmt]; GLRInputLayout::Entry entry; @@ -195,7 +195,6 @@ static inline void VertexAttribSetup(int attrib, int fmt, int stride, int offset entry.location = attrib; entry.normalized = type.normalized; entry.type = type.type; - entry.stride = stride; entry.count = type.count; entries.push_back(entry); } @@ -210,15 +209,16 @@ GLRInputLayout *DrawEngineGLES::SetupDecFmtForDraw(const DecVtxFormat &decFmt) { } std::vector entries; - VertexAttribSetup(ATTR_W1, decFmt.w0fmt, decFmt.stride, decFmt.w0off, entries); - VertexAttribSetup(ATTR_W2, decFmt.w1fmt, decFmt.stride, decFmt.w1off, entries); - VertexAttribSetup(ATTR_TEXCOORD, decFmt.uvfmt, decFmt.stride, decFmt.uvoff, entries); - VertexAttribSetup(ATTR_COLOR0, decFmt.c0fmt, decFmt.stride, decFmt.c0off, entries); - VertexAttribSetup(ATTR_COLOR1, decFmt.c1fmt, decFmt.stride, decFmt.c1off, entries); - VertexAttribSetup(ATTR_NORMAL, decFmt.nrmfmt, decFmt.stride, decFmt.nrmoff, entries); - VertexAttribSetup(ATTR_POSITION, DecVtxFormat::PosFmt(), decFmt.stride, decFmt.posoff, entries); - - inputLayout = render_->CreateInputLayout(entries); + VertexAttribSetup(ATTR_W1, decFmt.w0fmt, decFmt.w0off, entries); + VertexAttribSetup(ATTR_W2, decFmt.w1fmt, decFmt.w1off, entries); + VertexAttribSetup(ATTR_TEXCOORD, decFmt.uvfmt, decFmt.uvoff, entries); + VertexAttribSetup(ATTR_COLOR0, decFmt.c0fmt, decFmt.c0off, entries); + VertexAttribSetup(ATTR_COLOR1, decFmt.c1fmt, decFmt.c1off, entries); + VertexAttribSetup(ATTR_NORMAL, decFmt.nrmfmt, decFmt.nrmoff, entries); + VertexAttribSetup(ATTR_POSITION, DecVtxFormat::PosFmt(), decFmt.posoff, entries); + + int stride = decFmt.stride; + inputLayout = render_->CreateInputLayout(entries, stride); inputLayoutMap_.Insert(key, inputLayout); return inputLayout; }