More work on reinterpret. Get Vulkan running

This commit is contained in:
Henrik Rydgård 2020-11-06 20:08:57 +01:00
parent 981d0a2abe
commit 96c36d5c10
5 changed files with 53 additions and 24 deletions

View File

@ -664,6 +664,8 @@ InputLayout *D3D11DrawContext::CreateInputLayout(const InputLayoutDesc &desc) {
return inputLayout;
}
class D3D11ShaderModule;
class D3D11Pipeline : public Pipeline {
public:
~D3D11Pipeline() {
@ -694,6 +696,8 @@ public:
ID3D11GeometryShader *gs = nullptr;
D3D11_PRIMITIVE_TOPOLOGY topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
std::vector<D3D11ShaderModule *> shaderModules;
size_t dynamicUniformsSize = 0;
ID3D11Buffer *dynamicUniforms = nullptr;
};
@ -966,7 +970,9 @@ Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
dPipeline->raster = (D3D11RasterState *)desc.raster;
dPipeline->blend->AddRef();
dPipeline->depth->AddRef();
dPipeline->input->AddRef();
if (dPipeline->input) {
dPipeline->input->AddRef();
}
dPipeline->raster->AddRef();
dPipeline->topology = primToD3D11[(int)desc.prim];
if (desc.uniformDesc) {
@ -983,6 +989,8 @@ Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
std::vector<D3D11ShaderModule *> shaders;
D3D11ShaderModule *vshader = nullptr;
for (auto iter : desc.shaders) {
iter->AddRef();
D3D11ShaderModule *module = (D3D11ShaderModule *)iter;
shaders.push_back(module);
switch (module->GetStage()) {
@ -998,6 +1006,7 @@ Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
break;
}
}
dPipeline->shaderModules = shaders;
if (!vshader) {
// No vertex shader - no graphics
@ -1006,11 +1015,15 @@ Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
}
// Can finally create the input layout
auto &inputDesc = dPipeline->input->desc;
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)) {
Crash();
if (dPipeline->input) {
auto &inputDesc = dPipeline->input->desc;
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)) {
Crash();
}
} else {
dPipeline->il = nullptr;
}
return dPipeline;
}
@ -1081,8 +1094,10 @@ void D3D11DrawContext::ApplyCurrentState() {
curTopology_ = curPipeline_->topology;
}
int numVBs = (int)curPipeline_->input->strides.size();
context_->IASetVertexBuffers(0, 1, nextVertexBuffers_, (UINT *)curPipeline_->input->strides.data(), (UINT *)nextVertexBufferOffsets_);
if (curPipeline_->input) {
int numVBs = (int)curPipeline_->input->strides.size();
context_->IASetVertexBuffers(0, numVBs, nextVertexBuffers_, (UINT *)curPipeline_->input->strides.data(), (UINT *)nextVertexBufferOffsets_);
}
if (dirtyIndexBuffer_) {
context_->IASetIndexBuffer(nextIndexBuffer_, DXGI_FORMAT_R16_UINT, nextIndexBufferOffset_);
dirtyIndexBuffer_ = false;

View File

@ -141,10 +141,10 @@ void ShaderWriter::BeginVSMain(Slice<InputDef> inputs, Slice<UniformDef> uniform
case HLSL_D3D9:
{
C("struct VS_OUTPUT {\n");
C(" vec4 pos : POSITION;\n");
for (auto &varying : varyings) {
F(" %s %s : %s;\n", varying.type, varying.name, varying.semantic);
}
F(" vec4 pos : %s;\n", lang_.shaderLanguage == HLSL_D3D11 ? "SV_Position" : "POSITION");
C("};\n");
C("VS_OUTPUT main( "); // 2 spaces for the D3D9 rewind
@ -268,7 +268,8 @@ void ShaderWriter::DeclareTexture2D(const char *name, int binding) {
case HLSL_D3D9:
break;
case GLSL_VULKAN:
F("layout(set = 0, binding = %d) uniform sampler2D %s;\n", binding, name);
// In the thin3d descriptor set layout, textures start at 1 in set 0. Hence the +1.
F("layout(set = 0, binding = %d) uniform sampler2D %s;\n", binding + 1, name);
break;
default:
F("uniform sampler2D %s;\n", name);

View File

@ -1030,8 +1030,12 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
VKPipeline *pipeline = new VKPipeline(vulkan_, desc.uniformDesc ? desc.uniformDesc->uniformBufferSize : 16 * sizeof(float), (PipelineFlags)pipelineFlags);
for (int i = 0; i < (int)input->bindings.size(); i++) {
pipeline->stride[i] = input->bindings[i].stride;
if (input) {
for (int i = 0; i < (int)input->bindings.size(); i++) {
pipeline->stride[i] = input->bindings[i].stride;
}
} else {
pipeline->stride[0] = 0;
}
std::vector<VkPipelineShaderStageCreateInfo> stages;
@ -1076,6 +1080,8 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
VkPipelineRasterizationStateCreateInfo rs{ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO };
raster->ToVulkan(&rs);
VkPipelineVertexInputStateCreateInfo emptyVisc{ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO };
VkGraphicsPipelineCreateInfo createInfo[2]{};
for (auto &info : createInfo) {
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
@ -1088,7 +1094,7 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
info.pInputAssemblyState = &inputAssembly;
info.pTessellationState = nullptr;
info.pMultisampleState = &ms;
info.pVertexInputState = &input->visc;
info.pVertexInputState = input ? &input->visc : &emptyVisc;
info.pRasterizationState = &rs;
info.pViewportState = &vs; // Must set viewport and scissor counts even if we set the actual state dynamically.
info.layout = pipelineLayout_;

View File

@ -531,13 +531,15 @@ void FramebufferManagerCommon::ReformatFramebufferFrom(VirtualFramebuffer *vfb,
return;
}
char *vsCode = nullptr;
char *fsCode = nullptr;
if (!reinterpretVS_) {
char *buffer = new char[4000];
vsCode = new char[4000];
const ShaderLanguageDesc &shaderLanguageDesc = draw_->GetShaderLanguageDesc();
GenerateReinterpretVertexShader(buffer, shaderLanguageDesc);
reinterpretVS_ = draw_->CreateShaderModule(ShaderStage::Vertex, shaderLanguageDesc.shaderLanguage, (const uint8_t *)buffer, strlen(buffer), "reinterpret_vs");
GenerateReinterpretVertexShader(vsCode, shaderLanguageDesc);
reinterpretVS_ = draw_->CreateShaderModule(ShaderStage::Vertex, shaderLanguageDesc.shaderLanguage, (const uint8_t *)vsCode, strlen(vsCode), "reinterpret_vs");
_assert_(reinterpretVS_);
delete[] buffer;
}
if (!reinterpretSampler_) {
@ -551,12 +553,11 @@ void FramebufferManagerCommon::ReformatFramebufferFrom(VirtualFramebuffer *vfb,
Draw::Pipeline *pipeline = reinterpretFromTo_[(int)oldFormat][(int)newFormat];
if (!pipeline) {
char *buffer = new char[4000];
fsCode = new char[4000];
const ShaderLanguageDesc &shaderLanguageDesc = draw_->GetShaderLanguageDesc();
GenerateReinterpretFragmentShader(buffer, oldFormat, newFormat, shaderLanguageDesc);
Draw::ShaderModule *reinterpretFS = draw_->CreateShaderModule(ShaderStage::Fragment, shaderLanguageDesc.shaderLanguage, (const uint8_t *)buffer, strlen(buffer), "reinterpret_fs");
GenerateReinterpretFragmentShader(fsCode, oldFormat, newFormat, shaderLanguageDesc);
Draw::ShaderModule *reinterpretFS = draw_->CreateShaderModule(ShaderStage::Fragment, shaderLanguageDesc.shaderLanguage, (const uint8_t *)fsCode, strlen(fsCode), "reinterpret_fs");
_assert_(reinterpretFS);
delete[] buffer;
std::vector<Draw::ShaderModule *> shaders;
shaders.push_back(reinterpretVS_);
@ -597,10 +598,17 @@ void FramebufferManagerCommon::ReformatFramebufferFrom(VirtualFramebuffer *vfb,
draw_->Draw(3, 0);
draw_->InvalidateCachedState();
// Unbind.
draw_->BindTexture(0, nullptr);
RebindFramebuffer("RebindFramebuffer - After reinterpret");
shaderManager_->DirtyLastShader();
textureCache_->ForgetLastTexture();
gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_VERTEXSHADER_STATE);
delete[] vsCode;
delete[] fsCode;
}
void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) {

View File

@ -82,9 +82,9 @@ enum FShaderBit : uint8_t {
FS_BIT_DO_TEXTURE_PROJ = 22,
FS_BIT_COLOR_DOUBLE = 23,
FS_BIT_STENCIL_TO_ALPHA = 24, // 2 bits
FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE = 26, // 4 bits
FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE = 26, // 4 bits (ReplaceAlphaType)
FS_BIT_REPLACE_LOGIC_OP_TYPE = 30, // 2 bits
FS_BIT_REPLACE_BLEND = 32, // 3 bits
FS_BIT_REPLACE_BLEND = 32, // 3 bits (ReplaceBlendType)
FS_BIT_BLENDEQ = 35, // 3 bits
FS_BIT_BLENDFUNC_A = 38, // 4 bits
FS_BIT_BLENDFUNC_B = 42, // 4 bits
@ -92,7 +92,6 @@ enum FShaderBit : uint8_t {
FS_BIT_BGRA_TEXTURE = 47,
FS_BIT_TEST_DISCARD_TO_ZERO = 48,
FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL = 49,
// 50+ are free.
};
static inline FShaderBit operator +(FShaderBit bit, int i) {