diff --git a/Common/GPU/D3D11/thin3d_d3d11.cpp b/Common/GPU/D3D11/thin3d_d3d11.cpp index 0014b5bb05..14f361d902 100644 --- a/Common/GPU/D3D11/thin3d_d3d11.cpp +++ b/Common/GPU/D3D11/thin3d_d3d11.cpp @@ -26,6 +26,8 @@ namespace Draw { +static constexpr int MAX_BOUND_TEXTURES = 8; + // A problem is that we can't get the D3Dcompiler.dll without using a later SDK than 7.1, which was the last that // supported XP. A possible solution might be here: // https://tedwvc.wordpress.com/2014/01/01/how-to-target-xp-with-vc2012-or-vc2013-and-continue-to-use-the-windows-8-x-sdk/ @@ -1162,6 +1164,7 @@ void D3D11DrawContext::UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t } void D3D11DrawContext::BindVertexBuffers(int start, int count, Buffer **buffers, int *offsets) { + _assert_(start + count <= ARRAY_SIZE(nextVertexBuffers_)); // Lazy application for (int i = 0; i < count; i++) { D3D11Buffer *buf = (D3D11Buffer *)buffers[i]; @@ -1329,6 +1332,7 @@ Framebuffer *D3D11DrawContext::CreateFramebuffer(const FramebufferDesc &desc) { void D3D11DrawContext::BindTextures(int start, int count, Texture **textures) { // Collect the resource views from the textures. ID3D11ShaderResourceView *views[8]; + _assert_(start + count <= ARRAY_SIZE(views)); for (int i = 0; i < count; i++) { D3D11Texture *tex = (D3D11Texture *)textures[i]; views[i] = tex ? tex->view : nullptr; @@ -1338,6 +1342,7 @@ void D3D11DrawContext::BindTextures(int start, int count, Texture **textures) { void D3D11DrawContext::BindSamplerStates(int start, int count, SamplerState **states) { ID3D11SamplerState *samplers[8]; + _assert_(start + count <= ARRAY_SIZE(samplers)); for (int i = 0; i < count; i++) { D3D11SamplerState *samp = (D3D11SamplerState *)states[i]; samplers[i] = samp->ss; @@ -1613,6 +1618,7 @@ void D3D11DrawContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Ren } void D3D11DrawContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) { + _assert_(binding < MAX_BOUND_TEXTURES); D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo; switch (channelBit) { case FBChannel::FB_COLOR_BIT: diff --git a/Common/GPU/D3D9/thin3d_d3d9.cpp b/Common/GPU/D3D9/thin3d_d3d9.cpp index 79a0bb0dca..39a8b9d5b7 100644 --- a/Common/GPU/D3D9/thin3d_d3d9.cpp +++ b/Common/GPU/D3D9/thin3d_d3d9.cpp @@ -28,6 +28,8 @@ namespace Draw { +static constexpr int MAX_BOUND_TEXTURES = 8; + // Could be declared as u8 static const D3DCMPFUNC compareToD3D9[] = { D3DCMP_NEVER, @@ -525,12 +527,14 @@ public: void BindTextures(int start, int count, Texture **textures) override; void BindSamplerStates(int start, int count, SamplerState **states) override { + _assert_(start + count <= MAX_BOUND_TEXTURES); for (int i = 0; i < count; ++i) { D3D9SamplerState *s = static_cast(states[i]); s->Apply(device_, start + i); } } void BindVertexBuffers(int start, int count, Buffer **buffers, 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; @@ -785,6 +789,7 @@ Texture *D3D9Context::CreateTexture(const TextureDesc &desc) { } void D3D9Context::BindTextures(int start, int count, Texture **textures) { + _assert_(start + count <= MAX_BOUND_TEXTURES); for (int i = start; i < start + count; i++) { D3D9Texture *tex = static_cast(textures[i - start]); if (tex) { @@ -1182,6 +1187,7 @@ uintptr_t D3D9Context::GetFramebufferAPITexture(Framebuffer *fbo, int channelBit } void D3D9Context::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int color) { + _assert_(binding < MAX_BOUND_TEXTURES); D3D9Framebuffer *fb = (D3D9Framebuffer *)fbo; switch (channelBit) { case FB_DEPTH_BIT: diff --git a/Common/GPU/OpenGL/thin3d_gl.cpp b/Common/GPU/OpenGL/thin3d_gl.cpp index 454cde20f5..7d598ef1df 100644 --- a/Common/GPU/OpenGL/thin3d_gl.cpp +++ b/Common/GPU/OpenGL/thin3d_gl.cpp @@ -368,9 +368,7 @@ public: void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) override; void BindSamplerStates(int start, int count, SamplerState **states) override { - if (start + count > MAX_TEXTURE_SLOTS) { - return; - } + _assert_(start + count <= MAX_TEXTURE_SLOTS); for (int i = 0; i < count; i++) { int index = i + start; boundSamplers_[index] = static_cast(states[i]); @@ -402,6 +400,7 @@ public: void BindTextures(int start, int count, Texture **textures) override; void BindPipeline(Pipeline *pipeline) override; void BindVertexBuffers(int start, int count, Buffer **buffers, 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; @@ -1070,9 +1069,7 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) { } void OpenGLContext::BindTextures(int start, int count, Texture **textures) { - if (start + count > MAX_TEXTURE_SLOTS) { - return; - } + _assert_(start + count <= MAX_TEXTURE_SLOTS); for (int i = start; i < start + count; i++) { OpenGLTexture *glTex = static_cast(textures[i - start]); if (!glTex) { @@ -1354,6 +1351,7 @@ bool OpenGLContext::BlitFramebuffer(Framebuffer *fbsrc, int srcX1, int srcY1, in void OpenGLContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int color) { OpenGLFramebuffer *fb = (OpenGLFramebuffer *)fbo; + _assert_(binding < MAX_TEXTURE_SLOTS); GLuint aspect = 0; if (channelBit & FB_COLOR_BIT) { diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index 054096f377..f68132f5e4 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -295,7 +295,7 @@ class VKBuffer; class VKSamplerState; enum { - MAX_BOUND_TEXTURES = 2 + MAX_BOUND_TEXTURES = MAX_TEXTURE_SLOTS, }; struct DescriptorSetKey { @@ -416,6 +416,7 @@ public: // TODO: Make VKBuffers proper buffers, and do a proper binding model. This is just silly. void BindVertexBuffers(int start, int count, Buffer **buffers, 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; @@ -689,6 +690,7 @@ RasterState *VKContext::CreateRasterState(const RasterStateDesc &desc) { } void VKContext::BindSamplerStates(int start, int count, SamplerState **state) { + _assert_(start + count <= MAX_BOUND_TEXTURES); for (int i = start; i < start + count; i++) { boundSamplers_[i] = (VKSamplerState *)state[i - start]; } @@ -1271,6 +1273,7 @@ void VKContext::UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, } void VKContext::BindTextures(int start, int count, Texture **textures) { + _assert_(start + count <= MAX_BOUND_TEXTURES); for (int i = start; i < start + count; i++) { boundTextures_[i] = static_cast(textures[i - start]); boundImageView_[i] = boundTextures_[i] ? boundTextures_[i]->GetImageView() : GetNullTexture()->GetImageView(); @@ -1544,6 +1547,7 @@ void VKContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPass void VKContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) { VKFramebuffer *fb = (VKFramebuffer *)fbo; + _assert_(binding < MAX_BOUND_TEXTURES); // TODO: There are cases where this is okay, actually. But requires layout transitions and stuff - // we're not ready for this.