mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
DrawContext: Use uniform buffers on all platforms (simulated where necessary)
This commit is contained in:
parent
fe1b593c15
commit
9bdae8f32e
8 changed files with 43 additions and 34 deletions
|
@ -94,7 +94,7 @@ SoftGPU::SoftGPU(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
|
|||
PipelineDesc pipelineDesc{
|
||||
Primitive::TRIANGLE_LIST,
|
||||
{ draw_->GetVshaderPreset(VS_TEXTURE_COLOR_2D), draw_->GetFshaderPreset(FS_TEXTURE_COLOR_2D) },
|
||||
inputLayout, depth, blendstateOff, rasterNoCull
|
||||
inputLayout, depth, blendstateOff, rasterNoCull, &vsTexColBufDesc
|
||||
};
|
||||
texColor = draw_->CreateGraphicsPipeline(pipelineDesc);
|
||||
|
||||
|
@ -250,8 +250,10 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
|
|||
0.0f, 0.0f, 0.0f, 1.0f,
|
||||
};
|
||||
|
||||
texColor->SetMatrix4x4("WorldViewProj", identity4x4);
|
||||
VsTexColUB ub{};
|
||||
memcpy(ub.WorldViewProj, identity4x4, sizeof(float) * 16);
|
||||
draw_->BindPipeline(texColor);
|
||||
draw_->UpdateDynamicUniformBuffer(&ub, sizeof(ub));
|
||||
draw_->BindVertexBuffers(0, 1, &vdata, nullptr);
|
||||
draw_->BindIndexBuffer(idata, 0);
|
||||
draw_->DrawIndexed(6, 0);
|
||||
|
|
|
@ -596,12 +596,12 @@ void NativeInitGraphics(GraphicsContext *graphicsContext) {
|
|||
PipelineDesc colorDesc{
|
||||
Primitive::TRIANGLE_LIST,
|
||||
{ g_draw->GetVshaderPreset(VS_COLOR_2D), g_draw->GetFshaderPreset(FS_COLOR_2D) },
|
||||
inputLayout, depth, blendNormal, rasterNoCull
|
||||
inputLayout, depth, blendNormal, rasterNoCull, &vsColBufDesc,
|
||||
};
|
||||
PipelineDesc texColorDesc{
|
||||
Primitive::TRIANGLE_LIST,
|
||||
{ g_draw->GetVshaderPreset(VS_TEXTURE_COLOR_2D), g_draw->GetFshaderPreset(FS_TEXTURE_COLOR_2D) },
|
||||
inputLayout, depth, blendNormal, rasterNoCull
|
||||
inputLayout, depth, blendNormal, rasterNoCull, &vsTexColBufDesc,
|
||||
};
|
||||
|
||||
colorPipeline = g_draw->CreateGraphicsPipeline(colorDesc);
|
||||
|
|
|
@ -90,8 +90,12 @@ void DrawBuffer::Flush(bool set_blend_state) {
|
|||
if (count_ == 0)
|
||||
return;
|
||||
|
||||
pipeline_->SetMatrix4x4("WorldViewProj", drawMatrix_.getReadPtr());
|
||||
draw_->BindPipeline(pipeline_);
|
||||
|
||||
VsTexColUB ub{};
|
||||
memcpy(ub.WorldViewProj, drawMatrix_.getReadPtr(), sizeof(Matrix4x4));
|
||||
// pipeline_->SetMatrix4x4("WorldViewProj", drawMatrix_.getReadPtr());
|
||||
draw_->UpdateDynamicUniformBuffer(&ub, sizeof(ub));
|
||||
if (vbuf_) {
|
||||
draw_->UpdateBuffer(vbuf_, (const uint8_t *)verts_, 0, sizeof(Vertex) * count_, Draw::UPDATE_DISCARD);
|
||||
draw_->BindVertexBuffers(0, 1, &vbuf_, nullptr);
|
||||
|
|
|
@ -522,7 +522,7 @@ struct PipelineDesc {
|
|||
DepthStencilState *depthStencil;
|
||||
BlendState *blend;
|
||||
RasterState *raster;
|
||||
UniformBufferDesc *uniformDesc;
|
||||
const UniformBufferDesc *uniformDesc;
|
||||
};
|
||||
|
||||
struct DeviceCaps {
|
||||
|
|
|
@ -729,14 +729,14 @@ Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
|
|||
dPipeline->dynamicUniformsSize = desc.uniformDesc->uniformBufferSize;
|
||||
D3D11_BUFFER_DESC bufdesc{};
|
||||
bufdesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
bufdesc.ByteWidth = dPipeline->dynamicUniformsSize;
|
||||
bufdesc.StructureByteStride = dPipeline->dynamicUniformsSize;
|
||||
bufdesc.ByteWidth = (UINT)dPipeline->dynamicUniformsSize;
|
||||
bufdesc.StructureByteStride = (UINT)dPipeline->dynamicUniformsSize;
|
||||
bufdesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
bufdesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
HRESULT hr = device_->CreateBuffer(&bufdesc, nullptr, &dPipeline->dynamicUniforms);
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC bufview{};
|
||||
bufview.Buffer.ElementOffset = 0;
|
||||
bufview.Buffer.ElementWidth = dPipeline->dynamicUniformsSize;
|
||||
bufview.Buffer.ElementWidth = (UINT)dPipeline->dynamicUniformsSize;
|
||||
bufview.Buffer.FirstElement = 0;
|
||||
bufview.Buffer.NumElements = 1;
|
||||
hr = device_->CreateShaderResourceView(dPipeline->dynamicUniforms, &bufview, &dPipeline->dynamicUniformsView);
|
||||
|
@ -836,6 +836,10 @@ void D3D11DrawContext::ApplyCurrentState() {
|
|||
if (nextIndexBuffer_) {
|
||||
context_->IASetIndexBuffer(nextIndexBuffer_, DXGI_FORMAT_R32_UINT, nextIndexBufferOffset_);
|
||||
}
|
||||
|
||||
if (curPipeline_->dynamicUniforms) {
|
||||
context_->VSSetShaderResources(0, 1, &curPipeline_->dynamicUniformsView);
|
||||
}
|
||||
}
|
||||
|
||||
class D3D11Buffer : public Buffer {
|
||||
|
|
|
@ -816,6 +816,14 @@ Buffer *D3D9Context::CreateBuffer(size_t size, uint32_t usageFlags) {
|
|||
return new D3D9Buffer(device_, size, usageFlags);
|
||||
}
|
||||
|
||||
inline void Transpose4x4(float out[16], const float in[16]) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
out[i * 4 + j] = in[j * 4 + i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void D3D9Context::UpdateDynamicUniformBuffer(const void *ub, size_t size) {
|
||||
if (size != curPipeline_->dynamicUniforms.uniformBufferSize)
|
||||
Crash();
|
||||
|
@ -829,9 +837,11 @@ void D3D9Context::UpdateDynamicUniformBuffer(const void *ub, size_t size) {
|
|||
count = 4;
|
||||
break;
|
||||
}
|
||||
const float *srcPtr = (const float *)((uint8_t *)ub + uniform.offset);
|
||||
const float *srcPtr = (const float *)((const uint8_t *)ub + uniform.offset);
|
||||
if (uniform.vertexReg != -1) {
|
||||
device_->SetVertexShaderConstantF(uniform.vertexReg, srcPtr, count);
|
||||
float transp[16];
|
||||
Transpose4x4(transp, srcPtr);
|
||||
device_->SetVertexShaderConstantF(uniform.vertexReg, transp, count);
|
||||
}
|
||||
if (uniform.fragmentReg != -1) {
|
||||
device_->SetPixelShaderConstantF(uniform.fragmentReg, srcPtr, count);
|
||||
|
|
|
@ -404,9 +404,6 @@ public:
|
|||
|
||||
bool LinkShaders();
|
||||
|
||||
void Apply();
|
||||
void Unapply();
|
||||
|
||||
int GetUniformLoc(const char *name);
|
||||
|
||||
void SetVector(const char *name, float *value, int n) override;
|
||||
|
@ -436,8 +433,8 @@ public:
|
|||
// TODO: Optimize by getting the locations first and putting in a custom struct
|
||||
UniformBufferDesc dynamicUniforms;
|
||||
|
||||
private:
|
||||
GLuint program_;
|
||||
private:
|
||||
std::map<std::string, UniformInfo> uniformCache_;
|
||||
};
|
||||
|
||||
|
@ -515,7 +512,7 @@ public:
|
|||
|
||||
void SetViewports(int count, Viewport *viewports) override {
|
||||
// TODO: Use glViewportArrayv.
|
||||
glViewport(viewports[0].TopLeftX, viewports[0].TopLeftY, viewports[0].Width, viewports[0].Height);
|
||||
glViewport((GLint)viewports[0].TopLeftX, (GLint)viewports[0].TopLeftY, (GLsizei)viewports[0].Width, (GLsizei)viewports[0].Height);
|
||||
#if defined(USING_GLES2)
|
||||
glDepthRangef(viewports[0].MinDepth, viewports[0].MaxDepth);
|
||||
#else
|
||||
|
@ -769,6 +766,11 @@ void OpenGLTexture::SetImageData(int x, int y, int z, int width, int height, int
|
|||
ELOG("Thin3d GL: Unsupported texture format %d", (int)format_);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
GLenum err = glGetError();
|
||||
if (err) {
|
||||
ELOG("Thin3D GL: Error before loading texture: %08x", err);
|
||||
}*/
|
||||
|
||||
Bind();
|
||||
switch (target_) {
|
||||
|
@ -780,9 +782,9 @@ void OpenGLTexture::SetImageData(int x, int y, int z, int width, int height, int
|
|||
break;
|
||||
}
|
||||
|
||||
GLenum err = glGetError();
|
||||
if (err) {
|
||||
ELOG("Thin3D GL: Error loading texture: %08x", err);
|
||||
GLenum err2 = glGetError();
|
||||
if (err2) {
|
||||
ELOG("Thin3D GL: Error loading texture: %08x", err2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1086,19 +1088,12 @@ void OpenGLPipeline::SetMatrix4x4(const char *name, const float value[16]) {
|
|||
}
|
||||
}
|
||||
|
||||
void OpenGLPipeline::Apply() {
|
||||
glUseProgram(program_);
|
||||
}
|
||||
|
||||
void OpenGLPipeline::Unapply() {
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
void OpenGLContext::BindPipeline(Pipeline *pipeline) {
|
||||
curPipeline_ = (OpenGLPipeline *)pipeline;
|
||||
curPipeline_->blend->Apply();
|
||||
curPipeline_->depthStencil->Apply();
|
||||
curPipeline_->raster->Apply();
|
||||
glUseProgram(curPipeline_->program_);
|
||||
}
|
||||
|
||||
void OpenGLContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) {
|
||||
|
@ -1125,36 +1120,30 @@ void OpenGLContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) {
|
|||
void OpenGLContext::Draw(int vertexCount, int offset) {
|
||||
curVBuffers_[0]->Bind(curVBufferOffsets_[0]);
|
||||
curPipeline_->inputLayout->Apply();
|
||||
curPipeline_->Apply();
|
||||
|
||||
glDrawArrays(curPipeline_->prim, offset, vertexCount);
|
||||
|
||||
curPipeline_->Unapply();
|
||||
curPipeline_->inputLayout->Unapply();
|
||||
}
|
||||
|
||||
void OpenGLContext::DrawIndexed(int vertexCount, int offset) {
|
||||
curVBuffers_[0]->Bind(curVBufferOffsets_[0]);
|
||||
curPipeline_->inputLayout->Apply();
|
||||
curPipeline_->Apply();
|
||||
// Note: ibuf binding is stored in the VAO, so call this after binding the fmt.
|
||||
curIBuffer_->Bind(curIBufferOffset_);
|
||||
|
||||
glDrawElements(curPipeline_->prim, vertexCount, GL_UNSIGNED_INT, (const void *)(size_t)offset);
|
||||
|
||||
curPipeline_->Unapply();
|
||||
curPipeline_->inputLayout->Unapply();
|
||||
}
|
||||
|
||||
void OpenGLContext::DrawUP(const void *vdata, int vertexCount) {
|
||||
curPipeline_->inputLayout->Apply(vdata);
|
||||
curPipeline_->Apply();
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glDrawArrays(curPipeline_->prim, 0, vertexCount);
|
||||
|
||||
curPipeline_->Unapply();
|
||||
curPipeline_->inputLayout->Unapply();
|
||||
}
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ public:
|
|||
class VKPipeline : public Pipeline {
|
||||
public:
|
||||
VKPipeline(size_t size) {
|
||||
uboSize_ = size;
|
||||
uboSize_ = (int)size;
|
||||
ubo_ = new uint8_t[uboSize_];
|
||||
}
|
||||
~VKPipeline() {
|
||||
|
|
Loading…
Add table
Reference in a new issue