Dawn: implement textures & samplers.

Add samplers to Dawn binding group layout.
Convert filter modes from Gr to Dawn.
Rename fUniformBindGroup to fBindGroup (since it does more than uniforms now).
Split combined samplers into separate textures and samplers bindings;
recombine in the shader with makeSampler().
Create complete bind group layout before creating UBOs.
Implement scissor rect.
Set blend color in command buffer.
Pass shader caps to SkSL.
Enable flat interpolation, integer support, derivative support in Dawn Caps.
Reduce the Dawn caps to 6 fragment/sampler combos.
Add support for Int (1) vertex format.

Change-Id: Id5e9060855f0dfc8c071f84ea6c456aba2a72b35
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/233977
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
Stephen White 2019-08-15 16:48:24 -04:00 committed by Skia Commit-Bot
parent 4bdcbc2704
commit 170d9905cc
9 changed files with 309 additions and 46 deletions

View File

@ -8,12 +8,22 @@
#include "src/gpu/dawn/GrDawnCaps.h"
GrDawnCaps::GrDawnCaps(const GrContextOptions& contextOptions) : INHERITED(contextOptions) {
fMipMapSupport = true;
fBufferMapThreshold = SK_MaxS32; // FIXME: get this from Dawn?
fShaderCaps.reset(new GrShaderCaps(contextOptions));
fMaxTextureSize = 2048; // FIXME
fMaxTextureSize = fMaxRenderTargetSize = 4096; // FIXME
fMaxVertexAttributes = 16; // FIXME
fClampToBorderSupport = false;
fPerformPartialClearsAsDraws = true;
fShaderCaps->fFlatInterpolationSupport = true;
fShaderCaps->fIntegerSupport = true;
// FIXME: each fragment sampler takes two binding slots in Dawn (sampler + texture). Limit to
// 6 * 2 = 12, since kMaxBindingsPerGroup is 16 in Dawn, and we need to keep a few for
// non-texture bindings. Eventually, we may be able to increase kMaxBindingsPerGroup in Dawn.
fShaderCaps->fMaxFragmentSamplers = 6;
fShaderCaps->fShaderDerivativeSupport = true;
this->applyOptionsOverrides(contextOptions);
fShaderCaps->applyOptionsOverrides(contextOptions);
}

View File

@ -23,7 +23,10 @@
#include "src/gpu/dawn/GrDawnRenderTarget.h"
#include "src/gpu/dawn/GrDawnStencilAttachment.h"
#include "src/gpu/dawn/GrDawnTexture.h"
#include "src/gpu/dawn/GrDawnUtil.h"
#include "src/core/SkAutoMalloc.h"
#include "src/core/SkMipMap.h"
#include "src/sksl/SkSLCompiler.h"
#if !defined(SK_BUILD_FOR_WIN)
@ -222,15 +225,102 @@ GrStencilAttachment* GrDawnGpu::createStencilAttachmentForRenderTarget(const GrR
}
GrBackendTexture GrDawnGpu::createBackendTexture(int width, int height,
const GrBackendFormat& format,
const GrBackendFormat& backendFormat,
GrMipMapped mipMapped,
GrRenderable renderable,
const void* pixels,
size_t rowBytes,
const SkColor4f* color,
GrProtected isProtected) {
SkASSERT(!"unimplemented");
return GrBackendTexture();
dawn::TextureFormat format;
if (!backendFormat.asDawnFormat(&format)) {
return GrBackendTexture();
}
GrPixelConfig config = GrDawnFormatToPixelConfig(format);
if (width > this->caps()->maxTextureSize() || height > this->caps()->maxTextureSize()) {
return GrBackendTexture();
}
// Currently we don't support uploading pixel data when mipped.
if (pixels && GrMipMapped::kYes == mipMapped) {
return GrBackendTexture();
}
dawn::TextureDescriptor desc;
desc.usage =
dawn::TextureUsageBit::Sampled |
dawn::TextureUsageBit::CopySrc |
dawn::TextureUsageBit::CopyDst;
if (GrRenderable::kYes == renderable) {
desc.usage |= dawn::TextureUsageBit::OutputAttachment;
}
desc.size.width = width;
desc.size.height = height;
desc.size.depth = 1;
desc.format = format;
// Figure out the number of mip levels.
if (GrMipMapped::kYes == mipMapped) {
desc.mipLevelCount = SkMipMap::ComputeLevelCount(width, height) + 1;
}
dawn::Texture tex = this->device().CreateTexture(&desc);
size_t bpp = GrBytesPerPixel(config);
size_t baseLayerSize = bpp * width * height;
SkAutoMalloc defaultStorage(baseLayerSize);
if (!pixels) {
// Fill in the texture with all zeros so we don't have random garbage
pixels = defaultStorage.get();
memset(defaultStorage.get(), 0, baseLayerSize);
}
dawn::Device device = this->device();
dawn::CommandEncoder copyEncoder = fDevice.CreateCommandEncoder();
int w = width, h = height;
for (uint32_t i = 0; i < desc.mipLevelCount; i++) {
size_t origRowBytes = bpp * w;
size_t rowBytes = GrDawnRoundRowBytes(origRowBytes);
size_t size = rowBytes * h;
dawn::BufferDescriptor bufferDesc;
bufferDesc.size = size;
bufferDesc.usage = dawn::BufferUsageBit::CopySrc | dawn::BufferUsageBit::CopyDst;
dawn::Buffer buffer = this->device().CreateBuffer(&bufferDesc);
const uint8_t* src = static_cast<const uint8_t*>(pixels);
if (rowBytes == origRowBytes) {
buffer.SetSubData(0, size, src);
} else {
uint32_t offset = 0;
for (int row = 0; row < h; row++) {
buffer.SetSubData(offset, origRowBytes, src);
offset += rowBytes;
src += origRowBytes;
}
}
dawn::BufferCopyView srcBuffer;
srcBuffer.buffer = buffer;
srcBuffer.offset = 0;
srcBuffer.rowPitch = rowBytes;
srcBuffer.imageHeight = h;
dawn::TextureCopyView dstTexture;
dstTexture.texture = tex;
dstTexture.mipLevel = i;
dstTexture.origin = {0, 0, 0};
dawn::Extent3D copySize = {(uint32_t) w, (uint32_t) h, 1};
copyEncoder.CopyBufferToTexture(&srcBuffer, &dstTexture, &copySize);
w = SkTMax(1, w / 2);
h = SkTMax(1, h / 2);
}
dawn::CommandBuffer cmdBuf = copyEncoder.Finish();
fQueue.Submit(1, &cmdBuf);
GrDawnImageInfo info;
info.fTexture = tex;
info.fFormat = desc.format;
info.fLevelCount = desc.mipLevelCount;
return GrBackendTexture(width, height, info);
}
void GrDawnGpu::deleteBackendTexture(const GrBackendTexture& tex) {

View File

@ -84,13 +84,19 @@ GrDawnGpuTextureCommandBuffer::~GrDawnGpuTextureCommandBuffer() {}
////////////////////////////////////////////////////////////////////////////////
dawn::LoadOp to_dawn_load_op(GrLoadOp loadOp) {
static dawn::LoadOp to_dawn_load_op(GrLoadOp loadOp) {
switch (loadOp) {
case GrLoadOp::kLoad:
return dawn::LoadOp::Load;
case GrLoadOp::kDiscard:
// Use LoadOp::Load to emulate DontCare.
// Dawn doesn't have DontCare, for security reasons.
// Load should be equivalent to DontCare for desktop; Clear would
// probably be better for tilers. If Dawn does add DontCare
// as an extension, use it here.
return dawn::LoadOp::Load;
case GrLoadOp::kClear:
return dawn::LoadOp::Clear;
case GrLoadOp::kDiscard:
default:
SK_ABORT("Invalid LoadOp");
}
@ -255,6 +261,8 @@ static dawn::VertexFormat to_dawn_vertex_format(GrVertexAttribType type) {
return dawn::VertexFormat::Float4;
case kUShort2_GrVertexAttribType:
return dawn::VertexFormat::UShort2;
case kInt_GrVertexAttribType:
return dawn::VertexFormat::Int;
case kUByte4_norm_GrVertexAttribType:
return dawn::VertexFormat::UChar4Norm;
default:
@ -282,6 +290,24 @@ static dawn::PrimitiveTopology to_dawn_primitive_topology(GrPrimitiveType primit
}
}
void GrDawnGpuRTCommandBuffer::setScissorState(
const GrPipeline& pipeline,
const GrPipeline::FixedDynamicState* fixedDynamicState,
const GrPipeline::DynamicStateArrays* dynamicStateArrays) {
SkIRect rect;
if (pipeline.isScissorEnabled()) {
constexpr SkIRect kBogusScissor{0, 0, 1, 1};
rect = fixedDynamicState ? fixedDynamicState->fScissorRect : kBogusScissor;
if (kBottomLeft_GrSurfaceOrigin == fOrigin) {
rect.setXYWH(rect.x(), fRenderTarget->height() - rect.bottom(),
rect.width(), rect.height());
}
} else {
rect = SkIRect::MakeWH(fRenderTarget->width(), fRenderTarget->height());
}
fPassEncoder.SetScissorRect(rect.x(), rect.y(), rect.width(), rect.height());
}
void GrDawnGpuRTCommandBuffer::applyState(const GrPipeline& pipeline,
const GrPrimitiveProcessor& primProc,
const GrTextureProxy* const primProcProxies[],
@ -378,10 +404,15 @@ void GrDawnGpuRTCommandBuffer::applyState(const GrPipeline& pipeline,
rpDesc.colorStates = colorStates;
dawn::RenderPipeline renderPipeline = fGpu->device().CreateRenderPipeline(&rpDesc);
fPassEncoder.SetPipeline(renderPipeline);
fPassEncoder.SetBindGroup(0, program->fUniformBindGroup, 0, nullptr);
fPassEncoder.SetBindGroup(0, program->fBindGroup, 0, nullptr);
if (pipeline.isStencilEnabled()) {
fPassEncoder.SetStencilReference(pipeline.getUserStencil()->fFront.fRef);
}
GrXferProcessor::BlendInfo blendInfo = pipeline.getXferProcessor().getBlendInfo();
const float* c = blendInfo.fBlendConstant.vec();
dawn::Color color{c[0], c[1], c[2], c[3]};
fPassEncoder.SetBlendColor(&color);
this->setScissorState(pipeline, fixedDynamicState, dynamicStateArrays);
}
void GrDawnGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,

View File

@ -64,6 +64,9 @@ public:
private:
GrGpu* gpu() override;
void setScissorState(const GrPipeline&,
const GrPipeline::FixedDynamicState* fixedDynamicState,
const GrPipeline::DynamicStateArrays* dynamicStateArrays);
void applyState(const GrPipeline& pipeline,
const GrPrimitiveProcessor& primProc,
const GrTextureProxy* const primProcProxies[],

View File

@ -11,11 +11,13 @@
#include "src/gpu/GrShaderUtils.h"
#include "src/gpu/GrStencilSettings.h"
#include "src/gpu/dawn/GrDawnGpu.h"
#include "src/gpu/dawn/GrDawnTexture.h"
#include "src/sksl/SkSLCompiler.h"
static SkSL::String sksl_to_spirv(const GrDawnGpu* gpu, const char* shaderString,
SkSL::Program::Kind kind, SkSL::Program::Inputs* inputs) {
SkSL::Program::Settings settings;
settings.fCaps = gpu->caps()->shaderCaps();
std::unique_ptr<SkSL::Program> program = gpu->shaderCompiler()->convertProgram(
kind,
shaderString,
@ -149,6 +151,35 @@ static dawn::StencilOperation to_dawn_stencil_operation(GrStencilOp op) {
}
}
static dawn::FilterMode to_dawn_filter_mode(GrSamplerState::Filter filter) {
switch (filter) {
case GrSamplerState::Filter::kNearest:
return dawn::FilterMode::Nearest;
case GrSamplerState::Filter::kBilerp:
case GrSamplerState::Filter::kMipMap:
return dawn::FilterMode::Linear;
default:
SkASSERT(!"unsupported filter mode");
return dawn::FilterMode::Nearest;
}
}
static dawn::AddressMode to_dawn_address_mode(GrSamplerState::WrapMode wrapMode) {
switch (wrapMode) {
case GrSamplerState::WrapMode::kClamp:
return dawn::AddressMode::ClampToEdge;
case GrSamplerState::WrapMode::kClampToBorder:
// TODO: unsupported
return dawn::AddressMode::ClampToEdge;
case GrSamplerState::WrapMode::kRepeat:
return dawn::AddressMode::Repeat;
case GrSamplerState::WrapMode::kMirrorRepeat:
return dawn::AddressMode::MirrorRepeat;
}
SkASSERT(!"unsupported address mode");
return dawn::AddressMode::ClampToEdge;
}
static dawn::ColorStateDescriptor create_color_state(const GrDawnGpu* gpu,
const GrPipeline& pipeline,
dawn::TextureFormat colorFormat) {
@ -215,6 +246,19 @@ static dawn::DepthStencilStateDescriptor create_depth_stencil_state(
return state;
}
static dawn::Sampler create_sampler(const GrDawnGpu* gpu, const GrSamplerState& samplerState) {
dawn::SamplerDescriptor desc;
desc.addressModeU = to_dawn_address_mode(samplerState.wrapModeX());
desc.addressModeV = to_dawn_address_mode(samplerState.wrapModeY());
desc.addressModeW = dawn::AddressMode::ClampToEdge;
desc.magFilter = desc.minFilter = to_dawn_filter_mode(samplerState.filter());
desc.mipmapFilter = dawn::FilterMode::Linear;
desc.lodMinClamp = 0.0f;
desc.lodMaxClamp = 1000.0f;
desc.compare = dawn::CompareFunction::Never;
return gpu->device().CreateSampler(&desc);
}
static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding, const dawn::Buffer& buffer,
uint32_t offset, uint32_t size, const
dawn::Sampler& sampler,
@ -234,6 +278,16 @@ static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding, const da
return make_bind_group_binding(binding, buffer, offset, size, nullptr, nullptr);
}
static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding,
const dawn::Sampler& sampler) {
return make_bind_group_binding(binding, nullptr, 0, 0, sampler, nullptr);
}
static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding,
const dawn::TextureView& textureView) {
return make_bind_group_binding(binding, nullptr, 0, 0, nullptr, textureView);
}
sk_sp<GrDawnProgram> GrDawnProgramBuilder::Build(GrDawnGpu* gpu,
GrRenderTarget* renderTarget,
GrSurfaceOrigin origin,
@ -273,40 +327,74 @@ sk_sp<GrDawnProgram> GrDawnProgramBuilder::Build(GrDawnGpu* gpu,
result->fFragmentProcessorCnt = builder.fFragmentProcessorCnt;
std::vector<dawn::BindGroupLayoutBinding> layoutBindings;
std::vector<dawn::BindGroupBinding> bindings;
if (0 != geometryUniformSize) {
layoutBindings.push_back({ GrDawnUniformHandler::kGeometryBinding,
dawn::ShaderStageBit::Vertex,
dawn::BindingType::UniformBuffer});
}
if (0 != fragmentUniformSize) {
layoutBindings.push_back({ GrDawnUniformHandler::kFragBinding,
dawn::ShaderStageBit::Fragment,
dawn::BindingType::UniformBuffer});
}
uint32_t binding = GrDawnUniformHandler::kSamplerBindingBase;
for (int i = 0; i < builder.fUniformHandler.fSamplers.count(); ++i) {
layoutBindings.push_back({ binding++, dawn::ShaderStageBit::Fragment,
dawn::BindingType::Sampler});
layoutBindings.push_back({ binding++, dawn::ShaderStageBit::Fragment,
dawn::BindingType::SampledTexture});
}
dawn::BindGroupLayoutDescriptor bindGroupLayoutDesc;
bindGroupLayoutDesc.bindingCount = layoutBindings.size();
bindGroupLayoutDesc.bindings = layoutBindings.data();
auto bindGroupLayout = gpu->device().CreateBindGroupLayout(&bindGroupLayoutDesc);
dawn::PipelineLayoutDescriptor pipelineLayoutDesc;
pipelineLayoutDesc.bindGroupLayoutCount = 1;
pipelineLayoutDesc.bindGroupLayouts = &bindGroupLayout;
result->fPipelineLayout = gpu->device().CreatePipelineLayout(&pipelineLayoutDesc);
if (0 != geometryUniformSize) {
dawn::BufferDescriptor desc;
desc.usage = dawn::BufferUsageBit::Uniform | dawn::BufferUsageBit::CopyDst;
desc.size = geometryUniformSize;
result->fGeometryUniformBuffer = gpu->device().CreateBuffer(&desc);
bindings.push_back(make_bind_group_binding(0, result->fGeometryUniformBuffer, 0,
geometryUniformSize));
layoutBindings.push_back({ 0, dawn::ShaderStageBit::Vertex,
dawn::BindingType::UniformBuffer});
bindings.push_back(make_bind_group_binding(GrDawnUniformHandler::kGeometryBinding,
result->fGeometryUniformBuffer,
0, geometryUniformSize));
}
if (0 != fragmentUniformSize) {
dawn::BufferDescriptor desc;
desc.usage = dawn::BufferUsageBit::Uniform | dawn::BufferUsageBit::CopyDst;
desc.size = fragmentUniformSize;
result->fFragmentUniformBuffer = gpu->device().CreateBuffer(&desc);
bindings.push_back(make_bind_group_binding(1, result->fFragmentUniformBuffer, 0,
fragmentUniformSize));
layoutBindings.push_back({ 1, dawn::ShaderStageBit::Fragment,
dawn::BindingType::UniformBuffer});
bindings.push_back(make_bind_group_binding(GrDawnUniformHandler::kFragBinding,
result->fFragmentUniformBuffer,
0, fragmentUniformSize));
}
dawn::BindGroupLayoutDescriptor bindGroupLayoutDesc;
bindGroupLayoutDesc.bindingCount = layoutBindings.size();
bindGroupLayoutDesc.bindings = layoutBindings.data();
auto bindGroupLayout = gpu->device().CreateBindGroupLayout(&bindGroupLayoutDesc);
dawn::BindGroupDescriptor descriptor;
descriptor.layout = bindGroupLayout;
descriptor.bindingCount = bindings.size();
descriptor.bindings = bindings.data();
result->fUniformBindGroup = gpu->device().CreateBindGroup(&descriptor);
dawn::PipelineLayoutDescriptor pipelineLayoutDesc;
pipelineLayoutDesc.bindGroupLayoutCount = 1;
pipelineLayoutDesc.bindGroupLayouts = &bindGroupLayout;
result->fPipelineLayout = gpu->device().CreatePipelineLayout(&pipelineLayoutDesc);
binding = GrDawnUniformHandler::kSamplerBindingBase;
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
dawn::Sampler sampler = create_sampler(gpu, primProc.textureSampler(i).samplerState());
bindings.push_back(make_bind_group_binding(binding++, sampler));
GrDawnTexture* tex = static_cast<GrDawnTexture*>(primProcProxies[i]->peekTexture());
dawn::TextureView textureView = tex->textureView();
bindings.push_back(make_bind_group_binding(binding++, textureView));
}
GrFragmentProcessor::Iter iter(pipeline);
const GrFragmentProcessor* fp = iter.next();
while (fp) {
for (int i = 0; i < fp->numTextureSamplers(); ++i) {
dawn::Sampler sampler = create_sampler(gpu, fp->textureSampler(i).samplerState());
bindings.push_back(make_bind_group_binding(binding++, sampler));
GrDawnTexture* tex = static_cast<GrDawnTexture*>(fp->textureSampler(i).peekTexture());
dawn::TextureView textureView = tex->textureView();
bindings.push_back(make_bind_group_binding(binding++, textureView));
}
fp = iter.next();
}
dawn::BindGroupDescriptor bindGroupDescriptor;
bindGroupDescriptor.layout = bindGroupLayout;
bindGroupDescriptor.bindingCount = bindings.size();
bindGroupDescriptor.bindings = bindings.data();
result->fBindGroup = gpu->device().CreateBindGroup(&bindGroupDescriptor);
result->fBuiltinUniformHandles = builder.fUniformHandles;
result->fColorState = create_color_state(gpu, pipeline, colorFormat);
GrStencilSettings stencil;

View File

@ -63,7 +63,7 @@ struct GrDawnProgram : public SkRefCnt {
dawn::Buffer fGeometryUniformBuffer;
dawn::Buffer fFragmentUniformBuffer;
dawn::PipelineLayout fPipelineLayout;
dawn::BindGroup fUniformBindGroup;
dawn::BindGroup fBindGroup;
dawn::ColorStateDescriptor fColorState;
dawn::DepthStencilStateDescriptor fDepthStencilState;
GrDawnProgramDataManager fDataManager;

View File

@ -11,6 +11,8 @@
GrDawnUniformHandler::GrDawnUniformHandler(GrGLSLProgramBuilder* program)
: INHERITED(program)
, fUniforms(kUniformsPerBlock)
, fSamplers(kUniformsPerBlock)
, fTextures(kUniformsPerBlock)
{
}
@ -236,24 +238,62 @@ GrGLSLUniformHandler::SamplerHandle GrDawnUniformHandler::addSampler(const GrTex
const GrSwizzle& swizzle,
const char* name,
const GrShaderCaps* caps) {
SkASSERT(!"unimplemented");
SkASSERT(name && strlen(name));
SkString mangleName;
char prefix = 's';
fProgramBuilder->nameVariable(&mangleName, prefix, name, true);
return GrGLSLUniformHandler::SamplerHandle(0);
GrSLType samplerType = kSampler_GrSLType, textureType = kTexture2D_GrSLType;
int binding = kSamplerBindingBase + fSamplers.count() * 2;
UniformInfo& info = fSamplers.push_back();
info.fVar.setType(samplerType);
info.fVar.setTypeModifier(GrShaderVar::kUniform_TypeModifier);
info.fVar.setName(mangleName);
SkString layoutQualifier;
layoutQualifier.appendf("set = 0, binding = %d", binding);
info.fVar.addLayoutQualifier(layoutQualifier.c_str());
info.fVisibility = kFragment_GrShaderFlag;
info.fUBOOffset = 0;
fSamplerSwizzles.push_back(swizzle);
SkASSERT(fSamplerSwizzles.count() == fSamplers.count());
SkString mangleTexName;
char texPrefix = 't';
fProgramBuilder->nameVariable(&mangleTexName, texPrefix, name, true);
UniformInfo& texInfo = fTextures.push_back();
texInfo.fVar.setType(textureType);
texInfo.fVar.setTypeModifier(GrShaderVar::kUniform_TypeModifier);
texInfo.fVar.setName(mangleTexName);
SkString texLayoutQualifier;
texLayoutQualifier.appendf("set = 0, binding = %d", binding + 1);
texInfo.fVar.addLayoutQualifier(texLayoutQualifier.c_str());
texInfo.fVisibility = kFragment_GrShaderFlag;
texInfo.fUBOOffset = 0;
SkString reference;
reference.printf("makeSampler2D(%s, %s)", texInfo.fVar.getName().c_str(),
info.fVar.getName().c_str());
fSamplerReferences.push_back() = reference;
return GrGLSLUniformHandler::SamplerHandle(fSamplers.count() - 1);
}
const char* GrDawnUniformHandler::samplerVariable(
GrGLSLUniformHandler::SamplerHandle handle) const {
SkASSERT(!"unimplemented");
return "";
return fSamplerReferences[handle.toIndex()].c_str();
}
GrSwizzle GrDawnUniformHandler::samplerSwizzle(GrGLSLUniformHandler::SamplerHandle handle) const {
SkASSERT(!"unimplemented");
return GrSwizzle();
return fSamplerSwizzles[handle.toIndex()];
}
void GrDawnUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
for (int i = 0; i < fSamplers.count(); ++i) {
if (fSamplers[i].fVisibility & visibility) {
fSamplers[i].fVar.appendDecl(fProgramBuilder->shaderCaps(), out);
out->append(";\n");
fTextures[i].fVar.appendDecl(fProgramBuilder->shaderCaps(), out);
out->append(";\n");
}
}
SkString uniformsString;
for (int i = 0; i < fUniforms.count(); ++i) {
if (fUniforms[i].fVisibility & visibility) {
@ -275,8 +315,8 @@ void GrDawnUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString
uniformBinding = kFragBinding;
stage = "fragment";
}
out->appendf("layout (set = %d, binding = %d) uniform %sUniformBuffer\n{\n",
kUniformBufferBindGroup, uniformBinding, stage);
out->appendf("layout (set = 0, binding = %d) uniform %sUniformBuffer\n{\n",
uniformBinding, stage);
out->appendf("%s\n};\n", uniformsString.c_str());
}
}

View File

@ -20,11 +20,6 @@ public:
const GrShaderVar& getUniformVariable(UniformHandle u) const override;
const char* getUniformCStr(UniformHandle u) const override;
enum {
kUniformBufferBindGroup = 0,
kSamplerBindGroup = 1,
kTexelBufferBindGroup = 2,
};
struct UniformInfo {
GrShaderVar fVar;
int fUBOOffset;
@ -34,6 +29,7 @@ public:
enum {
kGeometryBinding = 0,
kFragBinding = 1,
kSamplerBindingBase = 2,
};
private:
@ -51,8 +47,12 @@ private:
int arrayCount,
const char** outName) override;
GrShaderVar fDummyVar;
UniformInfoArray fUniforms;
UniformInfoArray fUniforms;
UniformInfoArray fSamplers;
UniformInfoArray fTextures;
SkTArray<GrSwizzle> fSamplerSwizzles;
SkTArray<SkString> fSamplerReferences;
uint32_t fCurrentGeometryUBOOffset = 0;
uint32_t fCurrentFragmentUBOOffset = 0;

View File

@ -40,6 +40,7 @@ bool GrPixelConfigToDawnFormat(GrPixelConfig config, dawn::TextureFormat* format
*format = dawn::TextureFormat::BGRA8Unorm;
return true;
case kAlpha_8_GrPixelConfig:
case kAlpha_8_as_Red_GrPixelConfig:
*format = dawn::TextureFormat::R8Unorm;
return true;
default: