diff --git a/include/SDL3/SDL_gpu.h b/include/SDL3/SDL_gpu.h index 211d298f10..09f46738b4 100644 --- a/include/SDL3/SDL_gpu.h +++ b/include/SDL3/SDL_gpu.h @@ -1207,8 +1207,8 @@ typedef struct SDL_GPUDepthStencilState SDL_GPUStencilOpState frontStencilState; Uint8 compareMask; Uint8 writeMask; - Uint8 reference; Uint8 padding2; + Uint8 padding3; } SDL_GPUDepthStencilState; typedef struct SDL_GPUColorAttachmentDescription @@ -1238,7 +1238,6 @@ typedef struct SDL_GPUGraphicsPipelineCreateInfo SDL_GPUMultisampleState multisampleState; SDL_GPUDepthStencilState depthStencilState; SDL_GPUGraphicsPipelineAttachmentInfo attachmentInfo; - float blendConstants[4]; SDL_PropertiesID props; } SDL_GPUGraphicsPipelineCreateInfo; @@ -2140,6 +2139,33 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetGPUScissor( SDL_GPURenderPass *renderPass, const SDL_Rect *scissor); +/** + * Sets the current blend constants on a command buffer. + * + * \param renderPass a render pass handle. + * \param blendConstants the blend constant color. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GPU_BLENDFACTOR_CONSTANT_COLOR + * \sa SDL_GPU_BLENDFACTOR_ONE_MINUS_CONSTANT_COLOR + */ +extern SDL_DECLSPEC void SDLCALL SDL_SetGPUBlendConstants( + SDL_GPURenderPass *renderPass, + SDL_FColor blendConstants); + +/** + * Sets the current stencil reference value on a command buffer. + * + * \param renderPass a render pass handle. + * \param reference the stencil reference value to set. + * + * \since This function is available since SDL 3.0.0. + */ +extern SDL_DECLSPEC void SDLCALL SDL_SetGPUStencilReference( + SDL_GPURenderPass *renderPass, + Uint8 reference); + /** * Binds vertex buffers on a command buffer for use with subsequent draw * calls. diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index f3b8de3c44..35ef0041f1 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -778,8 +778,10 @@ SDL3_0.0.0 { SDL_SetEventEnabled; SDL_SetEventFilter; SDL_SetFloatProperty; + SDL_SetGPUBlendConstants; SDL_SetGPUBufferName; SDL_SetGPUScissor; + SDL_SetGPUStencilReference; SDL_SetGPUSwapchainParameters; SDL_SetGPUTextureName; SDL_SetGPUViewport; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 66e618b778..d04960d010 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -803,8 +803,10 @@ #define SDL_SetEventEnabled SDL_SetEventEnabled_REAL #define SDL_SetEventFilter SDL_SetEventFilter_REAL #define SDL_SetFloatProperty SDL_SetFloatProperty_REAL +#define SDL_SetGPUBlendConstants SDL_SetGPUBlendConstants_REAL #define SDL_SetGPUBufferName SDL_SetGPUBufferName_REAL #define SDL_SetGPUScissor SDL_SetGPUScissor_REAL +#define SDL_SetGPUStencilReference SDL_SetGPUStencilReference_REAL #define SDL_SetGPUSwapchainParameters SDL_SetGPUSwapchainParameters_REAL #define SDL_SetGPUTextureName SDL_SetGPUTextureName_REAL #define SDL_SetGPUViewport SDL_SetGPUViewport_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 54f542f37f..0d1ed3b05e 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -813,8 +813,10 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_SetCursor,(SDL_Cursor *a),(a),return) SDL_DYNAPI_PROC(void,SDL_SetEventEnabled,(Uint32 a, SDL_bool b),(a,b),) SDL_DYNAPI_PROC(void,SDL_SetEventFilter,(SDL_EventFilter a, void *b),(a,b),) SDL_DYNAPI_PROC(SDL_bool,SDL_SetFloatProperty,(SDL_PropertiesID a, const char *b, float c),(a,b,c),return) +SDL_DYNAPI_PROC(void,SDL_SetGPUBlendConstants,(SDL_GPURenderPass *a, SDL_FColor b),(a,b),) SDL_DYNAPI_PROC(void,SDL_SetGPUBufferName,(SDL_GPUDevice *a, SDL_GPUBuffer *b, const char *c),(a,b,c),) SDL_DYNAPI_PROC(void,SDL_SetGPUScissor,(SDL_GPURenderPass *a, const SDL_Rect *b),(a,b),) +SDL_DYNAPI_PROC(void,SDL_SetGPUStencilReference,(SDL_GPURenderPass *a, Uint8 b),(a,b),) SDL_DYNAPI_PROC(SDL_bool,SDL_SetGPUSwapchainParameters,(SDL_GPUDevice *a, SDL_Window *b, SDL_GPUSwapchainComposition c, SDL_GPUPresentMode d),(a,b,c,d),return) SDL_DYNAPI_PROC(void,SDL_SetGPUTextureName,(SDL_GPUDevice *a, SDL_GPUTexture *b, const char *c),(a,b,c),) SDL_DYNAPI_PROC(void,SDL_SetGPUViewport,(SDL_GPURenderPass *a, const SDL_GPUViewport *b),(a,b),) diff --git a/src/gpu/SDL_gpu.c b/src/gpu/SDL_gpu.c index c737b08204..8f8a3593fe 100644 --- a/src/gpu/SDL_gpu.c +++ b/src/gpu/SDL_gpu.c @@ -194,11 +194,6 @@ SDL_GPUGraphicsPipeline *SDL_GPU_FetchBlitPipeline( blitPipelineCreateInfo.primitiveType = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST; - blitPipelineCreateInfo.blendConstants[0] = 1.0f; - blitPipelineCreateInfo.blendConstants[1] = 1.0f; - blitPipelineCreateInfo.blendConstants[2] = 1.0f; - blitPipelineCreateInfo.blendConstants[3] = 1.0f; - pipeline = SDL_CreateGPUGraphicsPipeline( device, &blitPipelineCreateInfo); @@ -1281,6 +1276,42 @@ void SDL_SetGPUScissor( scissor); } +void SDL_SetGPUBlendConstants( + SDL_GPURenderPass *renderPass, + SDL_FColor blendConstants) +{ + if (renderPass == NULL) { + SDL_InvalidParamError("renderPass"); + return; + } + + if (RENDERPASS_DEVICE->debugMode) { + CHECK_RENDERPASS + } + + RENDERPASS_DEVICE->SetBlendConstants( + RENDERPASS_COMMAND_BUFFER, + blendConstants); +} + +void SDL_SetGPUStencilReference( + SDL_GPURenderPass *renderPass, + Uint8 reference) +{ + if (renderPass == NULL) { + SDL_InvalidParamError("renderPass"); + return; + } + + if (RENDERPASS_DEVICE->debugMode) { + CHECK_RENDERPASS + } + + RENDERPASS_DEVICE->SetStencilReference( + RENDERPASS_COMMAND_BUFFER, + reference); +} + void SDL_BindGPUVertexBuffers( SDL_GPURenderPass *renderPass, Uint32 firstBinding, diff --git a/src/gpu/SDL_sysgpu.h b/src/gpu/SDL_sysgpu.h index 7bb6319838..f9585e5b4b 100644 --- a/src/gpu/SDL_sysgpu.h +++ b/src/gpu/SDL_sysgpu.h @@ -398,6 +398,14 @@ struct SDL_GPUDevice SDL_GPUCommandBuffer *commandBuffer, const SDL_Rect *scissor); + void (*SetBlendConstants)( + SDL_GPUCommandBuffer *commandBuffer, + SDL_FColor blendConstants); + + void (*SetStencilReference)( + SDL_GPUCommandBuffer *commandBuffer, + Uint8 reference); + void (*BindVertexBuffers)( SDL_GPUCommandBuffer *commandBuffer, Uint32 firstBinding, @@ -716,6 +724,8 @@ struct SDL_GPUDevice ASSIGN_DRIVER_FUNC(BindGraphicsPipeline, name) \ ASSIGN_DRIVER_FUNC(SetViewport, name) \ ASSIGN_DRIVER_FUNC(SetScissor, name) \ + ASSIGN_DRIVER_FUNC(SetBlendConstants, name) \ + ASSIGN_DRIVER_FUNC(SetStencilReference, name) \ ASSIGN_DRIVER_FUNC(BindVertexBuffers, name) \ ASSIGN_DRIVER_FUNC(BindIndexBuffer, name) \ ASSIGN_DRIVER_FUNC(BindVertexSamplers, name) \ diff --git a/src/gpu/d3d11/SDL_gpu_d3d11.c b/src/gpu/d3d11/SDL_gpu_d3d11.c index 61bb1c67e0..741a593b95 100644 --- a/src/gpu/d3d11/SDL_gpu_d3d11.c +++ b/src/gpu/d3d11/SDL_gpu_d3d11.c @@ -476,7 +476,6 @@ typedef struct D3D11Shader typedef struct D3D11GraphicsPipeline { - float blendConstants[4]; Sint32 numColorAttachments; DXGI_FORMAT colorAttachmentFormats[MAX_COLOR_TARGET_BINDINGS]; ID3D11BlendState *colorAttachmentBlendState; @@ -486,7 +485,6 @@ typedef struct D3D11GraphicsPipeline Uint8 hasDepthStencilAttachment; DXGI_FORMAT depthStencilAttachmentFormat; ID3D11DepthStencilState *depthStencilState; - Uint8 stencilRef; SDL_GPUPrimitiveType primitiveType; ID3D11RasterizerState *rasterizerState; @@ -615,6 +613,8 @@ typedef struct D3D11CommandBuffer // Render Pass D3D11GraphicsPipeline *graphicsPipeline; + Uint8 stencilRef; + SDL_FColor blendConstants; // Render Pass MSAA resolve D3D11Texture *colorTargetResolveTexture[MAX_COLOR_TARGET_BINDINGS]; @@ -1541,11 +1541,6 @@ static SDL_GPUGraphicsPipeline *D3D11_CreateGraphicsPipeline( pipeline->colorAttachmentFormats[i] = SDLToD3D11_TextureFormat[pipelineCreateInfo->attachmentInfo.colorAttachmentDescriptions[i].format]; } - pipeline->blendConstants[0] = pipelineCreateInfo->blendConstants[0]; - pipeline->blendConstants[1] = pipelineCreateInfo->blendConstants[1]; - pipeline->blendConstants[2] = pipelineCreateInfo->blendConstants[2]; - pipeline->blendConstants[3] = pipelineCreateInfo->blendConstants[3]; - // Multisample pipeline->multisampleState = pipelineCreateInfo->multisampleState; @@ -1558,7 +1553,6 @@ static SDL_GPUGraphicsPipeline *D3D11_CreateGraphicsPipeline( pipeline->hasDepthStencilAttachment = pipelineCreateInfo->attachmentInfo.hasDepthStencilAttachment; pipeline->depthStencilAttachmentFormat = SDLToD3D11_TextureFormat[pipelineCreateInfo->attachmentInfo.depthStencilFormat]; - pipeline->stencilRef = pipelineCreateInfo->depthStencilState.reference; // Rasterizer @@ -3204,6 +3198,8 @@ static SDL_GPUCommandBuffer *D3D11_AcquireCommandBuffer( commandBuffer = D3D11_INTERNAL_GetInactiveCommandBufferFromPool(renderer); commandBuffer->graphicsPipeline = NULL; + commandBuffer->stencilRef = 0; + commandBuffer->blendConstants = (SDL_FColor){ 1.0f, 1.0f, 1.0f, 1.0f }; commandBuffer->computePipeline = NULL; for (i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1) { commandBuffer->colorTargetResolveTexture[i] = NULL; @@ -3384,6 +3380,78 @@ static void D3D11_INTERNAL_PushUniformData( } } +static void D3D11_SetViewport( + SDL_GPUCommandBuffer *commandBuffer, + const SDL_GPUViewport *viewport) +{ + D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer *)commandBuffer; + D3D11_VIEWPORT vp = { + viewport->x, + viewport->y, + viewport->w, + viewport->h, + viewport->minDepth, + viewport->maxDepth + }; + + ID3D11DeviceContext_RSSetViewports( + d3d11CommandBuffer->context, + 1, + &vp); +} + +static void D3D11_SetScissor( + SDL_GPUCommandBuffer *commandBuffer, + const SDL_Rect *scissor) +{ + D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer *)commandBuffer; + D3D11_RECT rect = { + scissor->x, + scissor->y, + scissor->x + scissor->w, + scissor->y + scissor->h + }; + + ID3D11DeviceContext_RSSetScissorRects( + d3d11CommandBuffer->context, + 1, + &rect); +} + +static void D3D11_SetBlendConstants( + SDL_GPUCommandBuffer *commandBuffer, + SDL_FColor blendConstants) +{ + D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer *)commandBuffer; + FLOAT blendFactor[4] = { blendConstants.r, blendConstants.g, blendConstants.b, blendConstants.a }; + + d3d11CommandBuffer->blendConstants = blendConstants; + + if (d3d11CommandBuffer->graphicsPipeline != NULL) { + ID3D11DeviceContext_OMSetBlendState( + d3d11CommandBuffer->context, + d3d11CommandBuffer->graphicsPipeline->colorAttachmentBlendState, + blendFactor, + d3d11CommandBuffer->graphicsPipeline->multisampleState.sampleMask); + } +} + +static void D3D11_SetStencilReference( + SDL_GPUCommandBuffer *commandBuffer, + Uint8 reference) +{ + D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer *)commandBuffer; + + d3d11CommandBuffer->stencilRef = reference; + + if (d3d11CommandBuffer->graphicsPipeline != NULL) { + ID3D11DeviceContext_OMSetDepthStencilState( + d3d11CommandBuffer->context, + d3d11CommandBuffer->graphicsPipeline->depthStencilState, + reference); + } +} + static void D3D11_BeginRenderPass( SDL_GPUCommandBuffer *commandBuffer, const SDL_GPUColorAttachmentInfo *colorAttachmentInfos, @@ -3396,8 +3464,8 @@ static void D3D11_BeginRenderPass( ID3D11DepthStencilView *dsv = NULL; Uint32 vpWidth = SDL_MAX_UINT32; Uint32 vpHeight = SDL_MAX_UINT32; - D3D11_VIEWPORT viewport; - D3D11_RECT scissorRect; + SDL_GPUViewport viewport; + SDL_Rect scissorRect; d3d11CommandBuffer->needVertexSamplerBind = true; d3d11CommandBuffer->needVertexResourceBind = true; @@ -3524,28 +3592,34 @@ static void D3D11_BeginRenderPass( } } - // Set default viewport and scissor state - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = (FLOAT)vpWidth; - viewport.Height = (FLOAT)vpHeight; - viewport.MinDepth = 0; - viewport.MaxDepth = 1; + // Set sensible default states + viewport.x = 0; + viewport.y = 0; + viewport.w = (float)vpWidth; + viewport.h = (float)vpHeight; + viewport.minDepth = 0; + viewport.maxDepth = 1; - ID3D11DeviceContext_RSSetViewports( - d3d11CommandBuffer->context, - 1, + D3D11_SetViewport( + commandBuffer, &viewport); - scissorRect.left = 0; - scissorRect.right = (LONG)viewport.Width; - scissorRect.top = 0; - scissorRect.bottom = (LONG)viewport.Height; + scissorRect.x = 0; + scissorRect.y = 0; + scissorRect.w = (int)vpWidth; + scissorRect.h = (int)vpHeight; - ID3D11DeviceContext_RSSetScissorRects( - d3d11CommandBuffer->context, - 1, + D3D11_SetScissor( + commandBuffer, &scissorRect); + + D3D11_SetStencilReference( + commandBuffer, + 0); + + D3D11_SetBlendConstants( + commandBuffer, + (SDL_FColor){ 1.0f, 1.0f, 1.0f, 1.0f }); } static void D3D11_BindGraphicsPipeline( @@ -3554,19 +3628,25 @@ static void D3D11_BindGraphicsPipeline( { D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer *)commandBuffer; D3D11GraphicsPipeline *pipeline = (D3D11GraphicsPipeline *)graphicsPipeline; + FLOAT blendFactor[4] = { + d3d11CommandBuffer->blendConstants.r, + d3d11CommandBuffer->blendConstants.g, + d3d11CommandBuffer->blendConstants.b, + d3d11CommandBuffer->blendConstants.a + }; d3d11CommandBuffer->graphicsPipeline = pipeline; ID3D11DeviceContext_OMSetBlendState( d3d11CommandBuffer->context, pipeline->colorAttachmentBlendState, - pipeline->blendConstants, + blendFactor, pipeline->multisampleState.sampleMask); ID3D11DeviceContext_OMSetDepthStencilState( d3d11CommandBuffer->context, pipeline->depthStencilState, - pipeline->stencilRef); + d3d11CommandBuffer->stencilRef); ID3D11DeviceContext_IASetPrimitiveTopology( d3d11CommandBuffer->context, @@ -3612,44 +3692,6 @@ static void D3D11_BindGraphicsPipeline( d3d11CommandBuffer->needFragmentUniformBufferBind = true; } -static void D3D11_SetViewport( - SDL_GPUCommandBuffer *commandBuffer, - const SDL_GPUViewport *viewport) -{ - D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer *)commandBuffer; - D3D11_VIEWPORT vp = { - viewport->x, - viewport->y, - viewport->w, - viewport->h, - viewport->minDepth, - viewport->maxDepth - }; - - ID3D11DeviceContext_RSSetViewports( - d3d11CommandBuffer->context, - 1, - &vp); -} - -static void D3D11_SetScissor( - SDL_GPUCommandBuffer *commandBuffer, - const SDL_Rect *scissor) -{ - D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer *)commandBuffer; - D3D11_RECT rect = { - scissor->x, - scissor->y, - scissor->x + scissor->w, - scissor->y + scissor->h - }; - - ID3D11DeviceContext_RSSetScissorRects( - d3d11CommandBuffer->context, - 1, - &rect); -} - static void D3D11_BindVertexBuffers( SDL_GPUCommandBuffer *commandBuffer, Uint32 firstBinding, @@ -5786,11 +5828,6 @@ static void D3D11_INTERNAL_InitBlitPipelines( blitPipelineCreateInfo.primitiveType = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST; - blitPipelineCreateInfo.blendConstants[0] = 1.0f; - blitPipelineCreateInfo.blendConstants[1] = 1.0f; - blitPipelineCreateInfo.blendConstants[2] = 1.0f; - blitPipelineCreateInfo.blendConstants[3] = 1.0f; - blitPipeline = D3D11_CreateGraphicsPipeline( (SDL_GPURenderer *)renderer, &blitPipelineCreateInfo); diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c index f219e75cc6..c3a98dacb0 100644 --- a/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -775,9 +775,6 @@ struct D3D12GraphicsPipeline Uint32 vertexStrides[MAX_BUFFER_BINDINGS]; - float blendConstants[4]; - Uint8 stencilRef; - Uint32 vertexSamplerCount; Uint32 vertexUniformBufferCount; Uint32 vertexStorageBufferCount; @@ -2603,11 +2600,6 @@ static SDL_GPUGraphicsPipeline *D3D12_CreateGraphicsPipeline( } pipeline->primitiveType = pipelineCreateInfo->primitiveType; - pipeline->blendConstants[0] = pipelineCreateInfo->blendConstants[0]; - pipeline->blendConstants[1] = pipelineCreateInfo->blendConstants[1]; - pipeline->blendConstants[2] = pipelineCreateInfo->blendConstants[2]; - pipeline->blendConstants[3] = pipelineCreateInfo->blendConstants[3]; - pipeline->stencilRef = pipelineCreateInfo->depthStencilState.reference; pipeline->vertexSamplerCount = vertShader->samplerCount; pipeline->vertexStorageTextureCount = vertShader->storageTextureCount; @@ -3611,6 +3603,23 @@ static void D3D12_SetScissor( ID3D12GraphicsCommandList_RSSetScissorRects(d3d12CommandBuffer->graphicsCommandList, 1, &scissorRect); } +static void D3D12_SetBlendConstants( + SDL_GPUCommandBuffer *commandBuffer, + SDL_FColor blendConstants) +{ + D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer; + FLOAT blendFactor[4] = { blendConstants.r, blendConstants.g, blendConstants.b, blendConstants.a }; + ID3D12GraphicsCommandList_OMSetBlendFactor(d3d12CommandBuffer->graphicsCommandList, blendFactor); +} + +static void D3D12_SetStencilReference( + SDL_GPUCommandBuffer *commandBuffer, + Uint8 reference +) { + D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer; + ID3D12GraphicsCommandList_OMSetStencilRef(d3d12CommandBuffer->graphicsCommandList, reference); +} + static D3D12TextureSubresource *D3D12_INTERNAL_FetchTextureSubresource( D3D12TextureContainer *container, Uint32 layer, @@ -3783,7 +3792,6 @@ static void D3D12_BeginRenderPass( const SDL_GPUDepthStencilAttachmentInfo *depthStencilAttachmentInfo) { D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer; - /* D3D12Renderer *renderer = d3d12CommandBuffer->renderer; */ Uint32 framebufferWidth = SDL_MAX_UINT32; Uint32 framebufferHeight = SDL_MAX_UINT32; @@ -3915,7 +3923,7 @@ static void D3D12_BeginRenderPass( false, (depthStencilAttachmentInfo == NULL) ? NULL : &dsv); - // Set sensible default viewport state + // Set sensible default states SDL_GPUViewport defaultViewport; defaultViewport.x = 0; defaultViewport.y = 0; @@ -3937,6 +3945,14 @@ static void D3D12_BeginRenderPass( D3D12_SetScissor( commandBuffer, &defaultScissor); + + D3D12_SetStencilReference( + commandBuffer, + 0); + + D3D12_SetBlendConstants( + commandBuffer, + (SDL_FColor){ 1.0f, 1.0f, 1.0f, 1.0f }); } static void D3D12_INTERNAL_TrackUniformBuffer( @@ -4120,21 +4136,9 @@ static void D3D12_BindGraphicsPipeline( // Set the pipeline state ID3D12GraphicsCommandList_SetPipelineState(d3d12CommandBuffer->graphicsCommandList, pipeline->pipelineState); - ID3D12GraphicsCommandList_SetGraphicsRootSignature(d3d12CommandBuffer->graphicsCommandList, pipeline->rootSignature->handle); - ID3D12GraphicsCommandList_IASetPrimitiveTopology(d3d12CommandBuffer->graphicsCommandList, SDLToD3D12_PrimitiveType[pipeline->primitiveType]); - float blendFactor[4] = { - pipeline->blendConstants[0], - pipeline->blendConstants[1], - pipeline->blendConstants[2], - pipeline->blendConstants[3] - }; - ID3D12GraphicsCommandList_OMSetBlendFactor(d3d12CommandBuffer->graphicsCommandList, blendFactor); - - ID3D12GraphicsCommandList_OMSetStencilRef(d3d12CommandBuffer->graphicsCommandList, pipeline->stencilRef); - // Mark that bindings are needed d3d12CommandBuffer->needVertexSamplerBind = true; d3d12CommandBuffer->needVertexStorageTextureBind = true; diff --git a/src/gpu/metal/SDL_gpu_metal.m b/src/gpu/metal/SDL_gpu_metal.m index 7c1e36b599..84eb1513ae 100644 --- a/src/gpu/metal/SDL_gpu_metal.m +++ b/src/gpu/metal/SDL_gpu_metal.m @@ -81,14 +81,14 @@ static MTLPixelFormat SDLToMetal_SurfaceFormat[] = { MTLPixelFormatABGR4Unorm, // B4G4R4A4_UNORM MTLPixelFormatBGRA8Unorm, // B8G8R8A8_UNORM #ifdef SDL_PLATFORM_MACOS - MTLPixelFormatBC1_RGBA, // BC1_UNORM - MTLPixelFormatBC2_RGBA, // BC2_UNORM - MTLPixelFormatBC3_RGBA, // BC3_UNORM - MTLPixelFormatBC4_RUnorm, // BC4_UNORM - MTLPixelFormatBC5_RGUnorm, // BC5_UNORM - MTLPixelFormatBC7_RGBAUnorm, // BC7_UNORM - MTLPixelFormatBC6H_RGBFloat, // BC6H_FLOAT - MTLPixelFormatBC6H_RGBUfloat,// BC6H_UFLOAT + MTLPixelFormatBC1_RGBA, // BC1_UNORM + MTLPixelFormatBC2_RGBA, // BC2_UNORM + MTLPixelFormatBC3_RGBA, // BC3_UNORM + MTLPixelFormatBC4_RUnorm, // BC4_UNORM + MTLPixelFormatBC5_RGUnorm, // BC5_UNORM + MTLPixelFormatBC7_RGBAUnorm, // BC7_UNORM + MTLPixelFormatBC6H_RGBFloat, // BC6H_FLOAT + MTLPixelFormatBC6H_RGBUfloat, // BC6H_UFLOAT #else MTLPixelFormatInvalid, // BC1_UNORM MTLPixelFormatInvalid, // BC2_UNORM @@ -402,14 +402,12 @@ typedef struct MetalGraphicsPipeline { id handle; - float blendConstants[4]; Uint32 sampleMask; SDL_GPURasterizerState rasterizerState; SDL_GPUPrimitiveType primitiveType; id depthStencilState; - Uint8 stencilReference; Uint32 vertexSamplerCount; Uint32 vertexUniformBufferCount; @@ -1103,13 +1101,8 @@ static SDL_GPUGraphicsPipeline *METAL_CreateGraphicsPipeline( result = SDL_malloc(sizeof(MetalGraphicsPipeline)); result->handle = pipelineState; - result->blendConstants[0] = pipelineCreateInfo->blendConstants[0]; - result->blendConstants[1] = pipelineCreateInfo->blendConstants[1]; - result->blendConstants[2] = pipelineCreateInfo->blendConstants[2]; - result->blendConstants[3] = pipelineCreateInfo->blendConstants[3]; result->sampleMask = pipelineCreateInfo->multisampleState.sampleMask; result->depthStencilState = depthStencilState; - result->stencilReference = pipelineCreateInfo->depthStencilState.reference; result->rasterizerState = pipelineCreateInfo->rasterizerState; result->primitiveType = pipelineCreateInfo->primitiveType; result->vertexSamplerCount = vertexShader->samplerCount; @@ -2087,6 +2080,65 @@ static void METAL_INTERNAL_ReturnUniformBufferToPool( uniformBuffer->drawOffset = 0; } +static void METAL_SetViewport( + SDL_GPUCommandBuffer *commandBuffer, + const SDL_GPUViewport *viewport) +{ + @autoreleasepool { + MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer; + MTLViewport metalViewport; + + metalViewport.originX = viewport->x; + metalViewport.originY = viewport->y; + metalViewport.width = viewport->w; + metalViewport.height = viewport->h; + metalViewport.znear = viewport->minDepth; + metalViewport.zfar = viewport->maxDepth; + + [metalCommandBuffer->renderEncoder setViewport:metalViewport]; + } +} + +static void METAL_SetScissor( + SDL_GPUCommandBuffer *commandBuffer, + const SDL_Rect *scissor) +{ + @autoreleasepool { + MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer; + MTLScissorRect metalScissor; + + metalScissor.x = scissor->x; + metalScissor.y = scissor->y; + metalScissor.width = scissor->w; + metalScissor.height = scissor->h; + + [metalCommandBuffer->renderEncoder setScissorRect:metalScissor]; + } +} + +static void METAL_SetBlendConstants( + SDL_GPUCommandBuffer *commandBuffer, + SDL_FColor blendConstants) +{ + @autoreleasepool { + MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer; + [metalCommandBuffer->renderEncoder setBlendColorRed:blendConstants.r + green:blendConstants.g + blue:blendConstants.b + alpha:blendConstants.a]; + } +} + +static void METAL_SetStencilReference( + SDL_GPUCommandBuffer *commandBuffer, + Uint8 reference +) { + @autoreleasepool { + MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer; + [metalCommandBuffer->renderEncoder setStencilReferenceValue:reference]; + } +} + static void METAL_BeginRenderPass( SDL_GPUCommandBuffer *commandBuffer, const SDL_GPUColorAttachmentInfo *colorAttachmentInfos, @@ -2099,8 +2151,8 @@ static void METAL_BeginRenderPass( MTLRenderPassDescriptor *passDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; Uint32 vpWidth = UINT_MAX; Uint32 vpHeight = UINT_MAX; - MTLViewport viewport; - MTLScissorRect scissorRect; + SDL_GPUViewport viewport; + SDL_Rect scissorRect; for (Uint32 i = 0; i < colorAttachmentCount; i += 1) { MetalTextureContainer *container = (MetalTextureContainer *)colorAttachmentInfos[i].texture; @@ -2201,20 +2253,28 @@ static void METAL_BeginRenderPass( } } - // Set default viewport and scissor state - viewport.originX = 0; - viewport.originY = 0; - viewport.width = vpWidth; - viewport.height = vpHeight; - viewport.znear = 0; - viewport.zfar = 1; - [metalCommandBuffer->renderEncoder setViewport:viewport]; + // Set sensible default states + viewport.x = 0; + viewport.y = 0; + viewport.w = vpWidth; + viewport.h = vpHeight; + viewport.minDepth = 0; + viewport.maxDepth = 1; + METAL_SetViewport(commandBuffer, &viewport); scissorRect.x = 0; scissorRect.y = 0; - scissorRect.width = vpWidth; - scissorRect.height = vpHeight; - [metalCommandBuffer->renderEncoder setScissorRect:scissorRect]; + scissorRect.w = vpWidth; + scissorRect.h = vpHeight; + METAL_SetScissor(commandBuffer, &scissorRect); + + METAL_SetBlendConstants( + commandBuffer, + (SDL_FColor){ 1.0f, 1.0f, 1.0f, 1.0f }); + + METAL_SetStencilReference( + commandBuffer, + 0); } } @@ -2240,19 +2300,10 @@ static void METAL_BindGraphicsPipeline( slopeScale:((rast->depthBiasEnable) ? rast->depthBiasSlopeFactor : 0) clamp:((rast->depthBiasEnable) ? rast->depthBiasClamp : 0)]; - // Apply blend constants - [metalCommandBuffer->renderEncoder - setBlendColorRed:metalGraphicsPipeline->blendConstants[0] - green:metalGraphicsPipeline->blendConstants[1] - blue:metalGraphicsPipeline->blendConstants[2] - alpha:metalGraphicsPipeline->blendConstants[3]]; - // Apply depth-stencil state if (metalGraphicsPipeline->depthStencilState != NULL) { [metalCommandBuffer->renderEncoder setDepthStencilState:metalGraphicsPipeline->depthStencilState]; - [metalCommandBuffer->renderEncoder - setStencilReferenceValue:metalGraphicsPipeline->stencilReference]; } for (Uint32 i = 0; i < metalGraphicsPipeline->vertexUniformBufferCount; i += 1) { @@ -2274,42 +2325,6 @@ static void METAL_BindGraphicsPipeline( } } -static void METAL_SetViewport( - SDL_GPUCommandBuffer *commandBuffer, - const SDL_GPUViewport *viewport) -{ - @autoreleasepool { - MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer; - MTLViewport metalViewport; - - metalViewport.originX = viewport->x; - metalViewport.originY = viewport->y; - metalViewport.width = viewport->w; - metalViewport.height = viewport->h; - metalViewport.znear = viewport->minDepth; - metalViewport.zfar = viewport->maxDepth; - - [metalCommandBuffer->renderEncoder setViewport:metalViewport]; - } -} - -static void METAL_SetScissor( - SDL_GPUCommandBuffer *commandBuffer, - const SDL_Rect *scissor) -{ - @autoreleasepool { - MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer; - MTLScissorRect metalScissor; - - metalScissor.x = scissor->x; - metalScissor.y = scissor->y; - metalScissor.width = scissor->w; - metalScissor.height = scissor->h; - - [metalCommandBuffer->renderEncoder setScissorRect:metalScissor]; - } -} - static void METAL_BindVertexBuffers( SDL_GPUCommandBuffer *commandBuffer, Uint32 firstBinding, diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index d555fd8841..8fcea98422 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -996,10 +996,12 @@ typedef struct VulkanCommandBuffer VulkanTextureSubresource *depthStencilAttachmentSubresource; // may be NULL - // Viewport/scissor state + // Dynamic state VkViewport currentViewport; VkRect2D currentScissor; + float blendConstants[4]; + Uint8 stencilRef; // Resource bind state @@ -6425,7 +6427,9 @@ static SDL_GPUGraphicsPipeline *VULKAN_CreateGraphicsPipeline( static const VkDynamicState dynamicStates[] = { VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR + VK_DYNAMIC_STATE_SCISSOR, + VK_DYNAMIC_STATE_BLEND_CONSTANTS, + VK_DYNAMIC_STATE_STENCIL_REFERENCE }; VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo; @@ -6590,8 +6594,7 @@ static SDL_GPUGraphicsPipeline *VULKAN_CreateGraphicsPipeline( pipelineCreateInfo->depthStencilState.compareMask; frontStencilState.writeMask = pipelineCreateInfo->depthStencilState.writeMask; - frontStencilState.reference = - pipelineCreateInfo->depthStencilState.reference; + frontStencilState.reference = 0; backStencilState.failOp = SDLToVK_StencilOp[pipelineCreateInfo->depthStencilState.backStencilState.failOp]; backStencilState.passOp = SDLToVK_StencilOp[pipelineCreateInfo->depthStencilState.backStencilState.passOp]; @@ -6601,8 +6604,7 @@ static SDL_GPUGraphicsPipeline *VULKAN_CreateGraphicsPipeline( pipelineCreateInfo->depthStencilState.compareMask; backStencilState.writeMask = pipelineCreateInfo->depthStencilState.writeMask; - backStencilState.reference = - pipelineCreateInfo->depthStencilState.reference; + backStencilState.reference = 0; depthStencilStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; depthStencilStateCreateInfo.pNext = NULL; @@ -6644,14 +6646,10 @@ static SDL_GPUGraphicsPipeline *VULKAN_CreateGraphicsPipeline( pipelineCreateInfo->attachmentInfo.colorAttachmentCount; colorBlendStateCreateInfo.pAttachments = colorBlendAttachmentStates; - colorBlendStateCreateInfo.blendConstants[0] = - pipelineCreateInfo->blendConstants[0]; - colorBlendStateCreateInfo.blendConstants[1] = - pipelineCreateInfo->blendConstants[1]; - colorBlendStateCreateInfo.blendConstants[2] = - pipelineCreateInfo->blendConstants[2]; - colorBlendStateCreateInfo.blendConstants[3] = - pipelineCreateInfo->blendConstants[3]; + colorBlendStateCreateInfo.blendConstants[0] = 1.0f; + colorBlendStateCreateInfo.blendConstants[1] = 1.0f; + colorBlendStateCreateInfo.blendConstants[2] = 1.0f; + colorBlendStateCreateInfo.blendConstants[3] = 1.0f; // We don't support LogicOp, so this is easy. colorBlendStateCreateInfo.logicOpEnable = VK_FALSE; @@ -7530,6 +7528,56 @@ static void VULKAN_SetScissor( &vulkanCommandBuffer->currentScissor); } +static void VULKAN_INTERNAL_SetCurrentBlendConstants( + VulkanCommandBuffer *vulkanCommandBuffer, + SDL_FColor blendConstants) +{ + vulkanCommandBuffer->blendConstants[0] = blendConstants.r; + vulkanCommandBuffer->blendConstants[1] = blendConstants.g; + vulkanCommandBuffer->blendConstants[2] = blendConstants.b; + vulkanCommandBuffer->blendConstants[3] = blendConstants.a; +} + +static void VULKAN_SetBlendConstants( + SDL_GPUCommandBuffer *commandBuffer, + SDL_FColor blendConstants) +{ + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer *)commandBuffer; + VulkanRenderer *renderer = (VulkanRenderer *)vulkanCommandBuffer->renderer; + + VULKAN_INTERNAL_SetCurrentBlendConstants( + vulkanCommandBuffer, + blendConstants); + + renderer->vkCmdSetBlendConstants( + vulkanCommandBuffer->commandBuffer, + vulkanCommandBuffer->blendConstants); +} + +static void VULKAN_INTERNAL_SetCurrentStencilReference( + VulkanCommandBuffer *vulkanCommandBuffer, + Uint8 reference) +{ + vulkanCommandBuffer->stencilRef = reference; +} + +static void VULKAN_SetStencilReference( + SDL_GPUCommandBuffer *commandBuffer, + Uint8 reference) +{ + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer *)commandBuffer; + VulkanRenderer *renderer = (VulkanRenderer *)vulkanCommandBuffer->renderer; + + VULKAN_INTERNAL_SetCurrentStencilReference( + vulkanCommandBuffer, + reference); + + renderer->vkCmdSetStencilReference( + vulkanCommandBuffer->commandBuffer, + VK_STENCIL_FACE_FRONT_AND_BACK, + reference); +} + static void VULKAN_BindVertexSamplers( SDL_GPUCommandBuffer *commandBuffer, Uint32 firstSlot, @@ -7986,7 +8034,7 @@ static void VULKAN_BeginRenderPass( SDL_stack_free(clearValues); - // Set sensible default viewport state + // Set sensible default states defaultViewport.x = 0; defaultViewport.y = 0; @@ -8007,6 +8055,14 @@ static void VULKAN_BeginRenderPass( VULKAN_INTERNAL_SetCurrentScissor( vulkanCommandBuffer, &defaultScissor); + + VULKAN_INTERNAL_SetCurrentBlendConstants( + vulkanCommandBuffer, + (SDL_FColor){ 1.0f, 1.0f, 1.0f, 1.0f }); + + VULKAN_INTERNAL_SetCurrentStencilReference( + vulkanCommandBuffer, + 0); } static void VULKAN_BindGraphicsPipeline( @@ -8038,6 +8094,15 @@ static void VULKAN_BindGraphicsPipeline( 1, &vulkanCommandBuffer->currentScissor); + renderer->vkCmdSetBlendConstants( + vulkanCommandBuffer->commandBuffer, + vulkanCommandBuffer->blendConstants); + + renderer->vkCmdSetStencilReference( + vulkanCommandBuffer->commandBuffer, + VK_STENCIL_FACE_FRONT_AND_BACK, + vulkanCommandBuffer->stencilRef); + // Acquire uniform buffers if necessary for (Uint32 i = 0; i < pipeline->resourceLayout.vertexUniformBufferCount; i += 1) { if (vulkanCommandBuffer->vertexUniformBuffers[i] == NULL) {