src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m
branchmetal-prototype-branch
changeset 57416 e153174dba06
equal deleted inserted replaced
57400:978ffc56771f 57416:e153174dba06
       
     1 #import "MTLPipelineStatesStorage.h"
       
     2 #import "Trace.h"
       
     3 
       
     4 #include "GraphicsPrimitiveMgr.h"
       
     5 #import "common.h"
       
     6 
       
     7 @implementation MTLPipelineStatesStorage
       
     8 
       
     9 @synthesize device;
       
    10 @synthesize library;
       
    11 @synthesize shaders;
       
    12 @synthesize states;
       
    13 @synthesize templateRenderPipelineDesc;
       
    14 @synthesize templateTexturePipelineDesc;
       
    15 
       
    16 - (id) initWithDevice:(id<MTLDevice>)dev shaderLibPath:(NSString *)shadersLib {
       
    17     self = [super init];
       
    18     if (self == nil) return self;
       
    19 
       
    20     self.device = dev;
       
    21 
       
    22     NSError *error = nil;
       
    23     self.library = [dev newLibraryWithFile:shadersLib error:&error];
       
    24     if (!self.library) {
       
    25         NSLog(@"Failed to load library. error %@", error);
       
    26         exit(0);
       
    27     }
       
    28     self.shaders = [NSMutableDictionary dictionaryWithCapacity:10];
       
    29     self.states = [NSMutableDictionary dictionaryWithCapacity:10];
       
    30 
       
    31     { // init template descriptors
       
    32         MTLVertexDescriptor *vertDesc = [[MTLVertexDescriptor new] autorelease];
       
    33         vertDesc.attributes[VertexAttributePosition].format = MTLVertexFormatFloat3;
       
    34         vertDesc.attributes[VertexAttributePosition].offset = 0;
       
    35         vertDesc.attributes[VertexAttributePosition].bufferIndex = MeshVertexBuffer;
       
    36         vertDesc.layouts[MeshVertexBuffer].stride = sizeof(struct Vertex);
       
    37         vertDesc.layouts[MeshVertexBuffer].stepRate = 1;
       
    38         vertDesc.layouts[MeshVertexBuffer].stepFunction = MTLVertexStepFunctionPerVertex;
       
    39 
       
    40         self.templateRenderPipelineDesc = [[MTLRenderPipelineDescriptor new] autorelease];
       
    41         self.templateRenderPipelineDesc.sampleCount = 1;
       
    42         self.templateRenderPipelineDesc.vertexDescriptor = vertDesc;
       
    43         self.templateRenderPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
       
    44         self.templateRenderPipelineDesc.label = @"template_render";
       
    45 
       
    46         self.templateTexturePipelineDesc = [[self.templateRenderPipelineDesc copy] autorelease];
       
    47         self.templateTexturePipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].format = MTLVertexFormatFloat2;
       
    48         self.templateTexturePipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].offset = 3*sizeof(float);
       
    49         self.templateTexturePipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].bufferIndex = MeshVertexBuffer;
       
    50         self.templateTexturePipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stride = sizeof(struct TxtVertex);
       
    51         self.templateTexturePipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stepRate = 1;
       
    52         self.templateTexturePipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stepFunction = MTLVertexStepFunctionPerVertex;
       
    53         self.templateTexturePipelineDesc.label = @"template_texture";
       
    54     }
       
    55 
       
    56     { // pre-create main states
       
    57         [self getRenderPipelineState:YES];
       
    58         [self getRenderPipelineState:NO];
       
    59         [self getTexturePipelineState:NO compositeRule:RULE_Src];
       
    60         [self getTexturePipelineState:NO compositeRule:RULE_SrcOver];
       
    61     }
       
    62 
       
    63     return self;
       
    64 }
       
    65 
       
    66 - (id<MTLRenderPipelineState>) getRenderPipelineState:(bool)isGradient {
       
    67     NSString * uid = [NSString stringWithFormat:@"render_grad[%d]", isGradient];
       
    68 
       
    69     id<MTLRenderPipelineState> result = [self.states valueForKey:uid];
       
    70     if (result == nil) {
       
    71         id<MTLFunction> vertexShader   = isGradient ? [self getShader:@"vert_grad"] : [self getShader:@"vert_col"];
       
    72         id<MTLFunction> fragmentShader = isGradient ? [self getShader:@"frag_grad"] : [self getShader:@"frag_col"];
       
    73         MTLRenderPipelineDescriptor *pipelineDesc = [[self.templateRenderPipelineDesc copy] autorelease];
       
    74         pipelineDesc.vertexFunction = vertexShader;
       
    75         pipelineDesc.fragmentFunction = fragmentShader;
       
    76         pipelineDesc.label = uid;
       
    77 
       
    78         NSError *error = nil;
       
    79         result = [self.device newRenderPipelineStateWithDescriptor:pipelineDesc error:&error];
       
    80         if (result == nil) {
       
    81             NSLog(@"Failed to create render pipeline state '%@', error %@", uid, error);
       
    82             exit(0);
       
    83         }
       
    84 
       
    85         [self.states setValue:result forKey:uid];
       
    86     }
       
    87 
       
    88     return result;
       
    89 };
       
    90 
       
    91 - (id<MTLRenderPipelineState>) getTexturePipelineState:(bool)isSourcePremultiplied compositeRule:(int)compositeRule {
       
    92     NSString * uid = [NSString stringWithFormat:@"texture_compositeRule[%d]", compositeRule];
       
    93 
       
    94     id<MTLRenderPipelineState> result = [self.states valueForKey:uid];
       
    95     if (result == nil) {
       
    96         id<MTLFunction> vertexShader   = [self getShader:@"vert_txt"];
       
    97         id<MTLFunction> fragmentShader = [self getShader:@"frag_txt"];
       
    98         MTLRenderPipelineDescriptor *pipelineDesc = [[self.templateTexturePipelineDesc copy] autorelease];
       
    99         pipelineDesc.vertexFunction = vertexShader;
       
   100         pipelineDesc.fragmentFunction = fragmentShader;
       
   101 
       
   102         if (compositeRule != RULE_Src) {
       
   103             pipelineDesc.colorAttachments[0].blendingEnabled = YES;
       
   104 
       
   105             if (!isSourcePremultiplied)
       
   106                 pipelineDesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
       
   107 
       
   108             //RGB = Source.rgb * SBF + Dest.rgb * DBF
       
   109             //A = Source.a * SBF + Dest.a * DBF
       
   110             //
       
   111             //default SRC:
       
   112             //DBF=0
       
   113             //SBF=1
       
   114             if (compositeRule == RULE_SrcOver) {
       
   115                 // SRC_OVER (Porter-Duff Source Over Destination rule):
       
   116                 // Ar = As + Ad*(1-As)
       
   117                 // Cr = Cs + Cd*(1-As)
       
   118                 pipelineDesc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
       
   119                 pipelineDesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
       
   120             } else {
       
   121                 J2dTrace1(J2D_TRACE_ERROR, "Unimplemented composite rule %d (will be used Src)", compositeRule);
       
   122                 pipelineDesc.colorAttachments[0].blendingEnabled = NO;
       
   123             }
       
   124         }
       
   125 
       
   126         NSError *error = nil;
       
   127         result = [self.device newRenderPipelineStateWithDescriptor:pipelineDesc error:&error];
       
   128         if (result == nil) {
       
   129             NSLog(@"Failed to create texture pipeline state '%@', error %@", uid, error);
       
   130             exit(0);
       
   131         }
       
   132 
       
   133         [self.states setValue:result forKey:uid];
       
   134     }
       
   135 
       
   136     return result;
       
   137 }
       
   138 
       
   139 - (id<MTLFunction>) getShader:(NSString *)name {
       
   140     id<MTLFunction> result = [self.shaders valueForKey:name];
       
   141     if (result == nil) {
       
   142         result = [[self.library newFunctionWithName:name] autorelease];
       
   143         [self.shaders setValue:result forKey:name];
       
   144     }
       
   145     return result;
       
   146 }
       
   147 @end