mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-12-01 01:11:46 +00:00
Merge pull request #14162 from unknownbrackets/thin3d-autoref
Draw: Auto ref/release bound textures/samplers
This commit is contained in:
commit
880b3432f3
@ -185,7 +185,7 @@ private:
|
||||
ID3D11Texture2D *bbDepthStencilTex_ = nullptr;
|
||||
ID3D11DepthStencilView *bbDepthStencilView_ = nullptr;
|
||||
|
||||
Framebuffer *curRenderTarget_ = nullptr;
|
||||
AutoRef<Framebuffer> curRenderTarget_;
|
||||
ID3D11RenderTargetView *curRenderTargetView_ = nullptr;
|
||||
ID3D11DepthStencilView *curDepthStencilView_ = nullptr;
|
||||
// Needed to rotate stencil/viewport rectangles properly
|
||||
@ -194,12 +194,12 @@ private:
|
||||
int curRTWidth_ = 0;
|
||||
int curRTHeight_ = 0;
|
||||
|
||||
D3D11Pipeline *curPipeline_ = nullptr;
|
||||
AutoRef<D3D11Pipeline> curPipeline_;
|
||||
DeviceCaps caps_{};
|
||||
|
||||
D3D11BlendState *curBlend_ = nullptr;
|
||||
D3D11DepthStencilState *curDepth_ = nullptr;
|
||||
D3D11RasterState *curRaster_ = nullptr;
|
||||
AutoRef<D3D11BlendState> curBlend_;
|
||||
AutoRef<D3D11DepthStencilState> curDepth_;
|
||||
AutoRef<D3D11RasterState> curRaster_;
|
||||
ID3D11InputLayout *curInputLayout_ = nullptr;
|
||||
ID3D11VertexShader *curVS_ = nullptr;
|
||||
ID3D11PixelShader *curPS_ = nullptr;
|
||||
@ -696,14 +696,6 @@ public:
|
||||
class D3D11Pipeline : public Pipeline {
|
||||
public:
|
||||
~D3D11Pipeline() {
|
||||
if (input)
|
||||
input->Release();
|
||||
if (blend)
|
||||
blend->Release();
|
||||
if (depth)
|
||||
depth->Release();
|
||||
if (raster)
|
||||
raster->Release();
|
||||
if (il)
|
||||
il->Release();
|
||||
if (dynamicUniforms)
|
||||
@ -716,11 +708,11 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
D3D11InputLayout *input = nullptr;
|
||||
AutoRef<D3D11InputLayout> input;
|
||||
ID3D11InputLayout *il = nullptr;
|
||||
D3D11BlendState *blend = nullptr;
|
||||
D3D11DepthStencilState *depth = nullptr;
|
||||
D3D11RasterState *raster = nullptr;
|
||||
AutoRef<D3D11BlendState> blend;
|
||||
AutoRef<D3D11DepthStencilState> depth;
|
||||
AutoRef<D3D11RasterState> raster;
|
||||
ID3D11VertexShader *vs = nullptr;
|
||||
ID3D11PixelShader *ps = nullptr;
|
||||
ID3D11GeometryShader *gs = nullptr;
|
||||
@ -975,12 +967,6 @@ Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
|
||||
dPipeline->depth = (D3D11DepthStencilState *)desc.depthStencil;
|
||||
dPipeline->input = (D3D11InputLayout *)desc.inputLayout;
|
||||
dPipeline->raster = (D3D11RasterState *)desc.raster;
|
||||
dPipeline->blend->AddRef();
|
||||
dPipeline->depth->AddRef();
|
||||
if (dPipeline->input) {
|
||||
dPipeline->input->AddRef();
|
||||
}
|
||||
dPipeline->raster->AddRef();
|
||||
dPipeline->topology = primToD3D11[(int)desc.prim];
|
||||
if (desc.uniformDesc) {
|
||||
dPipeline->dynamicUniformsSize = desc.uniformDesc->uniformBufferSize;
|
||||
@ -1026,7 +1012,7 @@ Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
|
||||
}
|
||||
|
||||
// Can finally create the input layout
|
||||
if (dPipeline->input) {
|
||||
if (dPipeline->input != nullptr) {
|
||||
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)) {
|
||||
@ -1104,7 +1090,7 @@ void D3D11DrawContext::ApplyCurrentState() {
|
||||
curTopology_ = curPipeline_->topology;
|
||||
}
|
||||
|
||||
if (curPipeline_->input) {
|
||||
if (curPipeline_->input != nullptr) {
|
||||
int numVBs = (int)curPipeline_->input->strides.size();
|
||||
context_->IASetVertexBuffers(0, numVBs, nextVertexBuffers_, (UINT *)curPipeline_->input->strides.data(), (UINT *)nextVertexBufferOffsets_);
|
||||
}
|
||||
@ -1378,13 +1364,13 @@ void D3D11DrawContext::Clear(int mask, uint32_t colorval, float depthVal, int st
|
||||
void D3D11DrawContext::BeginFrame() {
|
||||
context_->OMSetRenderTargets(1, &curRenderTargetView_, curDepthStencilView_);
|
||||
|
||||
if (curBlend_) {
|
||||
if (curBlend_ != nullptr) {
|
||||
context_->OMSetBlendState(curBlend_->bs, blendFactor_, 0xFFFFFFFF);
|
||||
}
|
||||
if (curDepth_) {
|
||||
if (curDepth_ != nullptr) {
|
||||
context_->OMSetDepthStencilState(curDepth_->dss, stencilRef_);
|
||||
}
|
||||
if (curRaster_) {
|
||||
if (curRaster_ != nullptr) {
|
||||
context_->RSSetState(curRaster_->rs);
|
||||
}
|
||||
context_->IASetInputLayout(curInputLayout_);
|
||||
@ -1394,7 +1380,7 @@ void D3D11DrawContext::BeginFrame() {
|
||||
if (curTopology_ != D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED) {
|
||||
context_->IASetPrimitiveTopology(curTopology_);
|
||||
}
|
||||
if (curPipeline_) {
|
||||
if (curPipeline_ != nullptr) {
|
||||
context_->IASetVertexBuffers(0, 1, nextVertexBuffers_, (UINT *)curPipeline_->input->strides.data(), (UINT *)nextVertexBufferOffsets_);
|
||||
context_->IASetIndexBuffer(nextIndexBuffer_, DXGI_FORMAT_R16_UINT, nextIndexBufferOffset_);
|
||||
if (curPipeline_->dynamicUniforms) {
|
||||
|
@ -273,10 +273,6 @@ class D3D9Pipeline : public Pipeline {
|
||||
public:
|
||||
D3D9Pipeline() {}
|
||||
~D3D9Pipeline() {
|
||||
if (depthStencil) depthStencil->Release();
|
||||
if (blend) blend->Release();
|
||||
if (raster) raster->Release();
|
||||
if (inputLayout) inputLayout->Release();
|
||||
}
|
||||
bool RequiresBuffer() override {
|
||||
return false;
|
||||
@ -287,10 +283,10 @@ public:
|
||||
|
||||
D3DPRIMITIVETYPE prim;
|
||||
int primDivisor;
|
||||
D3D9InputLayout *inputLayout = nullptr;
|
||||
D3D9DepthStencilState *depthStencil = nullptr;
|
||||
D3D9BlendState *blend = nullptr;
|
||||
D3D9RasterState *raster = nullptr;
|
||||
AutoRef<D3D9InputLayout> inputLayout;
|
||||
AutoRef<D3D9DepthStencilState> depthStencil;
|
||||
AutoRef<D3D9BlendState> blend;
|
||||
AutoRef<D3D9RasterState> raster;
|
||||
UniformBufferDesc dynamicUniforms;
|
||||
|
||||
void Apply(LPDIRECT3DDEVICE9 device);
|
||||
@ -610,12 +606,12 @@ private:
|
||||
DeviceCaps caps_{};
|
||||
|
||||
// Bound state
|
||||
D3D9Pipeline *curPipeline_ = nullptr;
|
||||
D3D9Buffer *curVBuffers_[4]{};
|
||||
AutoRef<D3D9Pipeline> curPipeline_;
|
||||
AutoRef<D3D9Buffer> curVBuffers_[4];
|
||||
int curVBufferOffsets_[4]{};
|
||||
D3D9Buffer *curIBuffer_ = nullptr;
|
||||
AutoRef<D3D9Buffer> curIBuffer_;
|
||||
int curIBufferOffset_ = 0;
|
||||
Framebuffer *curRenderTarget_ = nullptr;
|
||||
AutoRef<Framebuffer> curRenderTarget_;
|
||||
|
||||
// Framebuffer state
|
||||
LPDIRECT3DSURFACE9 deviceRTsurf = 0;
|
||||
@ -713,10 +709,6 @@ Pipeline *D3D9Context::CreateGraphicsPipeline(const PipelineDesc &desc) {
|
||||
pipeline->blend = (D3D9BlendState *)desc.blend;
|
||||
pipeline->raster = (D3D9RasterState *)desc.raster;
|
||||
pipeline->inputLayout = (D3D9InputLayout *)desc.inputLayout;
|
||||
pipeline->depthStencil->AddRef();
|
||||
pipeline->blend->AddRef();
|
||||
pipeline->raster->AddRef();
|
||||
pipeline->inputLayout->AddRef();
|
||||
if (desc.uniformDesc)
|
||||
pipeline->dynamicUniforms = *desc.uniformDesc;
|
||||
return pipeline;
|
||||
|
@ -281,10 +281,6 @@ public:
|
||||
iter->Release();
|
||||
}
|
||||
if (program_) render_->DeleteProgram(program_);
|
||||
if (depthStencil) depthStencil->Release();
|
||||
if (blend) blend->Release();
|
||||
if (raster) raster->Release();
|
||||
if (inputLayout) inputLayout->Release();
|
||||
}
|
||||
|
||||
bool LinkShaders();
|
||||
@ -295,10 +291,10 @@ public:
|
||||
|
||||
GLuint prim = 0;
|
||||
std::vector<OpenGLShaderModule *> shaders;
|
||||
OpenGLInputLayout *inputLayout = nullptr;
|
||||
OpenGLDepthStencilState *depthStencil = nullptr;
|
||||
OpenGLBlendState *blend = nullptr;
|
||||
OpenGLRasterState *raster = nullptr;
|
||||
AutoRef<OpenGLInputLayout> inputLayout;
|
||||
AutoRef<OpenGLDepthStencilState> depthStencil;
|
||||
AutoRef<OpenGLBlendState> blend;
|
||||
AutoRef<OpenGLRasterState> raster;
|
||||
|
||||
// TODO: Optimize by getting the locations first and putting in a custom struct
|
||||
UniformBufferDesc dynamicUniforms;
|
||||
@ -406,7 +402,7 @@ public:
|
||||
void BindPipeline(Pipeline *pipeline) override;
|
||||
void BindVertexBuffers(int start, int count, Buffer **buffers, int *offsets) override {
|
||||
for (int i = 0; i < count; i++) {
|
||||
curVBuffers_[i + start] = (OpenGLBuffer *)buffers[i];
|
||||
curVBuffers_[i + start] = (OpenGLBuffer *)buffers[i];
|
||||
curVBufferOffsets_[i + start] = offsets ? offsets[i] : 0;
|
||||
}
|
||||
}
|
||||
@ -482,17 +478,17 @@ private:
|
||||
DeviceCaps caps_{};
|
||||
|
||||
// Bound state
|
||||
OpenGLSamplerState *boundSamplers_[MAX_TEXTURE_SLOTS]{};
|
||||
AutoRef<OpenGLSamplerState> boundSamplers_[MAX_TEXTURE_SLOTS];
|
||||
// Point to GLRTexture directly because they can point to the textures
|
||||
// in framebuffers too (which also can be bound).
|
||||
const GLRTexture *boundTextures_[MAX_TEXTURE_SLOTS]{};
|
||||
|
||||
OpenGLPipeline *curPipeline_ = nullptr;
|
||||
OpenGLBuffer *curVBuffers_[4]{};
|
||||
AutoRef<OpenGLPipeline> curPipeline_;
|
||||
AutoRef<OpenGLBuffer> curVBuffers_[4]{};
|
||||
int curVBufferOffsets_[4]{};
|
||||
OpenGLBuffer *curIBuffer_ = nullptr;
|
||||
AutoRef<OpenGLBuffer> curIBuffer_;
|
||||
int curIBufferOffset_ = 0;
|
||||
Framebuffer *curRenderTarget_ = nullptr;
|
||||
AutoRef<Framebuffer> curRenderTarget_;
|
||||
|
||||
uint8_t stencilRef_ = 0;
|
||||
|
||||
@ -1069,12 +1065,6 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
|
||||
pipeline->blend = (OpenGLBlendState *)desc.blend;
|
||||
pipeline->raster = (OpenGLRasterState *)desc.raster;
|
||||
pipeline->inputLayout = (OpenGLInputLayout *)desc.inputLayout;
|
||||
pipeline->depthStencil->AddRef();
|
||||
pipeline->blend->AddRef();
|
||||
pipeline->raster->AddRef();
|
||||
if (pipeline->inputLayout) {
|
||||
pipeline->inputLayout->AddRef();
|
||||
}
|
||||
return pipeline;
|
||||
} else {
|
||||
ERROR_LOG(G3D, "Failed to create pipeline - shaders failed to link");
|
||||
@ -1210,7 +1200,7 @@ 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");
|
||||
_dbg_assert_msg_(curVBuffers_[0] != nullptr, "Can't call Draw without a vertex buffer");
|
||||
ApplySamplers();
|
||||
if (curPipeline_->inputLayout) {
|
||||
renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0]);
|
||||
@ -1219,8 +1209,8 @@ void OpenGLContext::Draw(int vertexCount, int offset) {
|
||||
}
|
||||
|
||||
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");
|
||||
_dbg_assert_msg_(curVBuffers_[0] != nullptr, "Can't call DrawIndexed without a vertex buffer");
|
||||
_dbg_assert_msg_(curIBuffer_ != nullptr, "Can't call DrawIndexed without an index buffer");
|
||||
ApplySamplers();
|
||||
if (curPipeline_->inputLayout) {
|
||||
renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0]);
|
||||
@ -1230,7 +1220,7 @@ void OpenGLContext::DrawIndexed(int vertexCount, int offset) {
|
||||
}
|
||||
|
||||
void OpenGLContext::DrawUP(const void *vdata, int vertexCount) {
|
||||
_assert_(curPipeline_->inputLayout);
|
||||
_assert_(curPipeline_->inputLayout != nullptr);
|
||||
int stride = curPipeline_->inputLayout->stride;
|
||||
size_t dataSize = stride * vertexCount;
|
||||
|
||||
|
@ -511,16 +511,16 @@ private:
|
||||
|
||||
VulkanTexture *nullTexture_ = nullptr;
|
||||
|
||||
VKPipeline *curPipeline_ = nullptr;
|
||||
VKBuffer *curVBuffers_[4]{};
|
||||
AutoRef<VKPipeline> curPipeline_;
|
||||
AutoRef<VKBuffer> curVBuffers_[4];
|
||||
int curVBufferOffsets_[4]{};
|
||||
VKBuffer *curIBuffer_ = nullptr;
|
||||
AutoRef<VKBuffer> curIBuffer_;
|
||||
int curIBufferOffset_ = 0;
|
||||
|
||||
VkDescriptorSetLayout descriptorSetLayout_ = VK_NULL_HANDLE;
|
||||
VkPipelineLayout pipelineLayout_ = VK_NULL_HANDLE;
|
||||
VkPipelineCache pipelineCache_ = VK_NULL_HANDLE;
|
||||
Framebuffer *curFramebuffer_ = nullptr;
|
||||
AutoRef<Framebuffer> curFramebuffer_;
|
||||
|
||||
VkDevice device_;
|
||||
VkQueue queue_;
|
||||
@ -529,8 +529,8 @@ private:
|
||||
enum {
|
||||
MAX_FRAME_COMMAND_BUFFERS = 256,
|
||||
};
|
||||
VKTexture *boundTextures_[MAX_BOUND_TEXTURES]{};
|
||||
VKSamplerState *boundSamplers_[MAX_BOUND_TEXTURES]{};
|
||||
AutoRef<VKTexture> boundTextures_[MAX_BOUND_TEXTURES];
|
||||
AutoRef<VKSamplerState> boundSamplers_[MAX_BOUND_TEXTURES];
|
||||
VkImageView boundImageView_[MAX_BOUND_TEXTURES]{};
|
||||
|
||||
struct FrameData {
|
||||
|
@ -335,6 +335,46 @@ private:
|
||||
int refcount_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct AutoRef {
|
||||
AutoRef() {
|
||||
}
|
||||
explicit AutoRef(T *p) {
|
||||
ptr = p;
|
||||
if (ptr)
|
||||
ptr->AddRef();
|
||||
}
|
||||
AutoRef(const AutoRef<T> &p) {
|
||||
*this = p.ptr;
|
||||
}
|
||||
~AutoRef() {
|
||||
if (ptr)
|
||||
ptr->Release();
|
||||
}
|
||||
|
||||
T *operator =(T *p) {
|
||||
if (ptr)
|
||||
ptr->Release();
|
||||
ptr = p;
|
||||
if (ptr)
|
||||
ptr->AddRef();
|
||||
return ptr;
|
||||
}
|
||||
AutoRef<T> &operator =(const AutoRef<T> &p) {
|
||||
*this = p.ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T *operator->() const {
|
||||
return ptr;
|
||||
}
|
||||
operator T *() {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
T *ptr = nullptr;
|
||||
};
|
||||
|
||||
class BlendState : public RefCountedObject {
|
||||
public:
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user