|
86 | 86 | uint64_t uHeap; |
87 | 87 | MTLTextureDescriptor* ptTextureDescriptor; |
88 | 88 | bool bOriginalView; |
| 89 | + bool bSwapchain; |
89 | 90 | } plMetalTexture; |
90 | 91 |
|
91 | 92 | typedef struct _plMetalSampler |
|
143 | 144 | plTempAllocator tTempAllocator; |
144 | 145 | CAMetalLayer* pMetalLayer; |
145 | 146 |
|
146 | | - bool bEncoderActive; |
| 147 | + bool bComputeEncoderActive; |
| 148 | + bool bRenderEncoderActive; |
147 | 149 | } plGraphics; |
148 | 150 |
|
149 | 151 | typedef struct _plDevice |
|
211 | 213 |
|
212 | 214 | // render encoder |
213 | 215 | id<MTL4RenderCommandEncoder> tRenderEncoder; |
| 216 | + MTL4RenderPassDescriptor* ptRenderPassDescriptor; |
214 | 217 |
|
215 | 218 | id<MTL4ArgumentTable> tArgumentTable; |
216 | 219 | id<MTLResidencySet> tResidencySet; |
|
1626 | 1629 | ptTexture->tView.uMips = 1; |
1627 | 1630 | ptTexture->tView.uLayerCount = 1; |
1628 | 1631 | ptTexture->tView.tTexture = tHandle; |
| 1632 | + ptTexture->tView.tTexture = tHandle; |
1629 | 1633 | ptTexture->tView.pcDebugName = "swapchain dummy image view"; |
1630 | 1634 | } |
1631 | 1635 | ptSwap->tInfo.uWidth = (uint32_t)gptIO->tMainViewportSize.x; |
|
1763 | 1767 |
|
1764 | 1768 | plTextureHandle tTexture = ptSwapchain->sbtSwapchainTextureViews[gptGraphics->uCurrentFrameIndex]; |
1765 | 1769 | ptDevice->sbtTexturesHot[tTexture.uIndex].tTexture = ptSwapchain->tCurrentDrawable.texture; |
| 1770 | + ptDevice->sbtTexturesHot[tTexture.uIndex].bSwapchain = true; |
1766 | 1771 |
|
1767 | 1772 | PL_PROFILE_END_SAMPLE_API(gptProfile, 0); |
1768 | 1773 | return true; |
|
1878 | 1883 | pl_graphics_begin_render_pass(plCommandBuffer* ptCmdBuffer, plRenderInfo tInfo, const plPassResources* ptResources) |
1879 | 1884 | { |
1880 | 1885 | plDevice* ptDevice = ptCmdBuffer->ptDevice; |
1881 | | - gptGraphics->bEncoderActive = true; |
| 1886 | + gptGraphics->bRenderEncoderActive = true; |
1882 | 1887 |
|
1883 | | - MTL4RenderPassDescriptor* ptRenderPassDescriptor = [MTL4RenderPassDescriptor new]; |
| 1888 | + ptDevice->ptRenderPassDescriptor = [MTL4RenderPassDescriptor new]; |
1884 | 1889 |
|
1885 | 1890 | for(uint32_t i = 0; i < PL_MAX_RENDER_TARGETS; i++) |
1886 | 1891 | { |
1887 | 1892 | if(!pl_graphics_is_texture_valid(ptDevice, tInfo.atColorAttachments[i].tTexture)) |
1888 | 1893 | break; |
1889 | 1894 |
|
1890 | | - ptRenderPassDescriptor.colorAttachments[i].texture = ptDevice->sbtTexturesHot[tInfo.atColorAttachments[i].tTexture.uIndex].tTexture; |
1891 | | - ptRenderPassDescriptor.colorAttachments[i].loadAction = pl__metal_load_op(tInfo.atColorAttachments[i].tLoadOp); |
1892 | | - ptRenderPassDescriptor.colorAttachments[i].storeAction = pl__metal_store_op(tInfo.atColorAttachments[i].tStoreOp); |
1893 | | - ptRenderPassDescriptor.colorAttachments[i].slice = ptDevice->sbtTexturesCold[tInfo.atColorAttachments[i].tTexture.uIndex].tView.uBaseLayer; |
| 1895 | + ptDevice->ptRenderPassDescriptor.colorAttachments[i].texture = ptDevice->sbtTexturesHot[tInfo.atColorAttachments[i].tTexture.uIndex].tTexture; |
| 1896 | + ptDevice->ptRenderPassDescriptor.colorAttachments[i].loadAction = pl__metal_load_op(tInfo.atColorAttachments[i].tLoadOp); |
| 1897 | + ptDevice->ptRenderPassDescriptor.colorAttachments[i].storeAction = pl__metal_store_op(tInfo.atColorAttachments[i].tStoreOp); |
| 1898 | + ptDevice->ptRenderPassDescriptor.colorAttachments[i].slice = ptDevice->sbtTexturesCold[tInfo.atColorAttachments[i].tTexture.uIndex].tView.uBaseLayer; |
1894 | 1899 |
|
1895 | | - ptRenderPassDescriptor.colorAttachments[i].clearColor = MTLClearColorMake( |
| 1900 | + ptDevice->ptRenderPassDescriptor.colorAttachments[i].clearColor = MTLClearColorMake( |
1896 | 1901 | tInfo.atColorAttachments[i].tClearColor.r, |
1897 | 1902 | tInfo.atColorAttachments[i].tClearColor.g, |
1898 | 1903 | tInfo.atColorAttachments[i].tClearColor.b, |
1899 | 1904 | tInfo.atColorAttachments[i].tClearColor.a); |
1900 | 1905 |
|
1901 | 1906 | if(tInfo.atColorAttachments[i].tResolveTexture.uIndex > 0) |
1902 | 1907 | { |
1903 | | - ptRenderPassDescriptor.colorAttachments[i].resolveTexture = ptDevice->sbtTexturesHot[tInfo.atColorAttachments[i].tResolveTexture.uIndex].tTexture; |
1904 | | - ptRenderPassDescriptor.colorAttachments[i].storeAction = MTLStoreActionMultisampleResolve; |
| 1908 | + ptDevice->ptRenderPassDescriptor.colorAttachments[i].resolveTexture = ptDevice->sbtTexturesHot[tInfo.atColorAttachments[i].tResolveTexture.uIndex].tTexture; |
| 1909 | + ptDevice->ptRenderPassDescriptor.colorAttachments[i].storeAction = MTLStoreActionMultisampleResolve; |
1905 | 1910 |
|
1906 | 1911 | } |
1907 | 1912 | } |
1908 | 1913 |
|
1909 | 1914 | if(pl_graphics_is_texture_valid(ptDevice, tInfo.tDepthAttachment.tTexture)) |
1910 | 1915 | { |
1911 | | - ptRenderPassDescriptor.depthAttachment.loadAction = pl__metal_load_op(tInfo.tDepthAttachment.tLoadOp); |
1912 | | - ptRenderPassDescriptor.depthAttachment.storeAction = pl__metal_store_op(tInfo.tDepthAttachment.tStoreOp); |
1913 | | - ptRenderPassDescriptor.depthAttachment.clearDepth = tInfo.tDepthAttachment.fClearZ; |
1914 | | - ptRenderPassDescriptor.depthAttachment.texture = ptDevice->sbtTexturesHot[tInfo.tDepthAttachment.tTexture.uIndex].tTexture; |
1915 | | - ptRenderPassDescriptor.depthAttachment.slice = ptDevice->sbtTexturesCold[tInfo.tDepthAttachment.tTexture.uIndex].tView.uBaseLayer; |
| 1916 | + ptDevice->ptRenderPassDescriptor.depthAttachment.loadAction = pl__metal_load_op(tInfo.tDepthAttachment.tLoadOp); |
| 1917 | + ptDevice->ptRenderPassDescriptor.depthAttachment.storeAction = pl__metal_store_op(tInfo.tDepthAttachment.tStoreOp); |
| 1918 | + ptDevice->ptRenderPassDescriptor.depthAttachment.clearDepth = tInfo.tDepthAttachment.fClearZ; |
| 1919 | + ptDevice->ptRenderPassDescriptor.depthAttachment.texture = ptDevice->sbtTexturesHot[tInfo.tDepthAttachment.tTexture.uIndex].tTexture; |
| 1920 | + ptDevice->ptRenderPassDescriptor.depthAttachment.slice = ptDevice->sbtTexturesCold[tInfo.tDepthAttachment.tTexture.uIndex].tView.uBaseLayer; |
1916 | 1921 | } |
1917 | 1922 |
|
1918 | 1923 | if(pl_graphics_is_texture_valid(ptDevice, tInfo.tStencilAttachment.tTexture)) |
1919 | 1924 | { |
1920 | | - ptRenderPassDescriptor.stencilAttachment.loadAction = pl__metal_load_op(tInfo.tStencilAttachment.tLoadOp); |
1921 | | - ptRenderPassDescriptor.stencilAttachment.storeAction = pl__metal_store_op(tInfo.tStencilAttachment.tStoreOp); |
1922 | | - ptRenderPassDescriptor.stencilAttachment.clearStencil = tInfo.tStencilAttachment.uClearStencil; |
1923 | | - ptRenderPassDescriptor.stencilAttachment.texture = ptDevice->sbtTexturesHot[tInfo.tStencilAttachment.tTexture.uIndex].tTexture; |
1924 | | - ptRenderPassDescriptor.stencilAttachment.slice = ptDevice->sbtTexturesCold[tInfo.tStencilAttachment.tTexture.uIndex].tView.uBaseLayer; |
| 1925 | + ptDevice->ptRenderPassDescriptor.stencilAttachment.loadAction = pl__metal_load_op(tInfo.tStencilAttachment.tLoadOp); |
| 1926 | + ptDevice->ptRenderPassDescriptor.stencilAttachment.storeAction = pl__metal_store_op(tInfo.tStencilAttachment.tStoreOp); |
| 1927 | + ptDevice->ptRenderPassDescriptor.stencilAttachment.clearStencil = tInfo.tStencilAttachment.uClearStencil; |
| 1928 | + ptDevice->ptRenderPassDescriptor.stencilAttachment.texture = ptDevice->sbtTexturesHot[tInfo.tStencilAttachment.tTexture.uIndex].tTexture; |
| 1929 | + ptDevice->ptRenderPassDescriptor.stencilAttachment.slice = ptDevice->sbtTexturesCold[tInfo.tStencilAttachment.tTexture.uIndex].tView.uBaseLayer; |
1925 | 1930 | } |
1926 | 1931 |
|
1927 | | - ptDevice->tRenderEncoder = [ptCmdBuffer->tCmdBuffer4 renderCommandEncoderWithDescriptor:ptRenderPassDescriptor]; |
| 1932 | + ptDevice->tRenderEncoder = [ptCmdBuffer->tCmdBuffer4 renderCommandEncoderWithDescriptor:ptDevice->ptRenderPassDescriptor]; |
1928 | 1933 | // ptDevice->tRenderEncoder.label = [NSString stringWithUTF8String:ptRenderPass->tDesc.pcDebugName]; |
1929 | 1934 |
|
1930 | | - [ptRenderPassDescriptor release]; |
1931 | | - ptRenderPassDescriptor = nil; |
| 1935 | + for(uint32_t i = 0; i < PL_MAX_RENDER_TARGETS; i++) |
| 1936 | + { |
| 1937 | + if(!pl_graphics_is_texture_valid(ptDevice, tInfo.atColorAttachments[i].tTexture)) |
| 1938 | + break; |
| 1939 | + |
| 1940 | + ptDevice->ptRenderPassDescriptor.colorAttachments[i].loadAction = MTLLoadActionLoad; |
| 1941 | + } |
| 1942 | + |
| 1943 | + if(pl_graphics_is_texture_valid(ptDevice, tInfo.tDepthAttachment.tTexture)) |
| 1944 | + { |
| 1945 | + ptDevice->ptRenderPassDescriptor.depthAttachment.loadAction = MTLLoadActionLoad; |
| 1946 | + } |
| 1947 | + |
| 1948 | + if(pl_graphics_is_texture_valid(ptDevice, tInfo.tStencilAttachment.tTexture)) |
| 1949 | + { |
| 1950 | + ptDevice->ptRenderPassDescriptor.stencilAttachment.loadAction = MTLLoadActionLoad; |
| 1951 | + } |
1932 | 1952 | } |
1933 | 1953 |
|
1934 | 1954 | void |
|
1937 | 1957 | plDevice* ptDevice = ptCmdBuffer->ptDevice; |
1938 | 1958 | [ptDevice->tRenderEncoder endEncoding]; |
1939 | 1959 | ptDevice->tRenderEncoder = nil; |
1940 | | - gptGraphics->bEncoderActive = false; |
| 1960 | + gptGraphics->bRenderEncoderActive = false; |
| 1961 | + [ptDevice->ptRenderPassDescriptor release]; |
| 1962 | + ptDevice->ptRenderPassDescriptor = nil; |
1941 | 1963 | } |
1942 | 1964 |
|
1943 | 1965 | void |
|
2015 | 2037 | { |
2016 | 2038 | plDevice* ptDevice = ptCmdBuffer->ptDevice; |
2017 | 2039 | ptDevice->tComputeEncoder = [ptCmdBuffer->tCmdBuffer4 computeCommandEncoder]; |
| 2040 | + gptGraphics->bComputeEncoderActive = true; |
2018 | 2041 | } |
2019 | 2042 |
|
2020 | 2043 | void |
|
2024 | 2047 | [ptDevice->tComputeEncoder endEncoding]; |
2025 | 2048 | // [ptDevice->tComputeEncoder release]; |
2026 | 2049 | ptDevice->tComputeEncoder = nil; |
| 2050 | + gptGraphics->bComputeEncoderActive = false; |
2027 | 2051 | } |
2028 | 2052 |
|
2029 | 2053 | void |
2030 | 2054 | pl_graphics_intra_pass_barrier(plCommandBuffer* ptCmdBuffer, plPipelineStageFlags tSrcStages, plPipelineStageFlags tDstStages, plBarrierScope tScope) |
2031 | 2055 | { |
2032 | 2056 | plDevice* ptDevice = ptCmdBuffer->ptDevice; |
2033 | | - PL_ASSERT(gptGraphics->bEncoderActive); |
| 2057 | + PL_ASSERT(gptGraphics->bRenderEncoderActive || gptGraphics->bComputeEncoderActive); |
2034 | 2058 | PL_ASSERT(tSrcStages != 0); |
2035 | 2059 | PL_ASSERT(tDstStages != 0); |
2036 | 2060 |
|
|
2050 | 2074 | if(tDstStages & PL_PIPELINE_STAGE_VERTEX) tDstStage |= MTLStageVertex; |
2051 | 2075 | if(tDstStages & PL_PIPELINE_STAGE_FRAGMENT) tDstStage |= MTLStageFragment; |
2052 | 2076 |
|
2053 | | - [ptDevice->tComputeEncoder barrierAfterEncoderStages:tSrcStage beforeEncoderStages:tDstStage visibilityOptions:tOptions]; |
| 2077 | + if(gptGraphics->bComputeEncoderActive) |
| 2078 | + [ptDevice->tComputeEncoder barrierAfterEncoderStages:tSrcStage beforeEncoderStages:tDstStage visibilityOptions:tOptions]; |
| 2079 | + else if(gptGraphics->bRenderEncoderActive) |
| 2080 | + { |
| 2081 | + if(tSrcStage & MTLStageFragment) |
| 2082 | + { |
| 2083 | + [ptDevice->tRenderEncoder barrierAfterStages:tSrcStage beforeQueueStages:tDstStage visibilityOptions:tOptions]; |
| 2084 | + [ptDevice->tRenderEncoder endEncoding]; |
| 2085 | + ptDevice->tRenderEncoder = nil; |
| 2086 | + ptDevice->tRenderEncoder = [ptCmdBuffer->tCmdBuffer4 renderCommandEncoderWithDescriptor:ptDevice->ptRenderPassDescriptor]; |
| 2087 | + [ptDevice->tRenderEncoder barrierAfterQueueStages:tSrcStage beforeStages:tDstStage visibilityOptions:tOptions]; |
| 2088 | + |
| 2089 | + } |
| 2090 | + else |
| 2091 | + [ptDevice->tComputeEncoder barrierAfterEncoderStages:tSrcStage beforeEncoderStages:tDstStage visibilityOptions:tOptions]; |
| 2092 | + } |
| 2093 | +} |
| 2094 | + |
| 2095 | +MTL4RenderPassDescriptor* |
| 2096 | +pl_graphics_get_metal_render_pass_descriptor(plCommandBuffer* ptCmdBuffer) |
| 2097 | +{ |
| 2098 | + plDevice* ptDevice = ptCmdBuffer->ptDevice; |
| 2099 | + return ptDevice->ptRenderPassDescriptor; |
2054 | 2100 | } |
2055 | 2101 |
|
2056 | 2102 | void |
2057 | 2103 | pl_graphics_consumer_barrier(plCommandBuffer* ptCmdBuffer, plPipelineStageFlags tSrcStages, plPipelineStageFlags tDstStages, plBarrierScope tScope) |
2058 | 2104 | { |
2059 | 2105 | plDevice* ptDevice = ptCmdBuffer->ptDevice; |
2060 | | - PL_ASSERT(gptGraphics->bEncoderActive); |
| 2106 | + PL_ASSERT(gptGraphics->bRenderEncoderActive || gptGraphics->bComputeEncoderActive); |
2061 | 2107 | PL_ASSERT(tSrcStages != 0); |
2062 | 2108 | PL_ASSERT(tDstStages != 0); |
2063 | 2109 |
|
|
2077 | 2123 | if(tDstStages & PL_PIPELINE_STAGE_VERTEX) tDstStage |= MTLStageVertex; |
2078 | 2124 | if(tDstStages & PL_PIPELINE_STAGE_FRAGMENT) tDstStage |= MTLStageFragment; |
2079 | 2125 |
|
2080 | | - [ptDevice->tRenderEncoder barrierAfterQueueStages:tSrcStage beforeStages:tDstStage visibilityOptions:tOptions]; |
| 2126 | + if(gptGraphics->bComputeEncoderActive) |
| 2127 | + [ptDevice->tComputeEncoder barrierAfterQueueStages:tSrcStage beforeStages:tDstStage visibilityOptions:tOptions]; |
| 2128 | + else if(gptGraphics->bRenderEncoderActive) |
| 2129 | + [ptDevice->tRenderEncoder barrierAfterQueueStages:tSrcStage beforeStages:tDstStage visibilityOptions:tOptions]; |
2081 | 2130 | } |
2082 | 2131 |
|
2083 | 2132 | void |
2084 | 2133 | pl_graphics_producer_barrier(plCommandBuffer* ptCmdBuffer, plPipelineStageFlags tSrcStages, plPipelineStageFlags tDstStages, plBarrierScope tScope) |
2085 | 2134 | { |
2086 | 2135 | plDevice* ptDevice = ptCmdBuffer->ptDevice; |
2087 | | - PL_ASSERT(gptGraphics->bEncoderActive); |
| 2136 | + PL_ASSERT(gptGraphics->bRenderEncoderActive || gptGraphics->bComputeEncoderActive); |
2088 | 2137 | PL_ASSERT(tSrcStages != 0); |
2089 | 2138 | PL_ASSERT(tDstStages != 0); |
2090 | 2139 |
|
|
2104 | 2153 | if(tDstStages & PL_PIPELINE_STAGE_VERTEX) tDstStage |= MTLStageVertex; |
2105 | 2154 | if(tDstStages & PL_PIPELINE_STAGE_FRAGMENT) tDstStage |= MTLStageFragment; |
2106 | 2155 |
|
2107 | | - [ptDevice->tRenderEncoder barrierAfterStages:tSrcStage beforeQueueStages:tDstStage visibilityOptions:tOptions]; |
| 2156 | + if(gptGraphics->bComputeEncoderActive) |
| 2157 | + [ptDevice->tComputeEncoder barrierAfterStages:tSrcStage beforeQueueStages:tDstStage visibilityOptions:tOptions]; |
| 2158 | + else if(gptGraphics->bRenderEncoderActive) |
| 2159 | + [ptDevice->tRenderEncoder barrierAfterStages:tSrcStage beforeQueueStages:tDstStage visibilityOptions:tOptions]; |
2108 | 2160 | } |
2109 | 2161 |
|
2110 | 2162 | void |
|
3053 | 3105 | for(uint32_t i = 0; i < pl_sb_size(ptGarbage->sbtTextures); i++) |
3054 | 3106 | { |
3055 | 3107 | const uint16_t uTextureIndex = ptGarbage->sbtTextures[i].uIndex; |
3056 | | - if( uSignaledValue > ptDevice->sbtTexturesCold[uTextureIndex]._uFrameBoundaryValueForDeletion + 1) |
| 3108 | + if( uSignaledValue > ptDevice->sbtTexturesCold[uTextureIndex]._uFrameBoundaryValueForDeletion + 1 && !ptDevice->sbtTexturesHot[uTextureIndex].bSwapchain) |
3057 | 3109 | { |
3058 | 3110 | plMetalTexture* ptMetalTexture = &ptDevice->sbtTexturesHot[uTextureIndex]; |
3059 | 3111 | [ptMetalTexture->tTexture release]; |
|
0 commit comments